tg3: tg3_reset_task() needs to use rtnl_lock to synchronize
authorPrashant Sreedharan <prashant@broadcom.com>
Wed, 14 Jan 2015 19:34:17 +0000 (11:34 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 14 Jan 2015 22:05:51 +0000 (17:05 -0500)
Currently tg3_reset_task() uses only tp->lock for synchronizing with code
paths like tg3_open() etc. But since tp->lock is released before doing
synchronize_irq(), rtnl_lock should be taken in tg3_reset_task() to
synchronize it with other code paths.

Reported-by: Peter Hurley <peter@hurleysoftware.com>
Tested-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Prashant Sreedharan <prashant@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/tg3.c

index 2dbd4aea01f3ba8f9b09852a2c0ec5fbfcead6d3..9247ae1412cc2ac29d312b7badf9a4edb4945cae 100644 (file)
@@ -11103,11 +11103,13 @@ static void tg3_reset_task(struct work_struct *work)
        struct tg3 *tp = container_of(work, struct tg3, reset_task);
        int err;
 
+       rtnl_lock();
        tg3_full_lock(tp, 0);
 
        if (!netif_running(tp->dev)) {
                tg3_flag_clear(tp, RESET_TASK_PENDING);
                tg3_full_unlock(tp);
+               rtnl_unlock();
                return;
        }
 
@@ -11140,6 +11142,7 @@ out:
                tg3_phy_start(tp);
 
        tg3_flag_clear(tp, RESET_TASK_PENDING);
+       rtnl_unlock();
 }
 
 static int tg3_request_irq(struct tg3 *tp, int irq_num)