linux/drivers/clk
Stephen Boyd 6314b6796e clk: Don't hold prepare_lock across debugfs creation
Rob Clark reports a lockdep splat that involves the prepare_lock
chained with the mmap semaphore.

======================================================
[ INFO: possible circular locking dependency detected ]
3.17.0-rc1-00050-g07a489b #802 Tainted: G        W
-------------------------------------------------------
Xorg.bin/5413 is trying to acquire lock:
 (prepare_lock){+.+.+.}, at: [<c0781280>] clk_prepare_lock+0x88/0xfc

but task is already holding lock:
 (qcom_iommu_lock){+.+...}, at: [<c079f664>] qcom_iommu_unmap+0x1c/0x1f0

which lock already depends on the new lock.

the existing dependency chain (in reverse order) is:

-> #4 (qcom_iommu_lock){+.+...}:
       [<c079f860>] qcom_iommu_map+0x28/0x450
       [<c079eb50>] iommu_map+0xc8/0x12c
       [<c056c1fc>] msm_iommu_map+0xb4/0x130
       [<c05697bc>] msm_gem_get_iova_locked+0x9c/0xe8
       [<c0569854>] msm_gem_get_iova+0x4c/0x64
       [<c0562208>] mdp4_kms_init+0x4c4/0x6c0
       [<c056881c>] msm_load+0x2ac/0x34c
       [<c0545724>] drm_dev_register+0xac/0x108
       [<c0547510>] drm_platform_init+0x50/0xf0
       [<c0578a60>] try_to_bring_up_master.part.3+0xc8/0x108
       [<c0578b48>] component_master_add_with_match+0xa8/0x104
       [<c0568294>] msm_pdev_probe+0x64/0x70
       [<c057e704>] platform_drv_probe+0x2c/0x60
       [<c057cff8>] driver_probe_device+0x108/0x234
       [<c057b65c>] bus_for_each_drv+0x64/0x98
       [<c057cec0>] device_attach+0x78/0x8c
       [<c057c590>] bus_probe_device+0x88/0xac
       [<c057c9b8>] deferred_probe_work_func+0x68/0x9c
       [<c0259db4>] process_one_work+0x1a0/0x40c
       [<c025a710>] worker_thread+0x44/0x4d8
       [<c025ec54>] kthread+0xd8/0xec
       [<c020e9a8>] ret_from_fork+0x14/0x2c

-> #3 (&dev->struct_mutex){+.+.+.}:
       [<c0541188>] drm_gem_mmap+0x38/0xd0
       [<c05695b8>] msm_gem_mmap+0xc/0x5c
       [<c02f0b6c>] mmap_region+0x35c/0x6c8
       [<c02f11ec>] do_mmap_pgoff+0x314/0x398
       [<c02de1e0>] vm_mmap_pgoff+0x84/0xb4
       [<c02ef83c>] SyS_mmap_pgoff+0x94/0xbc
       [<c020e8e0>] ret_fast_syscall+0x0/0x48

-> #2 (&mm->mmap_sem){++++++}:
       [<c0321138>] filldir64+0x68/0x180
       [<c0333fe0>] dcache_readdir+0x188/0x22c
       [<c0320ed0>] iterate_dir+0x9c/0x11c
       [<c03213b0>] SyS_getdents64+0x78/0xe8
       [<c020e8e0>] ret_fast_syscall+0x0/0x48

-> #1 (&sb->s_type->i_mutex_key#3){+.+.+.}:
       [<c03fc544>] __create_file+0x58/0x1dc
       [<c03fc70c>] debugfs_create_dir+0x1c/0x24
       [<c0781c7c>] clk_debug_create_subtree+0x20/0x170
       [<c0be2af8>] clk_debug_init+0xec/0x14c
       [<c0208c70>] do_one_initcall+0x8c/0x1c8
       [<c0b9cce4>] kernel_init_freeable+0x13c/0x1dc
       [<c0877bc4>] kernel_init+0x8/0xe8
       [<c020e9a8>] ret_from_fork+0x14/0x2c

