diff options
author | Fabio Estevam <fabio.estevam@freescale.com> | 2013-10-09 20:46:45 -0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-10-11 15:24:36 -0700 |
commit | c35d6a37bdcb1dde42dd65b00676696e2dd78f2f (patch) | |
tree | 7de7c8d5b0a8fb63746a5a539eb06c8d8e591505 | |
parent | 4ad0fdb0e23a4d31794f0818fb65eefdc8cd3306 (diff) |
imx-drm: imx-drm-core: Fix circular locking dependency
Booting a mx6 with CONFIG_PROVE_LOCKING we get:
======================================================
[ INFO: possible circular locking dependency detected ]
3.12.0-rc4-next-20131009+ #34 Not tainted
-------------------------------------------------------
swapper/0/1 is trying to acquire lock:
(&imx_drm_device->mutex){+.+.+.}, at: [<804575a8>] imx_drm_encoder_get_mux_id+0x28/0x98
but task is already holding lock:
(&crtc->mutex){+.+...}, at: [<802fe778>] drm_modeset_lock_all+0x40/0x54
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&crtc->mutex){+.+...}:
[<800777d0>] __lock_acquire+0x18d4/0x1c24
[<80077fec>] lock_acquire+0x68/0x7c
[<805ead5c>] _mutex_lock_nest_lock+0x58/0x3a8
[<802fec50>] drm_crtc_init+0x48/0xa8
[<80457c88>] imx_drm_add_crtc+0xd4/0x144
[<8045e2e8>] ipu_drm_probe+0x114/0x1fc
[<80312278>] platform_drv_probe+0x20/0x50
[<80310c68>] driver_probe_device+0x110/0x22c
[<80310e20>] __driver_attach+0x9c/0xa0
[<8030f218>] bus_for_each_dev+0x5c/0x90
[<80310750>] driver_attach+0x20/0x28
[<8031034c>] bus_add_driver+0xdc/0x1dc
[<803114d8>] driver_register+0x80/0xfc
[<80312198>] __platform_driver_register+0x50/0x64
[<808172fc>] ipu_drm_driver_init+0x18/0x20
[<800088c0>] do_one_initcall+0xfc/0x160
[<807e7c5c>] kernel_init_freeable+0x104/0x1d4
[<805e2930>] kernel_init+0x10/0xec
[<8000ea68>] ret_from_fork+0x14/0x2c
-> #1 (&dev->mode_config.mutex){+.+.+.}:
[<800777d0>] __lock_acquire+0x18d4/0x1c24
[<80077fec>] lock_acquire+0x68/0x7c
[<805eb100>] mutex_lock_nested+0x54/0x3a4
[<802fe758>] drm_modeset_lock_all+0x20/0x54
[<802fead4>] drm_encoder_init+0x20/0x7c
[<80457ae4>] imx_drm_add_encoder+0x88/0xec
[<80459838>] imx_ldb_probe+0x344/0x4fc
[<80312278>] platform_drv_probe+0x20/0x50
[<80310c68>] driver_probe_device+0x110/0x22c
[<80310e20>] __driver_attach+0x9c/0xa0
[<8030f218>] bus_for_each_dev+0x5c/0x90
[<80310750>] driver_attach+0x20/0x28
[<8031034c>] bus_add_driver+0xdc/0x1dc
[<803114d8>] driver_register+0x80/0xfc
[<80312198>] __platform_driver_register+0x50/0x64
[<8081722c>] imx_ldb_driver_init+0x18/0x20
[<800088c0>] do_one_initcall+0xfc/0x160
[<807e7c5c>] kernel_init_freeable+0x104/0x1d4
[<805e2930>] kernel_init+0x10/0xec
[<8000ea68>] ret_from_fork+0x14/0x2c
-> #0 (&imx_drm_device->mutex){+.+.+.}:
[<805e510c>] print_circular_bug+0x74/0x2e0
[<80077ad0>] __lock_acquire+0x1bd4/0x1c24
[<80077fec>] lock_acquire+0x68/0x7c
[<805eb100>] mutex_lock_nested+0x54/0x3a4
[<804575a8>] imx_drm_encoder_get_mux_id+0x28/0x98
[<80459a98>] imx_ldb_encoder_prepare+0x34/0x114
[<802ef724>] drm_crtc_helper_set_mode+0x1f0/0x4c0
[<802f0344>] drm_crtc_helper_set_config+0x828/0x99c
[<802ff270>] drm_mode_set_config_internal+0x5c/0xdc
[<802eebe0>] drm_fb_helper_set_par+0x50/0xb4
[<802af580>] fbcon_init+0x490/0x500
[<802dd104>] visual_init+0xa8/0xf8
[<802df414>] do_bind_con_driver+0x140/0x37c
[<802df764>] do_take_over_console+0x114/0x1c4
[<802af65c>] do_fbcon_takeover+0x6c/0xd4
[<802b2b30>] fbcon_event_notify+0x7c8/0x818
[<80049954>] notifier_call_chain+0x4c/0x8c
[<80049cd8>] __blocking_notifier_call_chain+0x50/0x68
[<80049d10>] blocking_notifier_call_chain+0x20/0x28
[<802a75f0>] fb_notifier_call_chain+0x1c/0x24
[<802a9224>] register_framebuffer+0x188/0x268
[<802ee994>] drm_fb_helper_initial_config+0x2bc/0x4b8
[<802f118c>] drm_fbdev_cma_init+0x7c/0xec
[<80817288>] imx_fb_helper_init+0x54/0x90
[<800088c0>] do_one_initcall+0xfc/0x160
[<807e7c5c>] kernel_init_freeable+0x104/0x1d4
[<805e2930>] kernel_init+0x10/0xec
[<8000ea68>] ret_from_fork+0x14/0x2c
other info that might help us debug this:
Chain exists of:
&imx_drm_device->mutex --> &dev->mode_config.mutex --> &crtc->mutex
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&crtc->mutex);
lock(&dev->mode_config.mutex);
lock(&crtc->mutex);
lock(&imx_drm_device->mutex);
*** DEADLOCK ***
6 locks held by swapper/0/1:
#0: (registration_lock){+.+.+.}, at: [<802a90bc>] register_framebuffer+0x20/0x268
#1: (&fb_info->lock){+.+.+.}, at: [<802a7a90>] lock_fb_info+0x20/0x44
#2: (console_lock){+.+.+.}, at: [<802a9218>] register_framebuffer+0x17c/0x268
#3: ((fb_notifier_list).rwsem){.+.+.+}, at: [<80049cbc>] __blocking_notifier_call_chain+0x34/0x68
#4: (&dev->mode_config.mutex){+.+.+.}, at: [<802fe758>] drm_modeset_lock_all+0x20/0x54
#5: (&crtc->mutex){+.+...}, at: [<802fe778>] drm_modeset_lock_all+0x40/0x54
In order to avoid this lockdep warning, remove the locking from
imx_drm_encoder_get_mux_id() and imx_drm_crtc_panel_format_pins().
Tested on a mx6sabrelite and mx53qsb.
Reported-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/imx-drm/imx-drm-core.c | 12 |
1 files changed, 0 insertions, 12 deletions
diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index a2e52a0c53c9..5e0b8e2889db 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -110,18 +110,12 @@ int imx_drm_crtc_panel_format_pins(struct drm_crtc *crtc, u32 encoder_type, struct imx_drm_crtc *imx_crtc; struct imx_drm_crtc_helper_funcs *helper; - mutex_lock(&imxdrm->mutex); - list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) if (imx_crtc->crtc == crtc) goto found; - mutex_unlock(&imxdrm->mutex); - return -EINVAL; found: - mutex_unlock(&imxdrm->mutex); - helper = &imx_crtc->imx_drm_helper_funcs; if (helper->set_interface_pix_fmt) return helper->set_interface_pix_fmt(crtc, @@ -647,20 +641,14 @@ int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder, struct imx_drm_crtc *imx_crtc; int i = 0; - mutex_lock(&imxdrm->mutex); - list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) { if (imx_crtc->crtc == crtc) goto found; i++; } - mutex_unlock(&imxdrm->mutex); - return -EINVAL; found: - mutex_unlock(&imxdrm->mutex); - return i; } EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id); |