diff options
author | Jamal Hadi Salim <hadi@znyx.com> | 2004-07-06 02:14:49 -0700 |
---|---|---|
committer | David S. Miller <davem@nuts.davemloft.net> | 2004-07-06 02:14:49 -0700 |
commit | 421340eb004d11b2fca485b517761dc36d872c0d (patch) | |
tree | df658f4e701b4569937858fe99b426cd581a8a76 /net | |
parent | 5fc1b9f8e46a8e7c9ce601ba768191de68f4d7f6 (diff) | |
download | history-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.c | 20 |
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; |