Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=eb2a021c4710b98081daa797d5a729ac23c240cd
Commit:     eb2a021c4710b98081daa797d5a729ac23c240cd
Parent:     1ca949299260aa49eeba34ff912e2321c8b1f647
Author:     Francois Romieu <[EMAIL PROTECTED]>
AuthorDate: Thu Feb 15 23:37:21 2007 +0100
Committer:  Jeff Garzik <[EMAIL PROTECTED]>
CommitDate: Tue Feb 20 11:18:12 2007 -0500

    r8169: RTNL and flush_scheduled_work deadlock
    
    flush_scheduled_work() in net_device->close has a slight tendency
    to deadlock with tasks on the workqueue that hold RTNL.
    
    rtl8169_close/down simply need the recovery tasks to not meddle
    with the hardware while the device is going down.
    
    Signed-off-by: Francois Romieu <[EMAIL PROTECTED]>
    Signed-off-by: Jeff Garzik <[EMAIL PROTECTED]>
---
 drivers/net/r8169.c |   25 ++++++++++++++++++-------
 1 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 5598d86..13cf06e 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1733,6 +1733,8 @@ rtl8169_remove_one(struct pci_dev *pdev)
        assert(dev != NULL);
        assert(tp != NULL);
 
+       flush_scheduled_work();
+
        unregister_netdev(dev);
        rtl8169_release_board(pdev, dev, tp->mmio_addr);
        pci_set_drvdata(pdev, NULL);
@@ -2161,10 +2163,13 @@ static void rtl8169_reinit_task(struct work_struct 
*work)
        struct net_device *dev = tp->dev;
        int ret;
 
-       if (netif_running(dev)) {
-               rtl8169_wait_for_quiescence(dev);
-               rtl8169_close(dev);
-       }
+       rtnl_lock();
+
+       if (!netif_running(dev))
+               goto out_unlock;
+
+       rtl8169_wait_for_quiescence(dev);
+       rtl8169_close(dev);
 
        ret = rtl8169_open(dev);
        if (unlikely(ret < 0)) {
@@ -2179,6 +2184,9 @@ static void rtl8169_reinit_task(struct work_struct *work)
                }
                rtl8169_schedule_work(dev, rtl8169_reinit_task);
        }
+
+out_unlock:
+       rtnl_unlock();
 }
 
 static void rtl8169_reset_task(struct work_struct *work)
@@ -2187,8 +2195,10 @@ static void rtl8169_reset_task(struct work_struct *work)
                container_of(work, struct rtl8169_private, task.work);
        struct net_device *dev = tp->dev;
 
+       rtnl_lock();
+
        if (!netif_running(dev))
-               return;
+               goto out_unlock;
 
        rtl8169_wait_for_quiescence(dev);
 
@@ -2210,6 +2220,9 @@ static void rtl8169_reset_task(struct work_struct *work)
                }
                rtl8169_schedule_work(dev, rtl8169_reset_task);
        }
+
+out_unlock:
+       rtnl_unlock();
 }
 
 static void rtl8169_tx_timeout(struct net_device *dev)
@@ -2722,8 +2735,6 @@ static void rtl8169_down(struct net_device *dev)
 
        netif_stop_queue(dev);
 
-       flush_scheduled_work();
-
 core_down:
        spin_lock_irq(&tp->lock);
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to