diff options
author | Octavian Purdila <opurdila@ixiacom.com> | 2009-12-26 06:51:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-26 23:45:32 -0500 |
commit | 52d58aef5ee460fedd7f250f05e79081019f2c79 (patch) | |
tree | 9c8d2bf8374570038820a47325a2305bcb83111d /net/llc/llc_core.c | |
parent | 6d2e3ea284463d5ab34e9cf2a41d0b8627b95d02 (diff) |
llc: replace the socket list with a local address based hash
For the cases where a lot of interfaces are used in conjunction with a
lot of LLC sockets bound to the same SAP, the iteration of the socket
list becomes prohibitively expensive.
Replacing the list with a a local address based hash significantly
improves the bind and listener lookup operations as well as the
datagram delivery.
Connected sockets delivery is also improved, but this patch does not
address the case where we have lots of sockets with the same local
address connected to different remote addresses.
In order to keep the socket sanity checks alive and fast a socket
counter was added to the SAP structure.
Signed-off-by: Octavian Purdila <opurdila@ixiacom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/llc/llc_core.c')
-rw-r--r-- | net/llc/llc_core.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index 5276b9722077..0c9ef8bc7655 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c | |||
@@ -33,12 +33,14 @@ DEFINE_RWLOCK(llc_sap_list_lock); | |||
33 | static struct llc_sap *llc_sap_alloc(void) | 33 | static struct llc_sap *llc_sap_alloc(void) |
34 | { | 34 | { |
35 | struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); | 35 | struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); |
36 | int i; | ||
36 | 37 | ||
37 | if (sap) { | 38 | if (sap) { |
38 | /* sap->laddr.mac - leave as a null, it's filled by bind */ | 39 | /* sap->laddr.mac - leave as a null, it's filled by bind */ |
39 | sap->state = LLC_SAP_STATE_ACTIVE; | 40 | sap->state = LLC_SAP_STATE_ACTIVE; |
40 | spin_lock_init(&sap->sk_lock); | 41 | spin_lock_init(&sap->sk_lock); |
41 | INIT_HLIST_NULLS_HEAD(&sap->sk_list, 0); | 42 | for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) |
43 | INIT_HLIST_NULLS_HEAD(&sap->sk_laddr_hash[i], i); | ||
42 | atomic_set(&sap->refcnt, 1); | 44 | atomic_set(&sap->refcnt, 1); |
43 | } | 45 | } |
44 | return sap; | 46 | return sap; |
@@ -143,7 +145,7 @@ out: | |||
143 | */ | 145 | */ |
144 | void llc_sap_close(struct llc_sap *sap) | 146 | void llc_sap_close(struct llc_sap *sap) |
145 | { | 147 | { |
146 | WARN_ON(!hlist_nulls_empty(&sap->sk_list)); | 148 | WARN_ON(sap->sk_count); |
147 | llc_del_sap(sap); | 149 | llc_del_sap(sap); |
148 | kfree(sap); | 150 | kfree(sap); |
149 | } | 151 | } |