• Duoming Zhou's avatar
    can: grcan: grcan_close(): fix deadlock · 47f070a6
    Duoming Zhou authored
    There are deadlocks caused by del_timer_sync(&priv->hang_timer) and
    del_timer_sync(&priv->rr_timer) in grcan_close(), one of the deadlocks
    are shown below:
    
       (Thread 1)              |      (Thread 2)
                               | grcan_reset_timer()
    grcan_close()              |  mod_timer()
     spin_lock_irqsave() //(1) |  (wait a time)
     ...                       | grcan_initiate_running_reset()
     del_timer_sync()          |  spin_lock_irqsave() //(2)
     (wait timer to stop)      |  ...
    
    We hold priv->lock in position (1) of thread 1 and use
    del_timer_sync() to wait timer to stop, but timer handler also need
    priv->lock in position (2) of thread 2. As a result, grcan_close()
    will block forever.
    
    This patch extracts del_timer_sync() from the protection of
    spin_lock_irqsave(), which could let timer handler to obtain the
    needed lock.
    
    Link: https://lore.kernel.org/all/20220425042400.66517-1-duoming@zju.edu.cn
    Fixes: 6cec9b07 ("can: grcan: Add device driver for GRCAN and GRHCAN cores")
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarDuoming Zhou <duoming@zju.edu.cn>
    Reviewed-by: default avatarAndreas Larsson <andreas@gaisler.com>
    Signed-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
    47f070a6
grcan.c 49 KB