Messages in this thread Patch in this message |  | | From | Duoming Zhou <> | Subject | [PATCH V2 10/11] arch: xtensa: platforms: Fix deadlock in iss_net_close() | Date | Sat, 9 Apr 2022 13:51:35 +0800 |
| |
There is a deadlock in iss_net_close(), which is shown below:
(Thread 1) | (Thread 2) | iss_net_open() iss_net_close() | mod_timer() spin_lock_bh() //(1) | (wait a time) ... | iss_net_timer() del_timer_sync() | spin_lock() //(2) (wait timer to stop) | ...
We hold lp->lock in position (1) of thread 1 and use del_timer_sync() to wait timer to stop, but timer handler also need lp->lock in position (2) of thread 2. As a result, iss_net_close() will block forever.
This patch extracts del_timer_sync() from the protection of spin_lock_bh(), which could let timer handler to obtain the needed lock. What`s more, we should remove spin_lock() in iss_net_timer(), because there is no resource need to protect and spin_lock() may cause deadlock in timer handler.
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn> --- Changes in V2: - Remove spin_lock() in iss_net_timer().
arch/xtensa/platforms/iss/network.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c index be3aaaad8be..1ae39c18c6e 100644 --- a/arch/xtensa/platforms/iss/network.c +++ b/arch/xtensa/platforms/iss/network.c @@ -352,9 +352,7 @@ static void iss_net_timer(struct timer_list *t) struct iss_net_private *lp = from_timer(lp, t, timer); iss_net_poll(); - spin_lock(&lp->lock); mod_timer(&lp->timer, jiffies + lp->timer_val); - spin_unlock(&lp->lock); } @@ -403,7 +401,9 @@ static int iss_net_close(struct net_device *dev) list_del(&opened); spin_unlock(&opened_lock); + spin_unlock_bh(&lp->lock); del_timer_sync(&lp->timer); + spin_lock_bh(&lp->lock); lp->tp.close(lp); -- 2.17.1
|  |