aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJamal Hadi Salim <hadi@znyx.com>2004-07-06 02:14:49 -0700
committerDavid S. Miller <davem@nuts.davemloft.net>2004-07-06 02:14:49 -0700
commit421340eb004d11b2fca485b517761dc36d872c0d (patch)
treedf658f4e701b4569937858fe99b426cd581a8a76 /net
parent5fc1b9f8e46a8e7c9ce601ba768191de68f4d7f6 (diff)
downloadhistory-421340eb004d11b2fca485b517761dc36d872c0d.tar.gz
[PKT_SCHED]: New version of u32 classifier hashing workaround.
This version does not change user visible structures. Signed-off-by: Jamal Hadi Salim <hadi@znyx.com> Signed-off-by: David S. Miller <davem@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/sched/cls_u32.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index c648627e6013de..2f763f228d4c2a 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -72,6 +72,7 @@ struct tc_u_knode
struct tcf_police *police;
#endif
#endif
+ u8 fshift;
struct tcf_result res;
struct tc_u_hnode *ht_down;
struct tc_u32_sel sel;
@@ -99,10 +100,10 @@ struct tc_u_common
static struct tc_u_common *u32_list;
-static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel)
+static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift)
{
-#ifdef fix_u32_bug
- unsigned h = (key & sel->hmask)>>sel->fshift;
+#ifndef fix_u32_bug
+ unsigned h = (key & sel->hmask)>>fshift;
#else
unsigned h = (key & sel->hmask);
@@ -206,7 +207,7 @@ check_terminal:
ht = n->ht_down;
sel = 0;
if (ht->divisor)
- sel = ht->divisor&u32_hash_fold(*(u32*)(ptr+n->sel.hoff), &n->sel);
+ sel = ht->divisor&u32_hash_fold(*(u32*)(ptr+n->sel.hoff), &n->sel,n->fshift);
if (!(n->sel.flags&(TC_U32_VAROFFSET|TC_U32_OFFSET|TC_U32_EAT)))
goto next_ht;
@@ -701,6 +702,17 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key));
n->ht_up = ht;
n->handle = handle;
+{
+ u8 i = 0;
+ u32 mask = s->hmask;
+ if (mask) {
+ while (!(mask & 1)) {
+ i++;
+ mask>>=1;
+ }
+ }
+ n->fshift = i;
+}
err = u32_set_parms(tp->q, base, ht, n, tb, tca[TCA_RATE-1]);
if (err == 0) {
struct tc_u_knode **ins;