From 29cd2e2dac799e5f243d6d3c68bf3834b65b204e Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Wed, 2 Jan 2019 14:55:06 -0300 Subject: drm/virtio: Remove incorrect kfree() The virtio_gpu_output is a member of struct virtio_gpu_device and is not a dynamically-allocated chunk, so it's wrong to kfree() it. Removing it fixes a memory corruption BUG() that can be triggered when the virtio-gpu driver is removed. Signed-off-by: Ezequiel Garcia Signed-off-by: Gerd Hoffmann Link: http://patchwork.freedesktop.org/patch/msgid/20190102175507.4653-1-ezequiel@collabora.com --- drivers/gpu/drm/virtio/virtgpu_display.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index e1c223e18d86..d539bc28dc97 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -243,12 +243,8 @@ static enum drm_connector_status virtio_gpu_conn_detect( static void virtio_gpu_conn_destroy(struct drm_connector *connector) { - struct virtio_gpu_output *virtio_gpu_output = - drm_connector_to_virtio_gpu_output(connector); - drm_connector_unregister(connector); drm_connector_cleanup(connector); - kfree(virtio_gpu_output); } static const struct drm_connector_funcs virtio_gpu_connector_funcs = { -- cgit v1.2.3 From edde9fc58e26c2b120e6e4d633b8df56629fd770 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Wed, 2 Jan 2019 14:55:07 -0300 Subject: drm/virtio: Add missing virtqueue reset As per the VirtIO spec, the virtqueues must be reset during cleanup (see "3.3.1 Driver Requirements: Device Cleanup"). Signed-off-by: Ezequiel Garcia Signed-off-by: Gerd Hoffmann Link: http://patchwork.freedesktop.org/patch/msgid/20190102175507.4653-2-ezequiel@collabora.com --- drivers/gpu/drm/virtio/virtgpu_kms.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index 1072064a0db2..c340be252fce 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -239,6 +239,7 @@ void virtio_gpu_driver_unload(struct drm_device *dev) flush_work(&vgdev->ctrlq.dequeue_work); flush_work(&vgdev->cursorq.dequeue_work); flush_work(&vgdev->config_changed_work); + vgdev->vdev->config->reset(vgdev->vdev); vgdev->vdev->config->del_vqs(vgdev->vdev); virtio_gpu_modeset_fini(vgdev); -- cgit v1.2.3 From 3630c2a24f75e3ac58366bc4745c2c63391bb4f7 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 19 Dec 2018 13:26:59 +0100 Subject: drm/virtio: log error responses If we got an error response code from the host, print it to the log. Signed-off-by: Gerd Hoffmann Reviewed-by: Oleksandr Andrushchenko Link: http://patchwork.freedesktop.org/patch/msgid/20181219122708.4586-2-kraxel@redhat.com --- drivers/gpu/drm/virtio/virtgpu_vq.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index e27c4aedb809..6bc2008b0d0d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -192,8 +192,16 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct *work) list_for_each_entry_safe(entry, tmp, &reclaim_list, list) { resp = (struct virtio_gpu_ctrl_hdr *)entry->resp_buf; - if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) - DRM_DEBUG("response 0x%x\n", le32_to_cpu(resp->type)); + if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) { + if (resp->type >= cpu_to_le32(VIRTIO_GPU_RESP_ERR_UNSPEC)) { + struct virtio_gpu_ctrl_hdr *cmd; + cmd = (struct virtio_gpu_ctrl_hdr *)entry->buf; + DRM_ERROR("response 0x%x (command 0x%x)\n", + le32_to_cpu(resp->type), + le32_to_cpu(cmd->type)); + } else + DRM_DEBUG("response 0x%x\n", le32_to_cpu(resp->type)); + } if (resp->flags & cpu_to_le32(VIRTIO_GPU_FLAG_FENCE)) { u64 f = le64_to_cpu(resp->fence_id); -- cgit v1.2.3 From 6a01d277ac611663e8e810177b50d16aa6c2a915 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 19 Dec 2018 13:27:00 +0100 Subject: drm/virtio: fix pageflip flush Sending the flush command only makes sense if we actually have a framebuffer attached to the scanout (handle != 0). Signed-off-by: Gerd Hoffmann Reviewed-by: Ezequiel Garcia Link: http://patchwork.freedesktop.org/patch/msgid/20181219122708.4586-3-kraxel@redhat.com --- drivers/gpu/drm/virtio/virtgpu_plane.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index ead5c53d4e21..548265b8e82d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -130,11 +130,12 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane, plane->state->src_h >> 16, plane->state->src_x >> 16, plane->state->src_y >> 16); - virtio_gpu_cmd_resource_flush(vgdev, handle, - plane->state->src_x >> 16, - plane->state->src_y >> 16, - plane->state->src_w >> 16, - plane->state->src_h >> 16); + if (handle) + virtio_gpu_cmd_resource_flush(vgdev, handle, + plane->state->src_x >> 16, + plane->state->src_y >> 16, + plane->state->src_w >> 16, + plane->state->src_h >> 16); } static int virtio_gpu_cursor_prepare_fb(struct drm_plane *plane, -- cgit v1.2.3 From cb66c6daa5e9b2b2aa7ebe956e329c81c1ffe466 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Wed, 19 Dec 2018 13:27:01 +0100 Subject: drm/virtio: drop virtio_gpu_fence_cleanup() Just call drm_fence_put directly instead. Also set vgfb->fence to NULL after dropping the reference. Signed-off-by: Gerd Hoffmann Reviewed-by: Ezequiel Garcia Link: http://patchwork.freedesktop.org/patch/msgid/20181219122708.4586-4-kraxel@redhat.com --- drivers/gpu/drm/virtio/virtgpu_drv.h | 1 - drivers/gpu/drm/virtio/virtgpu_fence.c | 8 -------- drivers/gpu/drm/virtio/virtgpu_ioctl.c | 2 +- drivers/gpu/drm/virtio/virtgpu_plane.c | 6 ++++-- 4 files changed, 5 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index 63704915f8ce..bfb31fc3d01d 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -337,7 +337,6 @@ int virtio_gpu_mmap(struct file *filp, struct vm_area_struct *vma); /* virtio_gpu_fence.c */ struct virtio_gpu_fence *virtio_gpu_fence_alloc( struct virtio_gpu_device *vgdev); -void virtio_gpu_fence_cleanup(struct virtio_gpu_fence *fence); int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, struct virtio_gpu_ctrl_hdr *cmd_hdr, struct virtio_gpu_fence *fence); diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 4d6826b27814..21bd4c4a32d1 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -81,14 +81,6 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) return fence; } -void virtio_gpu_fence_cleanup(struct virtio_gpu_fence *fence) -{ - if (!fence) - return; - - dma_fence_put(&fence->f); -} - int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, struct virtio_gpu_ctrl_hdr *cmd_hdr, struct virtio_gpu_fence *fence) diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c index 161b80fee492..14ce8188c052 100644 --- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -351,7 +351,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data, virtio_gpu_cmd_resource_create_3d(vgdev, qobj, &rc_3d); ret = virtio_gpu_object_attach(vgdev, qobj, fence); if (ret) { - virtio_gpu_fence_cleanup(fence); + dma_fence_put(&fence->f); goto fail_backoff; } ttm_eu_fence_buffer_objects(&ticket, &validate_list, &fence->f); diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index 548265b8e82d..024c2aa0c929 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -169,8 +169,10 @@ static void virtio_gpu_cursor_cleanup_fb(struct drm_plane *plane, return; vgfb = to_virtio_gpu_framebuffer(plane->state->fb); - if (vgfb->fence) - virtio_gpu_fence_cleanup(vgfb->fence); + if (vgfb->fence) { + dma_fence_put(&vgfb->fence->f); + vgfb->fence = NULL; + } } static void virtio_gpu_cursor_plane_update(struct drm_plane *plane, -- cgit v1.2.3 From 6e1490cf439aa86b104e5124c36275b964238e1f Mon Sep 17 00:00:00 2001 From: Noralf Trønnes Date: Sat, 5 Jan 2019 19:18:46 +0100 Subject: drm/fb-helper: generic: Fix setup error path If register_framebuffer() fails during fbdev setup we will leak the framebuffer, the GEM buffer and the shadow buffer for defio. This is because drm_fb_helper_fbdev_setup() just calls drm_fb_helper_fini() on error not taking into account that register_framebuffer() can fail. Since the generic emulation uses DRM client for its framebuffer and backing buffer in addition to a shadow buffer, it's necessary to open code drm_fb_helper_fbdev_setup() to properly handle the error path. Error cleanup is removed from .fb_probe and is handled by one function for all paths. Fixes: 9060d7f49376 ("drm/fb-helper: Finish the generic fbdev emulation") Reported-by: Peter Wu Signed-off-by: Noralf Trønnes Acked-by: Gerd Hoffmann Link: https://patchwork.freedesktop.org/patch/msgid/20190105181846.26495-1-noralf@tronnes.org --- drivers/gpu/drm/drm_fb_helper.c | 98 ++++++++++++++++++++++++----------------- 1 file changed, 58 insertions(+), 40 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 5e9ca6f96379..80136a7a5af1 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2961,18 +2961,16 @@ static int drm_fbdev_fb_release(struct fb_info *info, int user) return 0; } -/* - * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of - * unregister_framebuffer() or fb_release(). - */ -static void drm_fbdev_fb_destroy(struct fb_info *info) +static void drm_fbdev_cleanup(struct drm_fb_helper *fb_helper) { - struct drm_fb_helper *fb_helper = info->par; struct fb_info *fbi = fb_helper->fbdev; struct fb_ops *fbops = NULL; void *shadow = NULL; - if (fbi->fbdefio) { + if (!fb_helper->dev) + return; + + if (fbi && fbi->fbdefio) { fb_deferred_io_cleanup(fbi); shadow = fbi->screen_buffer; fbops = fbi->fbops; @@ -2986,6 +2984,12 @@ static void drm_fbdev_fb_destroy(struct fb_info *info) } drm_client_framebuffer_delete(fb_helper->buffer); +} + +static void drm_fbdev_release(struct drm_fb_helper *fb_helper) +{ + drm_fbdev_cleanup(fb_helper); + /* * FIXME: * Remove conditional when all CMA drivers have been moved over to using @@ -2997,6 +3001,15 @@ static void drm_fbdev_fb_destroy(struct fb_info *info) } } +/* + * fb_ops.fb_destroy is called by the last put_fb_info() call at the end of + * unregister_framebuffer() or fb_release(). + */ +static void drm_fbdev_fb_destroy(struct fb_info *info) +{ + drm_fbdev_release(info->par); +} + static int drm_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) { struct drm_fb_helper *fb_helper = info->par; @@ -3047,7 +3060,6 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, struct drm_framebuffer *fb; struct fb_info *fbi; u32 format; - int ret; DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n", sizes->surface_width, sizes->surface_height, @@ -3064,10 +3076,8 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, fb = buffer->fb; fbi = drm_fb_helper_alloc_fbi(fb_helper); - if (IS_ERR(fbi)) { - ret = PTR_ERR(fbi); - goto err_free_buffer; - } + if (IS_ERR(fbi)) + return PTR_ERR(fbi); fbi->par = fb_helper; fbi->fbops = &drm_fbdev_fb_ops; @@ -3098,8 +3108,7 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, if (!fbops || !shadow) { kfree(fbops); vfree(shadow); - ret = -ENOMEM; - goto err_fb_info_destroy; + return -ENOMEM; } *fbops = *fbi->fbops; @@ -3111,13 +3120,6 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper *fb_helper, } return 0; - -err_fb_info_destroy: - drm_fb_helper_fini(fb_helper); -err_free_buffer: - drm_client_framebuffer_delete(buffer); - - return ret; } EXPORT_SYMBOL(drm_fb_helper_generic_probe); @@ -3129,18 +3131,11 @@ static void drm_fbdev_client_unregister(struct drm_client_dev *client) { struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); - if (fb_helper->fbdev) { - drm_fb_helper_unregister_fbi(fb_helper); + if (fb_helper->fbdev) /* drm_fbdev_fb_destroy() takes care of cleanup */ - return; - } - - /* Did drm_fb_helper_fbdev_setup() run? */ - if (fb_helper->dev) - drm_fb_helper_fini(fb_helper); - - drm_client_release(client); - kfree(fb_helper); + drm_fb_helper_unregister_fbi(fb_helper); + else + drm_fbdev_release(fb_helper); } static int drm_fbdev_client_restore(struct drm_client_dev *client) @@ -3158,7 +3153,7 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client) struct drm_device *dev = client->dev; int ret; - /* If drm_fb_helper_fbdev_setup() failed, we only try once */ + /* Setup is not retried if it has failed */ if (!fb_helper->dev && fb_helper->funcs) return 0; @@ -3170,15 +3165,34 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client) return 0; } - ret = drm_fb_helper_fbdev_setup(dev, fb_helper, &drm_fb_helper_generic_funcs, - fb_helper->preferred_bpp, 0); - if (ret) { - fb_helper->dev = NULL; - fb_helper->fbdev = NULL; - return ret; - } + drm_fb_helper_prepare(dev, fb_helper, &drm_fb_helper_generic_funcs); + + ret = drm_fb_helper_init(dev, fb_helper, dev->mode_config.num_connector); + if (ret) + goto err; + + ret = drm_fb_helper_single_add_all_connectors(fb_helper); + if (ret) + goto err_cleanup; + + if (!drm_drv_uses_atomic_modeset(dev)) + drm_helper_disable_unused_functions(dev); + + ret = drm_fb_helper_initial_config(fb_helper, fb_helper->preferred_bpp); + if (ret) + goto err_cleanup; return 0; + +err_cleanup: + drm_fbdev_cleanup(fb_helper); +err: + fb_helper->dev = NULL; + fb_helper->fbdev = NULL; + + DRM_DEV_ERROR(dev->dev, "fbdev: Failed to setup generic emulation (ret=%d)\n", ret); + + return ret; } static const struct drm_client_funcs drm_fbdev_client_funcs = { @@ -3237,6 +3251,10 @@ int drm_fbdev_generic_setup(struct drm_device *dev, unsigned int preferred_bpp) drm_client_add(&fb_helper->client); + if (!preferred_bpp) + preferred_bpp = dev->mode_config.preferred_depth; + if (!preferred_bpp) + preferred_bpp = 32; fb_helper->preferred_bpp = preferred_bpp; ret = drm_fbdev_client_hotplug(&fb_helper->client); -- cgit v1.2.3 From 00eb5b0da8d27b3c944bfc959c3344d665caae26 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Sun, 23 Dec 2018 01:55:07 +0100 Subject: drm/fb-helper: fix leaks in error path of drm_fb_helper_fbdev_setup After drm_fb_helper_fbdev_setup calls drm_fb_helper_init, "dev->fb_helper" will be initialized (and thus drm_fb_helper_fini will have some effect). After that, drm_fb_helper_initial_config is called which may call the "fb_probe" driver callback. This driver callback may call drm_fb_helper_defio_init (as is done by drm_fb_helper_generic_probe) or set a framebuffer (as is done by bochs) as documented. These are normally cleaned up on exit by drm_fb_helper_fbdev_teardown which also calls drm_fb_helper_fini. If an error occurs after "fb_probe", but before setup is complete, then calling just drm_fb_helper_fini will leak resources. This was triggered by df2052cc922 ("bochs: convert to drm_fb_helper_fbdev_setup/teardown"): [ 50.008030] bochsdrmfb: enable CONFIG_FB_LITTLE_ENDIAN to support this framebuffer [ 50.009436] bochs-drm 0000:00:02.0: [drm:drm_fb_helper_fbdev_setup] *ERROR* fbdev: Failed to set configuration (ret=-38) [ 50.011456] [drm] Initialized bochs-drm 1.0.0 20130925 for 0000:00:02.0 on minor 2 [ 50.013604] WARNING: CPU: 1 PID: 1 at drivers/gpu/drm/drm_mode_config.c:477 drm_mode_config_cleanup+0x280/0x2a0 [ 50.016175] CPU: 1 PID: 1 Comm: swapper/0 Tainted: G T 4.20.0-rc7 #1 [ 50.017732] EIP: drm_mode_config_cleanup+0x280/0x2a0 ... [ 50.023155] Call Trace: [ 50.023155] ? bochs_kms_fini+0x1e/0x30 [ 50.023155] ? bochs_unload+0x18/0x40 This can be reproduced with QEMU and CONFIG_FB_LITTLE_ENDIAN=n. Link: https://lkml.kernel.org/r/20181221083226.GI23332@shao2-debian Link: https://lkml.kernel.org/r/20181223004315.GA11455@al Fixes: 8741216396b2 ("drm/fb-helper: Add drm_fb_helper_fbdev_setup/teardown()") Reported-by: kernel test robot Cc: Noralf Trønnes Signed-off-by: Peter Wu Reviewed-by: Noralf Trønnes Signed-off-by: Noralf Trønnes Link: https://patchwork.freedesktop.org/patch/msgid/20181223005507.28328-1-peter@lekensteyn.nl --- drivers/gpu/drm/drm_fb_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 80136a7a5af1..a83d9c73bcc8 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -2866,7 +2866,7 @@ int drm_fb_helper_fbdev_setup(struct drm_device *dev, return 0; err_drm_fb_helper_fini: - drm_fb_helper_fini(fb_helper); + drm_fb_helper_fbdev_teardown(dev); return ret; } -- cgit v1.2.3 From d516e75c71c9853ef70a9c476d11a97b69380147 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 8 Jan 2019 11:59:30 -0300 Subject: drm/virtio: Drop deprecated load/unload initialization Move the code around so the driver is probed the bus .probe and removed from the bus .remove callbacks. This commit is just a cleanup and shouldn't affect functionality. Signed-off-by: Ezequiel Garcia Link: http://patchwork.freedesktop.org/patch/msgid/20190108145930.15080-1-ezequiel@collabora.com Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/virtio/Makefile | 2 +- drivers/gpu/drm/virtio/virtgpu_display.c | 3 +- drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 103 ------------------------------- drivers/gpu/drm/virtio/virtgpu_drv.c | 79 ++++++++++++++++++++++-- drivers/gpu/drm/virtio/virtgpu_drv.h | 9 +-- drivers/gpu/drm/virtio/virtgpu_kms.c | 9 +-- 6 files changed, 83 insertions(+), 122 deletions(-) delete mode 100644 drivers/gpu/drm/virtio/virtgpu_drm_bus.c (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile index f29deec83d1f..4e90cc8fa651 100644 --- a/drivers/gpu/drm/virtio/Makefile +++ b/drivers/gpu/drm/virtio/Makefile @@ -3,7 +3,7 @@ # Makefile for the drm device driver. This driver provides support for the # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. -virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_drm_bus.o virtgpu_gem.o \ +virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_gem.o \ virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \ virtgpu_ioctl.o virtgpu_prime.o diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index d539bc28dc97..87d7c49cf057 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -358,7 +358,7 @@ static const struct drm_mode_config_funcs virtio_gpu_mode_funcs = { .atomic_commit = drm_atomic_helper_commit, }; -int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) +void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) { int i; @@ -377,7 +377,6 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev) vgdev_output_init(vgdev, i); drm_mode_config_reset(vgdev->ddev); - return 0; } void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev) diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c deleted file mode 100644 index 0887e0b64b9c..000000000000 --- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2015 Red Hat, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include -#include - -#include "virtgpu_drv.h" - -int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev) -{ - struct drm_device *dev; - int ret; - - dev = drm_dev_alloc(driver, &vdev->dev); - if (IS_ERR(dev)) - return PTR_ERR(dev); - vdev->priv = dev; - - if (strcmp(vdev->dev.parent->bus->name, "pci") == 0) { - struct pci_dev *pdev = to_pci_dev(vdev->dev.parent); - const char *pname = dev_name(&pdev->dev); - bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; - char unique[20]; - - DRM_INFO("pci: %s detected at %s\n", - vga ? "virtio-vga" : "virtio-gpu-pci", - pname); - dev->pdev = pdev; - if (vga) - drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, - 0, - "virtiodrmfb"); - - /* - * Normally the drm_dev_set_unique() call is done by core DRM. - * The following comment covers, why virtio cannot rely on it. - * - * Unlike the other virtual GPU drivers, virtio abstracts the - * underlying bus type by using struct virtio_device. - * - * Hence the dev_is_pci() check, used in core DRM, will fail - * and the unique returned will be the virtio_device "virtio0", - * while a "pci:..." one is required. - * - * A few other ideas were considered: - * - Extend the dev_is_pci() check [in drm_set_busid] to - * consider virtio. - * Seems like a bigger hack than what we have already. - * - * - Point drm_device::dev to the parent of the virtio_device - * Semantic changes: - * * Using the wrong device for i2c, framebuffer_alloc and - * prime import. - * Visual changes: - * * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer, - * will print the wrong information. - * - * We could address the latter issues, by introducing - * drm_device::bus_dev, ... which would be used solely for this. - * - * So for the moment keep things as-is, with a bulky comment - * for the next person who feels like removing this - * drm_dev_set_unique() quirk. - */ - snprintf(unique, sizeof(unique), "pci:%s", pname); - ret = drm_dev_set_unique(dev, unique); - if (ret) - goto err_free; - - } - - ret = drm_dev_register(dev, 0); - if (ret) - goto err_free; - - return 0; - -err_free: - drm_dev_put(dev); - return ret; -} diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c index 7df50920c1e0..af92964b6889 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.c +++ b/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -40,8 +40,60 @@ static int virtio_gpu_modeset = -1; MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); module_param_named(modeset, virtio_gpu_modeset, int, 0400); +static int virtio_gpu_pci_quirk(struct drm_device *dev, struct virtio_device *vdev) +{ + struct pci_dev *pdev = to_pci_dev(vdev->dev.parent); + const char *pname = dev_name(&pdev->dev); + bool vga = (pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA; + char unique[20]; + + DRM_INFO("pci: %s detected at %s\n", + vga ? "virtio-vga" : "virtio-gpu-pci", + pname); + dev->pdev = pdev; + if (vga) + drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, + 0, + "virtiodrmfb"); + + /* + * Normally the drm_dev_set_unique() call is done by core DRM. + * The following comment covers, why virtio cannot rely on it. + * + * Unlike the other virtual GPU drivers, virtio abstracts the + * underlying bus type by using struct virtio_device. + * + * Hence the dev_is_pci() check, used in core DRM, will fail + * and the unique returned will be the virtio_device "virtio0", + * while a "pci:..." one is required. + * + * A few other ideas were considered: + * - Extend the dev_is_pci() check [in drm_set_busid] to + * consider virtio. + * Seems like a bigger hack than what we have already. + * + * - Point drm_device::dev to the parent of the virtio_device + * Semantic changes: + * * Using the wrong device for i2c, framebuffer_alloc and + * prime import. + * Visual changes: + * * Helpers such as DRM_DEV_ERROR, dev_info, drm_printer, + * will print the wrong information. + * + * We could address the latter issues, by introducing + * drm_device::bus_dev, ... which would be used solely for this. + * + * So for the moment keep things as-is, with a bulky comment + * for the next person who feels like removing this + * drm_dev_set_unique() quirk. + */ + snprintf(unique, sizeof(unique), "pci:%s", pname); + return drm_dev_set_unique(dev, unique); +} + static int virtio_gpu_probe(struct virtio_device *vdev) { + struct drm_device *dev; int ret; if (vgacon_text_force() && virtio_gpu_modeset == -1) @@ -50,18 +102,39 @@ static int virtio_gpu_probe(struct virtio_device *vdev) if (virtio_gpu_modeset == 0) return -EINVAL; - ret = drm_virtio_init(&driver, vdev); + dev = drm_dev_alloc(&driver, &vdev->dev); + if (IS_ERR(dev)) + return PTR_ERR(dev); + vdev->priv = dev; + + if (!strcmp(vdev->dev.parent->bus->name, "pci")) { + ret = virtio_gpu_pci_quirk(dev, vdev); + if (ret) + goto err_free; + } + + ret = virtio_gpu_init(dev); if (ret) - return ret; + goto err_free; + + ret = drm_dev_register(dev, 0); + if (ret) + goto err_free; drm_fbdev_generic_setup(vdev->priv, 32); return 0; + +err_free: + drm_dev_put(dev); + return ret; } static void virtio_gpu_remove(struct virtio_device *vdev) { struct drm_device *dev = vdev->priv; + drm_dev_unregister(dev); + virtio_gpu_deinit(dev); drm_put_dev(dev); } @@ -123,8 +196,6 @@ static const struct file_operations virtio_gpu_driver_fops = { static struct drm_driver driver = { .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC, - .load = virtio_gpu_driver_load, - .unload = virtio_gpu_driver_unload, .open = virtio_gpu_driver_open, .postclose = virtio_gpu_driver_postclose, diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h index bfb31fc3d01d..cf896d879382 100644 --- a/drivers/gpu/drm/virtio/virtgpu_drv.h +++ b/drivers/gpu/drm/virtio/virtgpu_drv.h @@ -50,9 +50,6 @@ #define DRIVER_MINOR 1 #define DRIVER_PATCHLEVEL 0 -/* virtgpu_drm_bus.c */ -int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev); - struct virtio_gpu_object { struct drm_gem_object gem_base; uint32_t hw_res_handle; @@ -209,8 +206,8 @@ struct virtio_gpu_fpriv { extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS]; /* virtio_kms.c */ -int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags); -void virtio_gpu_driver_unload(struct drm_device *dev); +int virtio_gpu_init(struct drm_device *dev); +void virtio_gpu_deinit(struct drm_device *dev); int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file); void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file); @@ -320,7 +317,7 @@ int virtio_gpu_framebuffer_init(struct drm_device *dev, struct virtio_gpu_framebuffer *vgfb, const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object *obj); -int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); +void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev); void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev); /* virtio_gpu_plane.c */ diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index c340be252fce..84b6a6bf00c6 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -106,7 +106,7 @@ static void virtio_gpu_get_capsets(struct virtio_gpu_device *vgdev, vgdev->num_capsets = num_capsets; } -int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) +int virtio_gpu_init(struct drm_device *dev) { static vq_callback_t *callbacks[] = { virtio_gpu_ctrl_ack, virtio_gpu_cursor_ack @@ -193,9 +193,7 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) num_capsets, &num_capsets); DRM_INFO("number of cap sets: %d\n", num_capsets); - ret = virtio_gpu_modeset_init(vgdev); - if (ret) - goto err_modeset; + virtio_gpu_modeset_init(vgdev); virtio_device_ready(vgdev->vdev); vgdev->vqs_ready = true; @@ -209,7 +207,6 @@ int virtio_gpu_driver_load(struct drm_device *dev, unsigned long flags) 5 * HZ); return 0; -err_modeset: err_scanouts: virtio_gpu_ttm_fini(vgdev); err_ttm: @@ -231,7 +228,7 @@ static void virtio_gpu_cleanup_cap_cache(struct virtio_gpu_device *vgdev) } } -void virtio_gpu_driver_unload(struct drm_device *dev) +void virtio_gpu_deinit(struct drm_device *dev) { struct virtio_gpu_device *vgdev = dev->dev_private; -- cgit v1.2.3 From d4b9dd50076e02b46292be379ce976e9ad75dc40 Mon Sep 17 00:00:00 2001 From: Gustavo A. R. Silva Date: Tue, 8 Jan 2019 10:21:52 -0600 Subject: qxl: Use struct_size() in kzalloc() One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; void *entry[]; }; instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL); Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL); This code was detected with the help of Coccinelle. Signed-off-by: Gustavo A. R. Silva Link: http://patchwork.freedesktop.org/patch/msgid/20190108162152.GA25361@embeddedor Signed-off-by: Gerd Hoffmann --- drivers/gpu/drm/qxl/qxl_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 72a1784dae54..1f8fddcc34d6 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -48,8 +48,8 @@ static int qxl_alloc_client_monitors_config(struct qxl_device *qdev, } if (!qdev->client_monitors_config) { qdev->client_monitors_config = kzalloc( - sizeof(struct qxl_monitors_config) + - sizeof(struct qxl_head) * count, GFP_KERNEL); + struct_size(qdev->client_monitors_config, + heads, count), GFP_KERNEL); if (!qdev->client_monitors_config) return -ENOMEM; } -- cgit v1.2.3 From c39ff7ea780549be960bea9d028f8b5a4aadf2c9 Mon Sep 17 00:00:00 2001 From: Shayenne Moura Date: Thu, 20 Dec 2018 10:26:10 -0200 Subject: drm: omapdrm: Cleanup drm_display_mode print str This patch adjust the print string of drm_display_mode object to remove drm_mode_object dependency in omapdrm files. Signed-off-by: Shayenne Moura Reviewed-by: Sebastian Reichel Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/cb6079fa6de6fda8d865a1d2a61d7cf10019ae88.1545308167.git.shayenneluzmoura@gmail.com --- drivers/gpu/drm/omapdrm/omap_connector.c | 9 ++------- drivers/gpu/drm/omapdrm/omap_crtc.c | 8 ++------ 2 files changed, 4 insertions(+), 13 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c index b81302c4bf9e..874d8f3cbff6 100644 --- a/drivers/gpu/drm/omapdrm/omap_connector.c +++ b/drivers/gpu/drm/omapdrm/omap_connector.c @@ -305,14 +305,9 @@ static int omap_connector_mode_valid(struct drm_connector *connector, drm_mode_destroy(dev, new_mode); done: - DBG("connector: mode %s: " - "%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", + DBG("connector: mode %s: " DRM_MODE_FMT, (ret == MODE_OK) ? "valid" : "invalid", - mode->base.id, mode->name, mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, - mode->hsync_end, mode->htotal, - mode->vdisplay, mode->vsync_start, - mode->vsync_end, mode->vtotal, mode->type, mode->flags); + DRM_MODE_ARG(mode)); return ret; } diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index caffc547ef97..40acf4ce7c9f 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -427,12 +427,8 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc) struct omap_crtc *omap_crtc = to_omap_crtc(crtc); struct drm_display_mode *mode = &crtc->state->adjusted_mode; - DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", - omap_crtc->name, mode->base.id, mode->name, - mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal, - mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal, - mode->type, mode->flags); + DBG("%s: set mode: " DRM_MODE_FMT, + omap_crtc->name, DRM_MODE_ARG(mode)); drm_display_mode_to_videomode(mode, &omap_crtc->vm); } -- cgit v1.2.3 From e343c123483b08187a719132ae9f7e6407496088 Mon Sep 17 00:00:00 2001 From: Shayenne Moura Date: Thu, 20 Dec 2018 10:26:55 -0200 Subject: drm: meson: Cleanup on drm_display_mode print str This patch adjust the print string of drm_display_mode object to remove drm_mode_object dependency in meson files. Signed-off-by: Shayenne Moura Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/7017942bbbb3e0e6c1e2bd854ea5a5f461784ac4.1545308167.git.shayenneluzmoura@gmail.com --- drivers/gpu/drm/meson/meson_dw_hdmi.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c index d8c5cc34e22e..0b6c29cdd934 100644 --- a/drivers/gpu/drm/meson/meson_dw_hdmi.c +++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c @@ -365,7 +365,7 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, unsigned int wr_clk = readl_relaxed(priv->io_base + _REG(VPU_HDMI_SETTING)); - DRM_DEBUG_DRIVER("%d:\"%s\"\n", mode->base.id, mode->name); + DRM_DEBUG_DRIVER("\"%s\"\n", mode->name); /* Enable clocks */ regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100); @@ -555,12 +555,7 @@ dw_hdmi_mode_valid(struct drm_connector *connector, int vic = drm_match_cea_mode(mode); enum drm_mode_status status; - DRM_DEBUG_DRIVER("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", - mode->base.id, mode->name, mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, - mode->hsync_end, mode->htotal, - mode->vdisplay, mode->vsync_start, - mode->vsync_end, mode->vtotal, mode->type, mode->flags); + DRM_DEBUG_DRIVER("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); /* Check against non-VIC supported modes */ if (!vic) { @@ -650,8 +645,7 @@ static void meson_venc_hdmi_encoder_mode_set(struct drm_encoder *encoder, struct meson_drm *priv = dw_hdmi->priv; int vic = drm_match_cea_mode(mode); - DRM_DEBUG_DRIVER("%d:\"%s\" vic %d\n", - mode->base.id, mode->name, vic); + DRM_DEBUG_DRIVER("\"%s\" vic %d\n", mode->name, vic); /* VENC + VENC-DVI Mode setup */ meson_venc_hdmi_mode_set(priv, vic, mode); -- cgit v1.2.3 From 5e8345a01f068fe389cb6c766d86b59ad4448d20 Mon Sep 17 00:00:00 2001 From: Shayenne Moura Date: Thu, 20 Dec 2018 10:27:30 -0200 Subject: drm: sti: Cleanup drm_display_mode print str This patch adjust the print string of drm_display_mode object to remove drm_mode_object dependency in sti files. Signed-off-by: Shayenne Moura Acked-by: Benjamin Gaignard Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/c079f461575aece9d598784da25aaadc711a2729.1545308167.git.shayenneluzmoura@gmail.com --- drivers/gpu/drm/sti/sti_crtc.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index ed76e52eb213..ec9f87483e39 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c @@ -53,18 +53,10 @@ sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode) struct clk *compo_clk, *pix_clk; int rate = mode->clock * 1000; - DRM_DEBUG_KMS("CRTC:%d (%s) mode:%d (%s)\n", - crtc->base.id, sti_mixer_to_str(mixer), - mode->base.id, mode->name); - - DRM_DEBUG_KMS("%d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", - mode->vrefresh, mode->clock, - mode->hdisplay, - mode->hsync_start, mode->hsync_end, - mode->htotal, - mode->vdisplay, - mode->vsync_start, mode->vsync_end, - mode->vtotal, mode->type, mode->flags); + DRM_DEBUG_KMS("CRTC:%d (%s) mode: (%s)\n", + crtc->base.id, sti_mixer_to_str(mixer), mode->name); + + DRM_DEBUG_KMS(DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); if (mixer->id == STI_MIXER_MAIN) { compo_clk = compo->clk_compo_main; -- cgit v1.2.3 From 4fb6bb89249324be01f710e9d0b02a70c7f6caca Mon Sep 17 00:00:00 2001 From: Shayenne Moura Date: Thu, 20 Dec 2018 10:27:57 -0200 Subject: drm: i915: Cleanup drm_display_mode print str This patch adjust the print string of drm_display_mode object to remove drm_mode_object dependency in i915 files. It modifies the print style to standardize the use of DRM_MODE_FMT. Signed-off-by: Shayenne Moura Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/087e07a388c7c65b6d0ec50db069640e4eb32fdf.1545308167.git.shayenneluzmoura@gmail.com --- drivers/gpu/drm/i915/i915_debugfs.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 7f455bca528e..a63d084c8e96 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2948,14 +2948,7 @@ static void intel_seq_print_mode(struct seq_file *m, int tabs, for (i = 0; i < tabs; i++) seq_putc(m, '\t'); - seq_printf(m, "id %d:\"%s\" freq %d clock %d hdisp %d hss %d hse %d htot %d vdisp %d vss %d vse %d vtot %d type 0x%x flags 0x%x\n", - mode->base.id, mode->name, - mode->vrefresh, mode->clock, - mode->hdisplay, mode->hsync_start, - mode->hsync_end, mode->htotal, - mode->vdisplay, mode->vsync_start, - mode->vsync_end, mode->vtotal, - mode->type, mode->flags); + seq_printf(m, DRM_MODE_FMT "\n", DRM_MODE_ARG(mode)); } static void intel_encoder_info(struct seq_file *m, -- cgit v1.2.3 From fb4b49278f6b2b83bc638d4082301f98581c3598 Mon Sep 17 00:00:00 2001 From: Kuo-Hsin Yang Date: Tue, 8 Jan 2019 15:45:17 +0800 Subject: drm/gem: Mark pinned pages as unevictable The gem drivers use shmemfs to allocate backing storage for gem objects. On Samsung Chromebook Plus, the drm/rockchip driver may call rockchip_gem_get_pages -> drm_gem_get_pages -> shmem_read_mapping_page to pin a lot of pages, breaking the page reclaim mechanism and causing oom-killer invocation. E.g. when the size of a zone is 3.9 GiB, the inactive_ratio is 5. If active_anon / inactive_anon < 5 and all pages in the inactive_anon lru are pinned, page reclaim would keep scanning inactive_anon lru without reclaiming memory. It breaks page reclaim when the rockchip driver only pins about 1/6 of the anon lru pages. Mark these pinned pages as unevictable to avoid the premature oom-killer invocation. See also similar patch on i915 driver [1]. [1]: https://patchwork.freedesktop.org/patch/msgid/20181106132324.17390-1-chris@chris-wilson.co.uk Signed-off-by: Kuo-Hsin Yang Cc: Daniel Vetter Cc: Chris Wilson Reviewed-by: Chris Wilson Signed-off-by: Chris Wilson Link: https://patchwork.freedesktop.org/patch/msgid/20190108074517.209860-1-vovoy@chromium.org --- drivers/gpu/drm/drm_gem.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 8b55ece97967..2896ff60552f 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -526,6 +527,17 @@ int drm_gem_create_mmap_offset(struct drm_gem_object *obj) } EXPORT_SYMBOL(drm_gem_create_mmap_offset); +/* + * Move pages to appropriate lru and release the pagevec, decrementing the + * ref count of those pages. + */ +static void drm_gem_check_release_pagevec(struct pagevec *pvec) +{ + check_move_unevictable_pages(pvec); + __pagevec_release(pvec); + cond_resched(); +} + /** * drm_gem_get_pages - helper to allocate backing pages for a GEM object * from shmem @@ -551,6 +563,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj) { struct address_space *mapping; struct page *p, **pages; + struct pagevec pvec; int i, npages; /* This is the shared memory object that backs the GEM resource */ @@ -568,6 +581,8 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj) if (pages == NULL) return ERR_PTR(-ENOMEM); + mapping_set_unevictable(mapping); + for (i = 0; i < npages; i++) { p = shmem_read_mapping_page(mapping, i); if (IS_ERR(p)) @@ -586,8 +601,14 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj) return pages; fail: - while (i--) - put_page(pages[i]); + mapping_clear_unevictable(mapping); + pagevec_init(&pvec); + while (i--) { + if (!pagevec_add(&pvec, pages[i])) + drm_gem_check_release_pagevec(&pvec); + } + if (pagevec_count(&pvec)) + drm_gem_check_release_pagevec(&pvec); kvfree(pages); return ERR_CAST(p); @@ -605,6 +626,11 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, bool dirty, bool accessed) { int i, npages; + struct address_space *mapping; + struct pagevec pvec; + + mapping = file_inode(obj->filp)->i_mapping; + mapping_clear_unevictable(mapping); /* We already BUG_ON() for non-page-aligned sizes in * drm_gem_object_init(), so we should never hit this unless @@ -614,6 +640,7 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, npages = obj->size >> PAGE_SHIFT; + pagevec_init(&pvec); for (i = 0; i < npages; i++) { if (dirty) set_page_dirty(pages[i]); @@ -622,8 +649,11 @@ void drm_gem_put_pages(struct drm_gem_object *obj, struct page **pages, mark_page_accessed(pages[i]); /* Undo the reference we took when populating the table */ - put_page(pages[i]); + if (!pagevec_add(&pvec, pages[i])) + drm_gem_check_release_pagevec(&pvec); } + if (pagevec_count(&pvec)) + drm_gem_check_release_pagevec(&pvec); kvfree(pages); } -- cgit v1.2.3 From 428747ae5cca2ca13983b768513f13cb8896de04 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 8 Jan 2019 20:29:33 +0100 Subject: drm: remove include of drmP.h from bridge/dw_hdmi.h drmP.h is an relic from the days when there was a single header file. To enable the removal of drmP.h from all users drop include of drmP.h from bridge/dw_hdmi.h. A few files relied on the file included in drmP.h - add explicit include statements or forward declarations to these files. Build tested with arm and x86. v2: - prefer forward declarations when possible (Laurent Pinchart) - sort include files (Laurent Pinchart) Signed-off-by: Sam Ravnborg Reviewed-by: Laurent Pinchart Cc: Archit Taneja Cc: Andrzej Hajda Cc: David Airlie Cc: Daniel Vetter Cc: Kieran Bingham Cc: Fabio Estevam Cc: Neil Armstrong Cc: Maxime Ripard Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190108192939.15255-7-sam@ravnborg.org --- drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 4 ++++ drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c | 1 + include/drm/bridge/dw_hdmi.h | 6 ++++-- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c index 2228689d9a5e..5cbb71a866d5 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c @@ -5,6 +5,10 @@ * Copyright (c) 2017 Renesas Solutions Corp. * Kuninori Morimoto */ + +#include +#include + #include #include diff --git a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c index 75490a3e0a2a..790d499daa10 100644 --- a/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c +++ b/drivers/gpu/drm/rcar-du/rcar_dw_hdmi.c @@ -7,6 +7,7 @@ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) */ +#include #include #include diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h index 9c56412bb2cf..9f93895dde88 100644 --- a/include/drm/bridge/dw_hdmi.h +++ b/include/drm/bridge/dw_hdmi.h @@ -10,9 +10,11 @@ #ifndef __DW_HDMI__ #define __DW_HDMI__ -#include - +struct drm_connector; +struct drm_display_mode; +struct drm_encoder; struct dw_hdmi; +struct platform_device; /** * DOC: Supported input formats and encodings -- cgit v1.2.3 From fe1f664a36091f4a3c771178f47545b190c78162 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 8 Jan 2019 20:29:36 +0100 Subject: drm/arc: do not rely on drmP.h from drm_gem_cma_helper.h drmP.h was the only header file in the past and a lot of files rely on that drmP.h defines everything. The goal is to one day to delete drmP.h and as a step towards this it will no longer be included in the headers files in include/drm/ To prepare arc/ for this add dependencies that othwewise was pulled in by drmP.h from drm_gem_cma_helper.h Signed-off-by: Sam Ravnborg Acked-by: Noralf Trønnes Cc: Alexey Brodkin Cc: Daniel Vetter Cc: David Airlie [danvet: Fix typo in commit message.] Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190108192939.15255-10-sam@ravnborg.org --- drivers/gpu/drm/arc/arcpgu_crtc.c | 2 ++ drivers/gpu/drm/arc/arcpgu_drv.c | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index 62f51f70606d..155ab177ce0b 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -16,8 +16,10 @@ #include #include +#include #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c index 206a76abf771..39a79f5718c4 100644 --- a/drivers/gpu/drm/arc/arcpgu_drv.c +++ b/drivers/gpu/drm/arc/arcpgu_drv.c @@ -16,12 +16,18 @@ #include #include +#include +#include +#include #include #include #include #include #include +#include +#include #include +#include #include "arcpgu.h" #include "arcpgu_regs.h" -- cgit v1.2.3 From 84056e9b45f7a1a1284f33343551ae21bc3c2cc1 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 8 Jan 2019 20:29:38 +0100 Subject: drm/tinydrm: do not reply on drmP.h from drm_gem_cma_helper.h drmP.h was the only header file in the past and a lot of files rely on that drmP.h defines everything. The goal is to one day to delete drmP.h and as a step towards this it will no longer be included in the headers files in include/drm/ To prepare tinydrm/ for this add dependencies that othwewise was pulled in by drmP.h from drm_gem_cma_helper.h To avoid that tinydrm.h became "include everything", push include files to the individual drivers. Signed-off-by: Sam Ravnborg Acked-by: Noralf Trønnes Acked-by: David Lechner Cc: David Airlie Cc: Eric Anholt Cc: Daniel Vetter Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20190108192939.15255-12-sam@ravnborg.org --- drivers/gpu/drm/tinydrm/core/tinydrm-core.c | 3 +++ drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c | 3 +++ drivers/gpu/drm/tinydrm/hx8357d.c | 1 + drivers/gpu/drm/tinydrm/ili9225.c | 2 ++ drivers/gpu/drm/tinydrm/ili9341.c | 1 + drivers/gpu/drm/tinydrm/mi0283qt.c | 1 + drivers/gpu/drm/tinydrm/mipi-dbi.c | 3 +++ drivers/gpu/drm/tinydrm/repaper.c | 1 + drivers/gpu/drm/tinydrm/st7586.c | 1 + drivers/gpu/drm/tinydrm/st7735r.c | 1 + 10 files changed, 17 insertions(+) (limited to 'drivers/gpu/drm') diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-core.c b/drivers/gpu/drm/tinydrm/core/tinydrm-core.c index 01a6f2d42440..aeb93eadb047 100644 --- a/drivers/gpu/drm/tinydrm/core/tinydrm-core.c +++ b/drivers/gpu/drm/tinydrm/core/tinydrm-core.c @@ -10,11 +10,14 @@ #include #include #include +#include #include #include +#include #include #include #include +#include /** * DOC: overview diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c index eacfc0ec8ff1..d4576d6e8ce4 100644 --- a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c +++ b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c @@ -9,8 +9,11 @@ #include #include +#include #include #include +#include +#include #include struct tinydrm_connector { diff --git a/drivers/gpu/drm/tinydrm/hx8357d.c b/drivers/gpu/drm/tinydrm/hx8357d.c index 81a2bbeb25d4..3ae11aa4b73b 100644 --- a/drivers/gpu/drm/tinydrm/hx8357d.c +++ b/drivers/gpu/drm/tinydrm/hx8357d.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/drivers/gpu/drm/tinydrm/ili9225.c b/drivers/gpu/drm/tinydrm/ili9225.c index 78f7c2d1b449..b0ad58b97227 100644 --- a/drivers/gpu/drm/tinydrm/ili9225.c +++ b/drivers/gpu/drm/tinydrm/ili9225.c @@ -20,7 +20,9 @@ #include #include