aboutsummaryrefslogtreecommitdiffstats
path: root/net/llc/llc_sap.c
diff options
context:
space:
mode:
authorOctavian Purdila <opurdila@ixiacom.com>2009-12-26 06:51:05 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-26 23:45:32 -0500
commit52d58aef5ee460fedd7f250f05e79081019f2c79 (patch)
tree9c8d2bf8374570038820a47325a2305bcb83111d /net/llc/llc_sap.c
parent6d2e3ea284463d5ab34e9cf2a41d0b8627b95d02 (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_sap.c')
-rw-r--r--net/llc/llc_sap.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 94cb706f6cc4..ad6e6e1cf22f 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -321,10 +321,12 @@ static struct sock *llc_lookup_dgram(struct llc_sap *sap,
321{ 321{
322 struct sock *rc; 322 struct sock *rc;
323 struct hlist_nulls_node *node; 323 struct hlist_nulls_node *node;
324 int slot = llc_sk_laddr_hashfn(sap, laddr);
325 struct hlist_nulls_head *laddr_hb = &sap->sk_laddr_hash[slot];
324 326
325 rcu_read_lock_bh(); 327 rcu_read_lock_bh();
326again: 328again:
327 sk_nulls_for_each_rcu(rc, node, &sap->sk_list) { 329 sk_nulls_for_each_rcu(rc, node, laddr_hb) {
328 if (llc_dgram_match(sap, laddr, rc)) { 330 if (llc_dgram_match(sap, laddr, rc)) {
329 /* Extra checks required by SLAB_DESTROY_BY_RCU */ 331 /* Extra checks required by SLAB_DESTROY_BY_RCU */
330 if (unlikely(!atomic_inc_not_zero(&rc->sk_refcnt))) 332 if (unlikely(!atomic_inc_not_zero(&rc->sk_refcnt)))
@@ -338,6 +340,13 @@ again:
338 } 340 }
339 } 341 }
340 rc = NULL; 342 rc = NULL;
343 /*
344 * if the nulls value we got at the end of this lookup is
345 * not the expected one, we must restart lookup.
346 * We probably met an item that was moved to another chain.
347 */
348 if (unlikely(get_nulls_value(node) != slot))
349 goto again;
341found: 350found:
342 rcu_read_unlock_bh(); 351 rcu_read_unlock_bh();
343 return rc; 352 return rc;