diff options
author | Eric Dumazet <edumazet@google.com> | 2014-03-17 20:20:49 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-18 14:17:55 -0400 |
commit | d37d8ac17d38d389375060416ceedd5b19d5255c (patch) | |
tree | ebc4defe9fa6cef650f2c231a3cba5405928cede /net/sched/cls_fw.c | |
parent | 995dca4ce9dddf48597bd3e0427447acd4509f1d (diff) | |
download | linux-d37d8ac17d38d389375060416ceedd5b19d5255c.tar.gz linux-d37d8ac17d38d389375060416ceedd5b19d5255c.tar.bz2 linux-d37d8ac17d38d389375060416ceedd5b19d5255c.zip |
net: sched: use no more than one page in struct fw_head
In commit b4e9b520ca5d ("[NET_SCHED]: Add mask support to fwmark
classifier") Patrick added an u32 field in fw_head, making it slightly
bigger than one page.
Lets use 256 slots to make fw_hash() more straight forward, and move
@mask to the beginning of the structure as we often use a small number
of skb->mark. @mask and first hash buckets share the same cache line.
This brings back the memory usage to less than 4000 bytes, and permits
John to add a rcu_head at the end of the structure later without any
worry.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Thomas Graf <tgraf@suug.ch>
Cc: John Fastabend <john.fastabend@gmail.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/cls_fw.c')
-rw-r--r-- | net/sched/cls_fw.c | 33 |
1 files changed, 7 insertions, 26 deletions
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index a366537f82c6..63a3ce75c02e 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -29,11 +29,11 @@ #include <net/act_api.h> #include <net/pkt_cls.h> -#define HTSIZE (PAGE_SIZE/sizeof(struct fw_filter *)) +#define HTSIZE 256 struct fw_head { - struct fw_filter *ht[HTSIZE]; - u32 mask; + u32 mask; + struct fw_filter *ht[HTSIZE]; }; struct fw_filter { @@ -46,30 +46,11 @@ struct fw_filter { struct tcf_exts exts; }; -static inline int fw_hash(u32 handle) +static u32 fw_hash(u32 handle) { - if (HTSIZE == 4096) - return ((handle >> 24) & 0xFFF) ^ - ((handle >> 12) & 0xFFF) ^ - (handle & 0xFFF); - else if (HTSIZE == 2048) - return ((handle >> 22) & 0x7FF) ^ - ((handle >> 11) & 0x7FF) ^ - (handle & 0x7FF); - else if (HTSIZE == 1024) - return ((handle >> 20) & 0x3FF) ^ - ((handle >> 10) & 0x3FF) ^ - (handle & 0x3FF); - else if (HTSIZE == 512) - return (handle >> 27) ^ - ((handle >> 18) & 0x1FF) ^ - ((handle >> 9) & 0x1FF) ^ - (handle & 0x1FF); - else if (HTSIZE == 256) { - u8 *t = (u8 *) &handle; - return t[0] ^ t[1] ^ t[2] ^ t[3]; - } else - return handle & (HTSIZE - 1); + handle ^= (handle >> 16); + handle ^= (handle >> 8); + return handle % HTSIZE; } static int fw_classify(struct sk_buff *skb, const struct tcf_proto *tp, |