From 5bfd40139d55790cbc8e56ad1ce4f974f1fa186d Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Wed, 22 Nov 2017 21:39:28 +0100 Subject: drm/vc4: Fix false positive WARN() backtrace on refcount_inc() usage With CONFIG_REFCOUNT_FULL enabled, refcount_inc() complains when it's passed a refcount object that has its counter set to 0. In this driver, this is a valid use case since we want to increment ->usecnt only when the BO object starts to be used by real HW components and this is definitely not the case when the BO is created. Fix the problem by using refcount_inc_not_zero() instead of refcount_inc() and fallback to refcount_set(1) when refcount_inc_not_zero() returns false. Note that this 2-steps operation is not racy here because the whole section is protected by a mutex which guarantees that the counter does not change between the refcount_inc_not_zero() and refcount_set() calls. Fixes: b9f19259b84d ("drm/vc4: Add the DRM_IOCTL_VC4_GEM_MADVISE ioctl") Reported-by: Stefan Wahren Signed-off-by: Boris Brezillon Acked-by: Eric Anholt Link: https://patchwork.freedesktop.org/patch/msgid/20171122203928.28135-1-boris.brezillon@free-electrons.com --- drivers/gpu/drm/vc4/vc4_bo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 4ae45d7dac42..2decc8e2c79f 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -637,7 +637,8 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo) mutex_lock(&bo->madv_lock); switch (bo->madv) { case VC4_MADV_WILLNEED: - refcount_inc(&bo->usecnt); + if (!refcount_inc_not_zero(&bo->usecnt)) + refcount_set(&bo->usecnt, 1); ret = 0; break; case VC4_MADV_DONTNEED: -- cgit v1.2.3 From 510353a63796d467b41237ab4f136136f68c297d Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 21 Nov 2017 08:49:36 +0100 Subject: drm/bridge: analogix dp: Fix runtime PM state in get_modes() callback get_modes() callback might be called asynchronously from the DRM core and it is not synchronized with bridge_enable(), which sets proper runtime PM state of the main DP device. Fix this by calling pm_runtime_get_sync() before calling drm_get_edid(), which in turn calls drm_dp_i2c_xfer() and analogix_dp_transfer() to ensure that main DP device is runtime active when doing any access to its registers. This fixes the following kernel issue on Samsung Exynos5250 Snow board: Unhandled fault: imprecise external abort (0x406) at 0x00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: : 406 [#1] PREEMPT SMP ARM Modules linked in: CPU: 0 PID: 62 Comm: kworker/0:2 Not tainted 4.13.0-rc2-00364-g4a97a3da420b #3357 Hardware name: SAMSUNG EXYNOS (Flattened Device Tree) Workqueue: events output_poll_execute task: edc14800 task.stack: edcb2000 PC is at analogix_dp_transfer+0x15c/0x2fc LR is at analogix_dp_transfer+0x134/0x2fc pc : [] lr : [] psr: 60000013 sp : edcb3be8 ip : 0000002a fp : 00000001 r10: 00000000 r9 : edcb3cd8 r8 : edcb3c40 r7 : 00000000 r6 : edd3b380 r5 : edd3b010 r4 : 00000064 r3 : 00000000 r2 : f0ad3000 r1 : edcb3c40 r0 : edd3b010 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none Control: 10c5387d Table: 4000406a DAC: 00000051 Process kworker/0:2 (pid: 62, stack limit = 0xedcb2210) Stack: (0xedcb3be8 to 0xedcb4000) [] (analogix_dp_transfer) from [] (drm_dp_i2c_do_msg+0x8c/0x2b4) [] (drm_dp_i2c_do_msg) from [] (drm_dp_i2c_xfer+0x98/0x214) [] (drm_dp_i2c_xfer) from [] (__i2c_transfer+0x140/0x29c) [] (__i2c_transfer) from [] (i2c_transfer+0x70/0xe4) [] (i2c_transfer) from [] (drm_do_probe_ddc_edid+0xb4/0x114) [] (drm_do_probe_ddc_edid) from [] (drm_probe_ddc+0x18/0x28) [] (drm_probe_ddc) from [] (drm_get_edid+0x124/0x2d4) [] (drm_get_edid) from [] (analogix_dp_get_modes+0x90/0x114) [] (analogix_dp_get_modes) from [] (drm_helper_probe_single_connector_modes+0x198/0x68c) [] (drm_helper_probe_single_connector_modes) from [] (drm_setup_crtcs+0x1b4/0xd18) [] (drm_setup_crtcs) from [] (drm_fb_helper_hotplug_event+0x94/0xd0) [] (drm_fb_helper_hotplug_event) from [] (drm_kms_helper_hotplug_event+0x24/0x28) [] (drm_kms_helper_hotplug_event) from [] (output_poll_execute+0x6c/0x174) [] (output_poll_execute) from [] (process_one_work+0x188/0x3fc) [] (process_one_work) from [] (worker_thread+0x30/0x4b8) [] (worker_thread) from [] (kthread+0x128/0x164) [] (kthread) from [] (ret_from_fork+0x14/0x24) Code: 0a000002 ea000009 e2544001 0a00004a (e59537c8) ---[ end trace cddc7919c79f7878 ]--- Reported-by: Misha Komarovskiy CC: stable@vger.kernel.org # v4.10+ Signed-off-by: Marek Szyprowski Signed-off-by: Archit Taneja Link: https://patchwork.freedesktop.org/patch/msgid/20171121074936.22520-1-m.szyprowski@samsung.com --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 5dd3f1cd074a..a8905049b9da 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -946,7 +946,9 @@ static int analogix_dp_get_modes(struct drm_connector *connector) return 0; } + pm_runtime_get_sync(dp->dev); edid = drm_get_edid(connector, &dp->aux.ddc); + pm_runtime_put(dp->dev); if (edid) { drm_mode_connector_update_edid_property(&dp->connector, edid); -- cgit v1.2.3