diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-02 18:55:08 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-02 18:55:08 +0300 |
commit | 6d6b89bd2e316b78d668f761d380837b81fa71ef (patch) | |
tree | 7e63c58611fc6181153526abbdafdd846ed1a19d /net/llc/llc_core.c | |
parent | 13dda80e48439b446d0bc9bab34b91484bc8f533 (diff) | |
parent | 2507c05ff55fbf38326b08ed27eaed233bc75042 (diff) | |
download | linux-6d6b89bd2e316b78d668f761d380837b81fa71ef.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1341 commits)
virtio_net: remove forgotten assignment
be2net: fix tx completion polling
sis190: fix cable detect via link status poll
net: fix protocol sk_buff field
bridge: Fix build error when IGMP_SNOOPING is not enabled
bnx2x: Tx barriers and locks
scm: Only support SCM_RIGHTS on unix domain sockets.
vhost-net: restart tx poll on sk_sndbuf full
vhost: fix get_user_pages_fast error handling
vhost: initialize log eventfd context pointer
vhost: logging thinko fix
wireless: convert to use netdev_for_each_mc_addr
ethtool: do not set some flags, if others failed
ipoib: returned back addrlen check for mc addresses
netlink: Adding inode field to /proc/net/netlink
axnet_cs: add new id
bridge: Make IGMP snooping depend upon BRIDGE.
bridge: Add multicast count/interval sysfs entries
bridge: Add hash elasticity/max sysfs entries
bridge: Add multicast_snooping sysfs toggle
...
Trivial conflicts in Documentation/feature-removal-schedule.txt
Diffstat (limited to 'net/llc/llc_core.c')
-rw-r--r-- | net/llc/llc_core.c | 53 |
1 files changed, 19 insertions, 34 deletions
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index ff4c0ab96a69..78167e81dfeb 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c @@ -23,7 +23,7 @@ #include <net/llc.h> LIST_HEAD(llc_sap_list); -DEFINE_RWLOCK(llc_sap_list_lock); +DEFINE_SPINLOCK(llc_sap_list_lock); /** * llc_sap_alloc - allocates and initializes sap. @@ -33,40 +33,19 @@ DEFINE_RWLOCK(llc_sap_list_lock); static struct llc_sap *llc_sap_alloc(void) { struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); + int i; if (sap) { /* sap->laddr.mac - leave as a null, it's filled by bind */ sap->state = LLC_SAP_STATE_ACTIVE; - rwlock_init(&sap->sk_list.lock); + spin_lock_init(&sap->sk_lock); + for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) + INIT_HLIST_NULLS_HEAD(&sap->sk_laddr_hash[i], i); atomic_set(&sap->refcnt, 1); } return sap; } -/** - * llc_add_sap - add sap to station list - * @sap: Address of the sap - * - * Adds a sap to the LLC's station sap list. - */ -static void llc_add_sap(struct llc_sap *sap) -{ - list_add_tail(&sap->node, &llc_sap_list); -} - -/** - * llc_del_sap - del sap from station list - * @sap: Address of the sap - * - * Removes a sap to the LLC's station sap list. - */ -static void llc_del_sap(struct llc_sap *sap) -{ - write_lock_bh(&llc_sap_list_lock); - list_del(&sap->node); - write_unlock_bh(&llc_sap_list_lock); -} - static struct llc_sap *__llc_sap_find(unsigned char sap_value) { struct llc_sap* sap; @@ -90,13 +69,13 @@ out: */ struct llc_sap *llc_sap_find(unsigned char sap_value) { - struct llc_sap* sap; + struct llc_sap *sap; - read_lock_bh(&llc_sap_list_lock); + rcu_read_lock_bh(); sap = __llc_sap_find(sap_value); if (sap) llc_sap_hold(sap); - read_unlock_bh(&llc_sap_list_lock); + rcu_read_unlock_bh(); return sap; } @@ -117,7 +96,7 @@ struct llc_sap *llc_sap_open(unsigned char lsap, { struct llc_sap *sap = NULL; - write_lock_bh(&llc_sap_list_lock); + spin_lock_bh(&llc_sap_list_lock); if (__llc_sap_find(lsap)) /* SAP already exists */ goto out; sap = llc_sap_alloc(); @@ -125,9 +104,9 @@ struct llc_sap *llc_sap_open(unsigned char lsap, goto out; sap->laddr.lsap = lsap; sap->rcv_func = func; - llc_add_sap(sap); + list_add_tail_rcu(&sap->node, &llc_sap_list); out: - write_unlock_bh(&llc_sap_list_lock); + spin_unlock_bh(&llc_sap_list_lock); return sap; } @@ -142,8 +121,14 @@ out: */ void llc_sap_close(struct llc_sap *sap) { - WARN_ON(!hlist_empty(&sap->sk_list.list)); - llc_del_sap(sap); + WARN_ON(sap->sk_count); + + spin_lock_bh(&llc_sap_list_lock); + list_del_rcu(&sap->node); + spin_unlock_bh(&llc_sap_list_lock); + + synchronize_rcu(); + kfree(sap); } |