aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2014-09-05 02:37:49 -0400
committerMike Turquette <mturquette@linaro.org>2014-09-10 17:36:20 -0400
commit6314b6796e3c070d4c8086b08dfd453a0aeac4cf (patch)
tree6798b7305e754b7e7f286129bb612889657a5e8b
parent69e273c0b0a3c337a521d083374c918dc52c666f (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.c73
-rw-r--r--include/linux/clk-private.h1
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
101static struct dentry *rootdir; 101static struct dentry *rootdir;
102static int inited = 0; 102static int inited = 0;
103static DEFINE_MUTEX(clk_debug_lock);
104static HLIST_HEAD(clk_debug_list);
103 105
104static struct hlist_head *all_lists[] = { 106static 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 */
304static 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;
321out:
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 */
336static int clk_debug_register(struct clk *clk) 313static 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);
324unlock:
325 mutex_unlock(&clk_debug_lock);
344 326
345out:
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 */
359static void clk_debug_unregister(struct clk *clk) 338static 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;
347out:
348 mutex_unlock(&clk_debug_lock);
362} 349}
363 350
364struct dentry *clk_debugfs_add_file(struct clk *clk, char *name, umode_t mode, 351struct 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);
2125out: 2106
2126 clk_prepare_unlock(); 2107 clk_prepare_unlock();
2127} 2108}
2128EXPORT_SYMBOL_GPL(clk_unregister); 2109EXPORT_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;