summaryrefslogtreecommitdiffstats
path: root/drivers/soc
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2017-06-30 11:47:21 -0400
committerAndy Gross <andy.gross@linaro.org>2017-08-08 14:37:42 -0500
commit3e8b55411468ef9aa4401282a869715c45b0310b (patch)
tree772cc42626e9ab015fd367a8a5289a65089ba8e0 /drivers/soc
parent5771a8c08880cdca3bfb4a3fc6d309d6bba20877 (diff)
downloadop-kernel-dev-3e8b55411468ef9aa4401282a869715c45b0310b.zip
op-kernel-dev-3e8b55411468ef9aa4401282a869715c45b0310b.tar.gz
soc: qcom: smsm: fix of_node refcnting problem
of_find_node_with_property() drops the reference to the 'from' node, which eventually (after enough -EPROBE_DEFERs) drops the last reference to the node causing all sorts of fun problems, and this nice splat. BUG: sleeping function called from invalid context at ../kernel/locking/mutex.c:747 in_atomic(): 1, irqs_disabled(): 128, pid: 33, name: kworker/0:1 4 locks held by kworker/0:1/33: #0: ("events"){.+.+.+}, at: [<ffff0000080fa91c>] process_one_work+0x1a4/0x728 #1: (deferred_probe_work){+.+.+.}, at: [<ffff0000080fa91c>] process_one_work+0x1a4/0x728 #2: (&dev->mutex){......}, at: [<ffff000008676078>] __device_attach+0x30/0x168 #3: (devtree_lock){......}, at: [<ffff000008828fd0>] of_find_node_with_property+0x30/0xe0 irq event stamp: 18976 hardirqs last enabled at (18975): [<ffff00000815794c>] __down_trylock_console_sem+0x74/0xb8 hardirqs last disabled at (18976): [<ffff0000089e26d4>] _raw_spin_lock_irqsave+0x2c/0x78 softirqs last enabled at (16880): [<ffff0000080e0f00>] __do_softirq+0x580/0x640 softirqs last disabled at (16871): [<ffff0000080e13a4>] irq_exit+0xe4/0x138 CPU: 0 PID: 33 Comm: kworker/0:1 Tainted: G E 4.12.0-rc5+ #1455 Hardware name: qualcomm dragonboard410c/dragonboard410c, BIOS 2017.07-rc1-00234-g22fa70a-dirty 06/26/2017 Workqueue: events deferred_probe_work_func Call trace: [<ffff000008089ee0>] dump_backtrace+0x0/0x230 [<ffff00000808a134>] show_stack+0x24/0x30 [<ffff0000084e1944>] dump_stack+0xac/0xe8 [<ffff00000810d7e0>] ___might_sleep+0x150/0x230 [<ffff00000810d918>] __might_sleep+0x58/0x90 [<ffff0000089dde18>] __mutex_lock+0x50/0x870 [<ffff0000089de674>] mutex_lock_nested+0x3c/0x50 [<ffff000008388ae0>] kernfs_remove+0x30/0x50 [<ffff00000838b720>] sysfs_remove_dir+0x58/0x70 [<ffff0000084e393c>] kobject_del+0x1c/0x58 [<ffff0000084e374c>] kobject_put+0xb4/0x208 [<ffff00000882c364>] of_node_put+0x24/0x30 [<ffff000008829018>] of_find_node_with_property+0x78/0xe0 [<ffff000000aff5f4>] qcom_smsm_probe+0x194/0x720 [smsm] [<ffff0000086793b4>] platform_drv_probe+0x74/0x110 [<ffff0000086765bc>] driver_probe_device+0x2b4/0x420 [<ffff000008676920>] __device_attach_driver+0xd0/0x150 [<ffff000008673e78>] bus_for_each_drv+0x68/0xa8 [<ffff00000867611c>] __device_attach+0xd4/0x168 [<ffff000008676a1c>] device_initial_probe+0x24/0x30 [<ffff000008675380>] bus_probe_device+0xa0/0xa8 [<ffff000008675948>] deferred_probe_work_func+0xb8/0xf8 [<ffff0000080fa9d4>] process_one_work+0x25c/0x728 [<ffff0000080faef4>] worker_thread+0x54/0x3d8 [<ffff0000081031d8>] kthread+0x110/0x140 [<ffff000008082d90>] ret_from_fork+0x10/0x40 OF: ERROR: Bad of_node_put() on /smsm CPU: 0 PID: 33 Comm: kworker/0:1 Tainted: G W E 4.12.0-rc5+ #1455 Hardware name: qualcomm dragonboard410c/dragonboard410c, BIOS 2017.07-rc1-00234-g22fa70a-dirty 06/26/2017 Workqueue: events deferred_probe_work_func Signed-off-by: Rob Clark <robdclark@gmail.com> Signed-off-by: Andy Gross <andy.gross@linaro.org>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/qcom/smsm.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c
index dc540ea9..403bea9 100644
--- a/drivers/soc/qcom/smsm.c
+++ b/drivers/soc/qcom/smsm.c
@@ -496,7 +496,8 @@ static int qcom_smsm_probe(struct platform_device *pdev)
if (!smsm->hosts)
return -ENOMEM;
- local_node = of_find_node_with_property(pdev->dev.of_node, "#qcom,smem-state-cells");
+ local_node = of_find_node_with_property(of_node_get(pdev->dev.of_node),
+ "#qcom,smem-state-cells");
if (!local_node) {
dev_err(&pdev->dev, "no state entry\n");
return -EINVAL;
OpenPOWER on IntegriCloud