]> git.hungrycats.org Git - linux/commitdiff
[BRIDGE]: Fix deadlock on device removal.
authorStephen Hemminger <shemminger@osdl.org>
Sat, 22 May 2004 06:38:39 +0000 (23:38 -0700)
committerStephen Hemminger <shemminger@osdl.org>
Sat, 22 May 2004 06:38:39 +0000 (23:38 -0700)
Fix a deadlock where deleting a device call br_del_if with lock held.
br_del_if doesn't want to be called under lock anymore.

net/bridge/br_notify.c

index 594bb5bca5d7f46725634c82025fa5ff5c7aee59..c59335e3b49b126ca6f52f6fc9960d5dbb6a00b7 100644 (file)
@@ -38,30 +38,35 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
 
        br = p->br;
 
-       spin_lock_bh(&br->lock);
-       switch (event) 
-       {
+       switch (event) {
        case NETDEV_CHANGEADDR:
+               spin_lock_bh(&br->lock);
                br_fdb_changeaddr(p, dev->dev_addr);
                if (br->dev->flags & IFF_UP)
                        br_stp_recalculate_bridge_id(br);
+               spin_unlock_bh(&br->lock);
                break;
 
        case NETDEV_DOWN:
-               if (br->dev->flags & IFF_UP)
+               if (br->dev->flags & IFF_UP) {
+                       spin_lock_bh(&br->lock);
                        br_stp_disable_port(p);
+                       spin_unlock_bh(&br->lock);
+               }
                break;
 
        case NETDEV_UP:
-               if (br->dev->flags & IFF_UP)
+               if (br->dev->flags & IFF_UP) {
+                       spin_lock_bh(&br->lock);
                        br_stp_enable_port(p);
+                       spin_unlock_bh(&br->lock);
+               }
                break;
 
        case NETDEV_UNREGISTER:
                br_del_if(br, dev);
                break;
        }
-       spin_unlock_bh(&br->lock);
 
        return NOTIFY_DONE;
 }