summaryrefslogtreecommitdiff
path: root/mm/memfd.c
diff options
context:
space:
mode:
authorYang Yingliang <yangyingliang@huawei.com>2022-12-05 11:04:34 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-01-19 19:26:31 +0300
commit25d5648802f12ae486076ceca5d7ddf1fef792b2 (patch)
tree64b803732e76f46804dd448149b9fde901619b30 /mm/memfd.c
parent2efb6edd52dc50273f5e68ad863dd1b1fb2f2d1c (diff)
downloadlinux-25d5648802f12ae486076ceca5d7ddf1fef792b2.tar.xz
w1: fix deadloop in __w1_remove_master_device()
I got a deadloop report while doing device(ds2482) add/remove test: [ 162.241881] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1. [ 163.272251] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1. [ 164.296157] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1. ... __w1_remove_master_device() can't return, because the dev->refcnt is not zero. w1_add_master_device() | w1_alloc_dev() | atomic_set(&dev->refcnt, 2) | kthread_run() | |__w1_remove_master_device() | kthread_stop() // KTHREAD_SHOULD_STOP is set, | // threadfn(w1_process) won't be | // called. | kthread() | | // refcnt will never be 0, it's deadloop. | while (atomic_read(&dev->refcnt)) {...} After calling w1_add_master_device(), w1_process() is not really invoked, before w1_process() starting, if kthread_stop() is called in __w1_remove_master_device(), w1_process() will never be called, the refcnt can not be decreased, then it causes deadloop in remove function because of non-zero refcnt. We need to make sure w1_process() is really started, so move the set refcnt into w1_process() to fix this problem. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Link: https://lore.kernel.org/r/20221205080434.3149205-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'mm/memfd.c')
0 files changed, 0 insertions, 0 deletions