-> #0 (prepare_lock){+.+.+.}:
       [<c087c408>] mutex_lock_nested+0x70/0x3e8
       [<c0781280>] clk_prepare_lock+0x88/0xfc
       [<c0782c50>] clk_prepare+0xc/0x24
       [<c079f474>] __enable_clocks.isra.4+0x18/0xa4
       [<c079f614>] __flush_iotlb_va+0xe0/0x114
       [<c079f6f4>] qcom_iommu_unmap+0xac/0x1f0
       [<c079ea3c>] iommu_unmap+0x9c/0xe8
       [<c056c2fc>] msm_iommu_unmap+0x64/0x84
       [<c0569da4>] msm_gem_free_object+0x11c/0x338
       [<c05413ec>] drm_gem_object_handle_unreference_unlocked+0xfc/0x130
       [<c0541604>] drm_gem_object_release_handle+0x50/0x68
       [<c0447a98>] idr_for_each+0xa8/0xdc
       [<c0541c10>] drm_gem_release+0x1c/0x28
       [<c0540b3c>] drm_release+0x370/0x428
       [<c031105c>] __fput+0x98/0x1e8
       [<c025d73c>] task_work_run+0xb0/0xfc
       [<c02477ec>] do_exit+0x2ec/0x948
       [<c0247ec0>] do_group_exit+0x4c/0xb8
       [<c025180c>] get_signal+0x28c/0x6ac
       [<c0211204>] do_signal+0xc4/0x3e4
       [<c02116cc>] do_work_pending+0xb4/0xc4
       [<c020e938>] work_pending+0xc/0x20

other info that might help us debug this:

Chain exists of:
  prepare_lock --> &dev->struct_mutex --> qcom_iommu_lock

 Possible unsafe locking scenario:

       CPU0                    CPU1
       ----                    ----
  lock(qcom_iommu_lock);
                               lock(&dev->struct_mutex);
                               lock(qcom_iommu_lock);
  lock(prepare_lock);

 *** DEADLOCK ***

3 locks held by Xorg.bin/5413:
 #0:  (drm_global_mutex){+.+.+.}, at: [<c0540800>] drm_release+0x34/0x428
 #1:  (&dev->struct_mutex){+.+.+.}, at: [<c05413bc>] drm_gem_object_handle_unreference_unlocked+0xcc/0x130
 #2:  (qcom_iommu_lock){+.+...}, at: [<c079f664>] qcom_iommu_unmap+0x1c/0x1f0

stack backtrace:
CPU: 1 PID: 5413 Comm: Xorg.bin Tainted: G        W      3.17.0-rc1-00050-g07a489b #802
[<c0216290>] (unwind_backtrace) from [<c0211d8c>] (show_stack+0x10/0x14)
[<c0211d8c>] (show_stack) from [<c087a078>] (dump_stack+0x98/0xb8)
[<c087a078>] (dump_stack) from [<c027f024>] (print_circular_bug+0x218/0x340)
[<c027f024>] (print_circular_bug) from [<c0283e08>] (__lock_acquire+0x1d24/0x20b8)
[<c0283e08>] (__lock_acquire) from [<c0284774>] (lock_acquire+0x9c/0xbc)
[<c0284774>] (lock_acquire) from [<c087c408>] (mutex_lock_nested+0x70/0x3e8)
[<c087c408>] (mutex_lock_nested) from [<c0781280>] (clk_prepare_lock+0x88/0xfc)
[<c0781280>] (clk_prepare_lock) from [<c0782c50>] (clk_prepare+0xc/0x24)
[<c0782c50>] (clk_prepare) from [<c079f474>] (__enable_clocks.isra.4+0x18/0xa4)
[<c079f474>] (__enable_clocks.isra.4) from [<c079f614>] (__flush_iotlb_va+0xe0/0x114)
[<c079f614>] (__flush_iotlb_va) from [<c079f6f4>] (qcom_iommu_unmap+0xac/0x1f0)
[<c079f6f4>] (qcom_iommu_unmap) from [<c079ea3c>] (iommu_unmap+0x9c/0xe8)
[<c079ea3c>] (iommu_unmap) from [<c056c2fc>] (msm_iommu_unmap+0x64/0x84)
[<c056c2fc>] (msm_iommu_unmap) from [<c0569da4>] (msm_gem_free_object+0x11c/0x338)
[<c0569da4>] (msm_gem_free_object) from [<c05413ec>] (drm_gem_object_handle_unreference_unlocked+0xfc/0x130)
[<c05413ec>] (drm_gem_object_handle_unreference_unlocked) from [<c0541604>] (drm_gem_object_release_handle+0x50/0x68)
[<c0541604>] (drm_gem_object_release_handle) from [<c0447a98>] (idr_for_each+0xa8/0xdc)
[<c0447a98>] (idr_for_each) from [<c0541c10>] (drm_gem_release+0x1c/0x28)
[<c0541c10>] (drm_gem_release) from [<c0540b3c>] (drm_release+0x370/0x428)
[<c0540b3c>] (drm_release) from [<c031105c>] (__fput+0x98/0x1e8)
[<c031105c>] (__fput) from [<c025d73c>] (task_work_run+0xb0/0xfc)
[<c025d73c>] (task_work_run) from [<c02477ec>] (do_exit+0x2ec/0x948)
[<c02477ec>] (do_exit) from [<c0247ec0>] (do_group_exit+0x4c/0xb8)
[<c0247ec0>] (do_group_exit) from [<c025180c>] (get_signal+0x28c/0x6ac)
[<c025180c>] (get_signal) from [<c0211204>] (do_signal+0xc4/0x3e4)
[<c0211204>] (do_signal) from [<c02116cc>] (do_work_pending+0xb4/0xc4)
[<c02116cc>] (do_work_pending) from [<c020e938>] (work_pending+0xc/0x20)

