Patch from Stephen Hemminger Remove brlock from snap and vlan. Change in snap unregister path from earlier version to use synchronize_kernel. This code needs further testing before final 2.5 inclusion. (Kind of wonder if anyone actually ever uses this?) 25-akpm/net/802/psnap.c | 24 +++++++++++------------- 25-akpm/net/8021q/vlan.c | 8 ++++---- 25-akpm/net/8021q/vlan_dev.c | 1 - 3 files changed, 15 insertions(+), 18 deletions(-) diff -puN net/8021q/vlan.c~brlock-removal-2 net/8021q/vlan.c --- 25/net/8021q/vlan.c~brlock-removal-2 Thu Mar 13 15:14:34 2003 +++ 25-akpm/net/8021q/vlan.c Thu Mar 13 15:14:34 2003 @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -68,7 +67,6 @@ static struct packet_type vlan_packet_ty .dev =NULL, .func = vlan_skb_recv, /* VLAN receive method */ .data = (void *)(-1), /* Set here '(void *)1' when this code can SHARE SKBs */ - .next = NULL }; /* End of global variables definitions. */ @@ -231,9 +229,11 @@ static int unregister_vlan_dev(struct ne real_dev->vlan_rx_kill_vid(real_dev, vlan_id); } - br_write_lock(BR_NETPROTO_LOCK); grp->vlan_devices[vlan_id] = NULL; - br_write_unlock(BR_NETPROTO_LOCK); + + /* wait for RCU in network receive */ + smp_wmb(); + synchronize_kernel(); /* Caller unregisters (and if necessary, puts) diff -puN net/8021q/vlan_dev.c~brlock-removal-2 net/8021q/vlan_dev.c --- 25/net/8021q/vlan_dev.c~brlock-removal-2 Thu Mar 13 15:14:34 2003 +++ 25-akpm/net/8021q/vlan_dev.c Thu Mar 13 15:14:34 2003 @@ -31,7 +31,6 @@ #include #include #include -#include #include "vlan.h" #include "vlanproc.h" diff -puN net/802/psnap.c~brlock-removal-2 net/802/psnap.c --- 25/net/802/psnap.c~brlock-removal-2 Thu Mar 13 15:14:34 2003 +++ 25-akpm/net/802/psnap.c Thu Mar 13 15:14:34 2003 @@ -21,10 +21,10 @@ #include #include #include -#include LIST_HEAD(snap_list); static struct llc_sap *snap_sap; +static spinlock_t snap_lock = SPIN_LOCK_UNLOCKED; /* * Find a snap client by matching the 5 bytes. @@ -34,17 +34,15 @@ static struct datalink_proto *find_snap_ struct list_head *entry; struct datalink_proto *proto = NULL, *p; - if (list_empty(&snap_list)) - goto out; - - list_for_each(entry, &snap_list) { + rcu_read_lock(); + list_for_each_rcu(entry, &snap_list) { p = list_entry(entry, struct datalink_proto, node); if (!memcmp(p->type, desc, 5)) { proto = p; break; } } -out: + rcu_read_unlock(); return proto; } @@ -124,8 +122,7 @@ struct datalink_proto *register_snap_cli { struct datalink_proto *proto = NULL; - br_write_lock_bh(BR_NETPROTO_LOCK); - + spin_lock_bh(&snap_lock); if (find_snap_client(desc)) goto out; @@ -135,10 +132,10 @@ struct datalink_proto *register_snap_cli proto->rcvfunc = rcvfunc; proto->header_length = 5 + 3; /* snap + 802.2 */ proto->request = snap_request; - list_add(&proto->node, &snap_list); + list_add_rcu(&proto->node, &snap_list); } out: - br_write_unlock_bh(BR_NETPROTO_LOCK); + spin_unlock_bh(&snap_lock); return proto; } @@ -147,12 +144,13 @@ out: */ void unregister_snap_client(struct datalink_proto *proto) { - br_write_lock_bh(BR_NETPROTO_LOCK); + spin_lock_bh(&snap_lock); + list_del_rcu(&proto->node); + spin_unlock_bh(&snap_lock); - list_del(&proto->node); + synchronize_kernel(); /* wait for RCU */ kfree(proto); - br_write_unlock_bh(BR_NETPROTO_LOCK); } MODULE_LICENSE("GPL"); _