summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
authorOctavian Purdila <opurdila@ixiacom.com>2009-12-26 14:51:05 +0300
committerDavid S. Miller <davem@davemloft.net>2009-12-27 07:45:32 +0300
commit52d58aef5ee460fedd7f250f05e79081019f2c79 (patch)
tree9c8d2bf8374570038820a47325a2305bcb83111d /include/net
parent6d2e3ea284463d5ab34e9cf2a41d0b8627b95d02 (diff)
downloadlinux-52d58aef5ee460fedd7f250f05e79081019f2c79.tar.xz
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 'include/net')
-rw-r--r--include/net/llc.h21
1 files changed, 20 insertions, 1 deletions
diff --git a/include/net/llc.h b/include/net/llc.h
index dbef5917905b..709a9b37e239 100644
--- a/include/net/llc.h
+++ b/include/net/llc.h
@@ -17,6 +17,8 @@
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/rculist_nulls.h>
+#include <linux/hash.h>
+#include <linux/jhash.h>
#include <asm/atomic.h>
@@ -35,6 +37,9 @@ struct llc_addr {
#define LLC_SK_DEV_HASH_BITS 6
#define LLC_SK_DEV_HASH_ENTRIES (1<<LLC_SK_DEV_HASH_BITS)
+#define LLC_SK_LADDR_HASH_BITS 6
+#define LLC_SK_LADDR_HASH_ENTRIES (1<<LLC_SK_LADDR_HASH_BITS)
+
/**
* struct llc_sap - Defines the SAP component
*
@@ -58,7 +63,8 @@ struct llc_sap {
struct llc_addr laddr;
struct list_head node;
spinlock_t sk_lock;
- struct hlist_nulls_head sk_list;
+ int sk_count;
+ struct hlist_nulls_head sk_laddr_hash[LLC_SK_LADDR_HASH_ENTRIES];
struct hlist_head sk_dev_hash[LLC_SK_DEV_HASH_ENTRIES];
};
@@ -68,6 +74,19 @@ struct hlist_head *llc_sk_dev_hash(struct llc_sap *sap, int ifindex)
return &sap->sk_dev_hash[ifindex % LLC_SK_DEV_HASH_ENTRIES];
}
+static inline
+u32 llc_sk_laddr_hashfn(struct llc_sap *sap, const struct llc_addr *laddr)
+{
+ return hash_32(jhash(laddr->mac, sizeof(laddr->mac), 0),
+ LLC_SK_LADDR_HASH_BITS);
+}
+
+static inline
+struct hlist_nulls_head *llc_sk_laddr_hash(struct llc_sap *sap,
+ const struct llc_addr *laddr)
+{
+ return &sap->sk_laddr_hash[llc_sk_laddr_hashfn(sap, laddr)];
+}
#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
#define LLC_DEST_SAP 1 /* Type 1 goes here */