We can break this chain if we don't hold the prepare_lock while
creating debugfs directories. We only hold the prepare_lock right
now because we're traversing the clock tree recursively and we
don't want the hierarchy to change during the traversal.
Replacing this traversal with a simple linked list walk allows us
to only grab a list lock instead of the prepare_lock, thus
breaking the lock chain.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Mike Turquette <mturquette@linaro.org>
2014-09-10 14:36:20 -07:00
..
at91 clk: at91: main: warn when the main crystal frequency is not set 2014-07-02 09:00:52 -07:00
bcm clk: bcm/kona: implement determine_rate() 2014-05-27 17:34:32 -07:00
berlin clk: berlin: add core clock driver for BG2Q 2014-05-29 09:30:19 -07:00
hisilicon clk: hisi: add clk-hix5hd2.c 2014-05-12 11:30:32 +08:00
keystone clk: keystone: gate: fix clk_init_data initialization 2014-02-10 15:17:43 -05:00
mmp clk: mmp: try to use closer one when do round rate 2014-03-26 20:59:27 -07:00
mvebu clk: mvebu: extend clk-cpu for dynamic frequency scaling 2014-07-16 12:58:38 +00:00
mxs ARM: mxs: remove custom .init_time hook 2013-09-29 21:09:34 +02:00
qcom qcom clock changes for 3.17 2014-07-25 15:41:19 -07:00
rockchip clk: rockchip: add clock controller for rk3288 2014-07-13 12:17:10 -07:00
samsung ARM: SoC platform changes for 3.17 2014-08-08 11:14:29 -07:00
shmobile clk: shmobile: Add R8A7740-specific clock support 2014-05-23 13:38:25 -07:00
sirf clk: sirf: update copyright years to 2014 2014-03-26 21:47:35 -07:00
socfpga Adds support getting the divider registers for the MAIN PLL that was once 2014-05-12 19:11:13 -07:00
spear Merge branch 'clk-fixes' into clk-next 2014-07-13 07:56:45 -07:00
st clk: st: Use round to closest divider flag 2014-07-28 22:37:16 -07:00
sunxi clk: sunxi: staticize structures and arrays 2014-07-28 15:39:22 -07:00
tegra ARM: SoC cleanups for 3.17 2014-08-08 11:00:26 -07:00
ti The clock framework changes for 3.17 are mostly additions of new clock 2014-08-04 11:44:20 -07:00
ux500 clk: ux500: Staticize ux500_twocell_get 2014-02-23 15:04:40 -08:00
versatile clk: versatile: add versatile OSC support 2014-06-24 14:21:22 -05:00
x86 ACPI / LPSS: add support for Intel BayTrail 2013-06-19 01:08:47 +02:00
zynq clk: zynq: Leave debug clocks in bootup state 2014-04-22 13:10:18 +02:00
clk-axi-clkgen.c clk: axi-clkgen: Add support for v2 2014-02-26 17:02:29 -08:00
clk-axm5516.c clk: Add clock driver for AXM55xx SoC 2014-05-22 22:06:14 -07:00
clk-bcm2835.c ARM: bcm2835: remove custom .init_time hook 2013-09-29 21:09:24 +02:00
clk-clps711x.c clk: Add CLPS711X clk driver 2014-07-28 23:30:46 -07:00
clk-composite.c clk: composite: improve rate_hw sanity check logic 2014-07-13 12:17:05 -07:00
clk-conf.c clk: Add missing of_clk_set_defaults export 2014-08-04 09:48:39 -07:00
clk-devres.c
clk-divider.c clk: divider: Fix overflow in clk_divider_bestdiv 2014-05-27 19:16:24 -07:00
clk-efm32gg.c clk: new driver for efm32 SoC 2013-11-04 12:23:18 -08:00
clk-fixed-factor.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial 2013-11-15 16:47:22 -08:00
clk-fixed-rate.c clk: add accuracy support for fixed clock 2013-12-22 23:14:28 -08:00
clk-fractional-divider.c clk: new basic clk type for fractional divider 2014-05-20 13:34:02 +02:00
clk-gate.c clk: wrap I/O access for improved portability 2013-08-27 17:50:38 -07:00
clk-highbank.c ARM: highbank: remove custom .init_time hook 2013-09-29 21:09:29 +02:00
clk-ls1x.c
clk-max77686.c clk: max77686: Register OF clock provider 2014-01-08 09:57:07 -08:00
clk-moxart.c clk: add MOXA ART SoCs clock driver 2014-03-18 17:13:14 -07:00
clk-mux.c clk: wrap I/O access for improved portability 2013-08-27 17:50:38 -07:00
clk-nomadik.c clk: nomadik: fix multiplatform problem 2014-02-26 11:14:44 -08:00
clk-nspire.c clk: Add TI-Nspire clock drivers 2013-05-31 12:07:45 -07:00
clk-palmas.c clk: Add driver for Palmas clk32kg and clk32kgaudio clocks 2014-07-01 21:37:57 -07:00
clk-ppc-corenet.c clk: ppc-corenet: Fix Section mismatch warning 2014-07-01 20:11:22 -07:00
clk-s2mps11.c Merge branch 'clk-fixes' into clk-next 2014-07-03 11:55:42 -07:00
clk-si570.c clk: si570: Fix email address specifiction 2014-05-20 16:18:18 +02:00
clk-si5351.c The second half of the clock framework pull requeust for 3.14 is 2014-01-28 18:44:53 -08:00
clk-si5351.h clk: si5351: remove variant from platform_data 2014-01-27 11:20:22 -08:00
clk-twl6040.c
clk-u300.c clk: u300: Terminate of match table 2014-05-27 18:29:04 -07:00
clk-vt8500.c clk: vt8500: Staticize vtwm_pll_ops 2013-12-19 17:47:32 -08:00
clk-wm831x.c clk: wm831x: get rid of the implementation of remove function 2013-10-02 01:23:34 -07:00
clk-xgene.c clk: Add APM X-Gene SoC clock driver 2013-10-07 11:22:15 -07:00
clk.c clk: Don't hold prepare_lock across debugfs creation 2014-09-10 14:36:20 -07:00
clk.h clk: Add of_clk_get_by_clkspec() helper 2014-05-22 15:54:59 -07:00
clkdev.c clkdev: Don't print errors on probe defer 2014-06-26 12:55:03 -07:00
Kconfig clk: Add driver for Palmas clk32kg and clk32kgaudio clocks 2014-07-01 21:37:57 -07:00
Makefile clk: Add CLPS711X clk driver 2014-07-28 23:30:46 -07:00