diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2014-09-05 02:37:49 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2014-09-10 17:36:20 -0400 |
commit | 6314b6796e3c070d4c8086b08dfd453a0aeac4cf (patch) | |
tree | 6798b7305e754b7e7f286129bb612889657a5e8b | |
parent | 69e273c0b0a3c337a521d083374c918dc52c666f (diff) |
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>
-rw-r--r-- | drivers/clk/clk.c | 73 | ||||
-rw-r--r-- | include/linux/clk-private.h | 1 |
2 files changed, 28 insertions, 46 deletions
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b76fa69b44cb..8ca28189e4e9 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -100,6 +100,8 @@ static void clk_enable_unlock(unsigned long flags) | |||
100 | 100 | ||
101 | static struct dentry *rootdir; | 101 | static struct dentry *rootdir; |
102 | static int inited = 0; | 102 | static int inited = 0; |
103 | static DEFINE_MUTEX(clk_debug_lock); | ||
104 | static HLIST_HEAD(clk_debug_list); | ||
103 | 105 | ||
104 | static struct hlist_head *all_lists[] = { | 106 | static struct hlist_head *all_lists[] = { |
105 | &clk_root_list, | 107 | &clk_root_list, |
@@ -300,28 +302,6 @@ out: | |||
300 | return ret; | 302 | return ret; |
301 | } | 303 | } |
302 | 304 | ||
303 | /* caller must hold prepare_lock */ | ||
304 | static int clk_debug_create_subtree(struct clk *clk, struct dentry *pdentry) | ||
305 | { | ||
306 | struct clk *child; | ||
307 | int ret = -EINVAL;; | ||
308 | |||
309 | if (!clk || !pdentry) | ||
310 | goto out; | ||
311 | |||
312 | ret = clk_debug_create_one(clk, pdentry); | ||
313 | |||
314 | if (ret) | ||
315 | goto out; | ||
316 | |||
317 | hlist_for_each_entry(child, &clk->children, child_node) | ||
318 | clk_debug_create_subtree(child, pdentry); | ||
319 | |||
320 | ret = 0; | ||
321 | out: | ||
322 | return ret; | ||
323 | } | ||
324 | |||
325 | /** | 305 | /** |
326 | * clk_debug_register - add a clk node to the debugfs clk tree | 306 | * clk_debug_register - add a clk node to the debugfs clk tree |
327 | * @clk: the clk being added to the debugfs clk tree | 307 | * @clk: the clk being added to the debugfs clk tree |
@@ -329,20 +309,21 @@ out: | |||
329 | * Dynamically adds a clk to the debugfs clk tree if debugfs has been | 309 | * Dynamically adds a clk to the debugfs clk tree if debugfs has been |
330 | * initialized. Otherwise it bails out early since the debugfs clk tree | 310 | * initialized. Otherwise it bails out early since the debugfs clk tree |
331 | * will be created lazily by clk_debug_init as part of a late_initcall. | 311 | * will be created lazily by clk_debug_init as part of a late_initcall. |
332 | * | ||
333 | * Caller must hold prepare_lock. Only clk_init calls this function (so | ||
334 | * far) so this is taken care. | ||
335 | */ | 312 | */ |
336 | static int clk_debug_register(struct clk *clk) | 313 | static int clk_debug_register(struct clk *clk) |
337 | { | 314 | { |
338 | int ret = 0; | 315 | int ret = 0; |
339 | 316 | ||
317 | mutex_lock(&clk_debug_lock); | ||
318 | hlist_add_head(&clk->debug_node, &clk_debug_list); | ||
319 | |||
340 | if (!inited) | 320 | if (!inited) |
341 | goto out; | 321 | goto unlock; |
342 | 322 | ||
343 | ret = clk_debug_create_subtree(clk, rootdir); | 323 | ret = clk_debug_create_one(clk, rootdir); |
324 | unlock: | ||
325 | mutex_unlock(&clk_debug_lock); | ||
344 | 326 | ||
345 | out: | ||
346 | return ret; | 327 | return ret; |
347 | } | 328 | } |
348 | 329 | ||
@@ -353,12 +334,18 @@ out: | |||
353 | * Dynamically removes a clk and all it's children clk nodes from the | 334 | * Dynamically removes a clk and all it's children clk nodes from the |
354 | * debugfs clk tree if clk->dentry points to debugfs created by | 335 | * debugfs clk tree if clk->dentry points to debugfs created by |
355 | * clk_debug_register in __clk_init. | 336 | * clk_debug_register in __clk_init. |
356 | * | ||
357 | * Caller must hold prepare_lock. | ||
358 | */ | 337 | */ |
359 | static void clk_debug_unregister(struct clk *clk) | 338 | static void clk_debug_unregister(struct clk *clk) |
360 | { | 339 | { |
340 | mutex_lock(&clk_debug_lock); | ||
341 | if (!clk->dentry) | ||
342 | goto out; | ||
343 | |||
344 | hlist_del_init(&clk->debug_node); | ||
361 | debugfs_remove_recursive(clk->dentry); | 345 | debugfs_remove_recursive(clk->dentry); |
346 | clk->dentry = NULL; | ||
347 | out: | ||
348 | mutex_unlock(&clk_debug_lock); | ||
362 | } | 349 | } |
363 | 350 | ||
364 | struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode, | 351 | struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode, |
@@ -415,17 +402,12 @@ static int __init clk_debug_init(void) | |||
415 | if (!d) | 402 | if (!d) |
416 | return -ENOMEM; | 403 | return -ENOMEM; |
417 | 404 | ||
418 | clk_prepare_lock(); | 405 | mutex_lock(&clk_debug_lock); |
419 | 406 | hlist_for_each_entry(clk, &clk_debug_list, debug_node) | |
420 | hlist_for_each_entry(clk, &clk_root_list, child_node) | 407 | clk_debug_create_one(clk, rootdir); |
421 | clk_debug_create_subtree(clk, rootdir); | ||
422 | |||
423 | hlist_for_each_entry(clk, &clk_orphan_list, child_node) | ||
424 | clk_debug_create_subtree(clk, rootdir); | ||
425 | 408 | ||
426 | inited = 1; | 409 | inited = 1; |
427 | 410 | mutex_unlock(&clk_debug_lock); | |
428 | clk_prepare_unlock(); | ||
429 | 411 | ||
430 | return 0; | 412 | return 0; |
431 | } | 413 | } |
@@ -2087,14 +2069,16 @@ void clk_unregister(struct clk *clk) | |||
2087 | { | 2069 | { |
2088 | unsigned long flags; | 2070 | unsigned long flags; |
2089 | 2071 | ||
2090 | if (!clk || WARN_ON_ONCE(IS_ERR(clk))) | 2072 | if (!clk || WARN_ON_ONCE(IS_ERR(clk))) |
2091 | return; | 2073 | return; |
2074 | |||
2075 | clk_debug_unregister(clk); | ||
2092 | 2076 | ||
2093 | clk_prepare_lock(); | 2077 | clk_prepare_lock(); |
2094 | 2078 | ||
2095 | if (clk->ops == &clk_nodrv_ops) { | 2079 | if (clk->ops == &clk_nodrv_ops) { |
2096 | pr_err("%s: unregistered clock: %s\n", __func__, clk->name); | 2080 | pr_err("%s: unregistered clock: %s\n", __func__, clk->name); |
2097 | goto out; | 2081 | return; |
2098 | } | 2082 | } |
2099 | /* | 2083 | /* |
2100 | * Assign empty clock ops for consumers that might still hold | 2084 | * Assign empty clock ops for consumers that might still hold |
@@ -2113,16 +2097,13 @@ void clk_unregister(struct clk *clk) | |||
2113 | clk_set_parent(child, NULL); | 2097 | clk_set_parent(child, NULL); |
2114 | } | 2098 | } |
2115 | 2099 | ||
2116 | clk_debug_unregister(clk); | ||
2117 | |||
2118 | hlist_del_init(&clk->child_node); | 2100 | hlist_del_init(&clk->child_node); |
2119 | 2101 | ||
2120 | if (clk->prepare_count) | 2102 | if (clk->prepare_count) |
2121 | pr_warn("%s: unregistering prepared clock: %s\n", | 2103 | pr_warn("%s: unregistering prepared clock: %s\n", |
2122 | __func__, clk->name); | 2104 | __func__, clk->name); |
2123 | |||
2124 | kref_put(&clk->ref, __clk_release); | 2105 | kref_put(&clk->ref, __clk_release); |
2125 | out: | 2106 | |
2126 | clk_prepare_unlock(); | 2107 | clk_prepare_unlock(); |
2127 | } | 2108 | } |
2128 | EXPORT_SYMBOL_GPL(clk_unregister); | 2109 | EXPORT_SYMBOL_GPL(clk_unregister); |
diff --git a/include/linux/clk-private.h b/include/linux/clk-private.h index efbf70b9fd84..4ed34105c371 100644 --- a/include/linux/clk-private.h +++ b/include/linux/clk-private.h | |||
@@ -48,6 +48,7 @@ struct clk { | |||
48 | unsigned long accuracy; | 48 | unsigned long accuracy; |
49 | struct hlist_head children; | 49 | struct hlist_head children; |
50 | struct hlist_node child_node; | 50 | struct hlist_node child_node; |
51 | struct hlist_node debug_node; | ||
51 | unsigned int notifier_count; | 52 | unsigned int notifier_count; |
52 | #ifdef CONFIG_DEBUG_FS | 53 | #ifdef CONFIG_DEBUG_FS |
53 | struct dentry *dentry; | 54 | struct dentry *dentry; |