usb: chipidea: fix deadlock in ci_otg_del_timer
stable inclusion from stable-v5.10.156 commit efaab055201b4e44824676f4281ba5bfcaa4a588 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7MCG1 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=efaab055201b4e44824676f4281ba5bfcaa4a588 -------------------------------- commit 7a58b8d6 upstream. There is a deadlock in ci_otg_del_timer(), the process is shown below: (thread 1) | (thread 2) ci_otg_del_timer() | ci_otg_hrtimer_func() ... | spin_lock_irqsave() //(1) | ... ... | hrtimer_cancel() | spin_lock_irqsave() //(2) (block forever) We hold ci->lock in position (1) and use hrtimer_cancel() to wait ci_otg_hrtimer_func() to stop, but ci_otg_hrtimer_func() also need ci->lock in position (2). As a result, the hrtimer_cancel() in ci_otg_del_timer() will be blocked forever. This patch extracts hrtimer_cancel() from the protection of spin_lock_irqsave() in order that the ci_otg_hrtimer_func() could obtain the ci->lock. What`s more, there will be no race happen. Because the "next_timer" is always under the protection of spin_lock_irqsave() and we only check whether "next_timer" equals to NUM_OTG_FSM_TIMERS in the following code. Fixes: 3a316ec4 ("usb: chipidea: use hrtimer for otg fsm timers") Cc: stable <stable@kernel.org> Signed-off-by: NDuoming Zhou <duoming@zju.edu.cn> Link: https://lore.kernel.org/r/20220918033312.94348-1-duoming@zju.edu.cnSigned-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Nsanglipeng <sanglipeng1@jd.com> (cherry picked from commit e36e04ba)
Showing
想要评论请 注册 或 登录