From: Eric Dumazet <eric.dumazet@gmail.com>
To: Stephen Hemminger <shemminger@vyatta.com>
Cc: Patrick McHardy <kaber@trash.net>,
David Miller <davem@davemloft.net>,
netdev@vger.kernel.org
Subject: Re: [PATCH] CHOKe flow scheduler (0.10)
Date: Thu, 20 Jan 2011 23:46:51 +0100 [thread overview]
Message-ID: <1295563611.2613.41.camel@edumazet-laptop> (raw)
In-Reply-To: <1295547589.2825.497.camel@edumazet-laptop>
Le jeudi 20 janvier 2011 à 19:19 +0100, Eric Dumazet a écrit :
> Le jeudi 20 janvier 2011 à 09:38 -0800, Stephen Hemminger a écrit :
>
> ...
>
> Hi Stephen
>
> I am contemplating choke_linearize_header() (yet another hash
> function... oh well...) and say :
>
> Instead of this boolean return, just use skb_get_rxhash(). It performs
> what you want, and return 32bits of information, instead of one bit.
>
> (if result (rxhash) is zero, it means you can drop packet because it is
> not linearized)
>
> So choke_match_flow() can be faster if rxhash differs (no cache miss on
> skb->data on an old skb)
> (Do the full check only if rxhash is equal on skb1 / skb2)
>
> More over, the skb_get_rxhash() call is _really_ needed only if CHOKe
> triggers :
> if (p->qavg <= p->qth_min)
> we dont have to compute rxhash at all.
>
> If you want, I can send a diff on your v0.10, just tell me !
Here is my diff against v 0.10
Seems to work well here
qdisc choke 11: parent 1:11 limit 130000b min 10833b max 32500b ewma 13 Plog 21 Scell_log 30
Sent 459876256 bytes 836183 pkt (dropped 318428, overlimits 28 requeues 0)
rate 51823Kbit 11779pps backlog 5926323b 10781p requeues 0
marked 0 early 28 pdrop 0 other 0 matched 159200
Thanks !
net/sched/sch_choke.c | 114 ++++++++++++----------------------------
1 file changed, 37 insertions(+), 77 deletions(-)
diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c
index e1ac560..0e898ed 100644
--- a/net/sched/sch_choke.c
+++ b/net/sched/sch_choke.c
@@ -141,63 +141,24 @@ static void choke_drop_by_idx(struct Qdisc *sch, unsigned int idx)
--sch->q.qlen;
}
-/* Make sure network and transport headers can be dereferenced */
-static bool choke_linearize_header(struct sk_buff *skb)
-{
- int nhoff, poff;
- struct ipv6hdr *ip6;
- struct iphdr *ip;
- u8 ip_proto;
- u32 ihl;
-
- nhoff = skb_network_offset(skb);
-
- switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
- if (!pskb_may_pull(skb, sizeof(*ip) + nhoff))
- return false;
-
- ip = (struct iphdr *) (skb->data + nhoff);
- if (ip->frag_off & htons(IP_MF | IP_OFFSET))
- return false;
-
- ip_proto = ip->protocol;
- ihl = ip->ihl;
- break;
- case __constant_htons(ETH_P_IPV6):
- if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff))
- return false;
-
- ip6 = (struct ipv6hdr *) (skb->data + nhoff);
- ip_proto = ip6->nexthdr;
- ihl = (40 >> 2);
- break;
- default:
- return true;
- }
-
- poff = proto_ports_offset(ip_proto);
- if (poff >= 0) {
- nhoff += ihl * 4 + poff;
- if (!pskb_may_pull(skb, nhoff + 4))
- return false;
- }
-
- return true;
-}
-
/*
* Compare flow of two packets
* Returns true only if source and destination address and port match.
* false for special cases
*/
-static bool choke_match_flow(const struct sk_buff *skb1,
- const struct sk_buff *skb2)
+static bool choke_match_flow(struct sk_buff *skb1,
+ struct sk_buff *skb2)
{
int off1, off2, poff;
+ const u32 *ports1, *ports2;
+ u8 ip_proto;
if (skb1->protocol != skb2->protocol)
return false;
+ if (skb_get_rxhash(skb1) != skb_get_rxhash(skb2))
+ return false;
+ if (!skb_get_rxhash(skb1))
+ return true;
off1 = skb_network_offset(skb1);
off2 = skb_network_offset(skb2);
@@ -209,27 +170,14 @@ static bool choke_match_flow(const struct sk_buff *skb1,
ip1 = (struct iphdr *) (skb1->data + off1);
ip2 = (struct iphdr *) (skb2->data + off2);
- if (ip1->protocol != ip2->protocol ||
+ ip_proto = ip1->protocol;
+ if (ip_proto != ip2->protocol ||
ip1->saddr != ip2->saddr || ip1->daddr != ip2->daddr)
return false;
-
- if (ip1->frag_off & htons(IP_MF | IP_OFFSET) ||
- ip2->frag_off & htons(IP_MF | IP_OFFSET))
- return ip1->id == ip2->id;
-
- poff = proto_ports_offset(ip1->protocol);
- if (poff < 0)
- return true;
- else {
- const u32 *ports1, *ports2;
-
- ports1 = (__force u32 *) (skb1->data + off1
- + ip1->ihl * 4 + poff);
- ports2 = (__force u32 *) (skb2->data + off2
- + ip2->ihl * 4 + poff);
-
- return *ports1 == *ports2;
- }
+ if ((ip1->frag_off | ip2->frag_off) & htons(IP_MF | IP_OFFSET))
+ ip_proto = 0;
+ off1 += ip1->ihl * 4;
+ off2 += ip2->ihl * 4;
break;
}
@@ -239,15 +187,32 @@ static bool choke_match_flow(const struct sk_buff *skb1,
ip1 = (struct ipv6hdr *) (skb1->data + off1);
ip2 = (struct ipv6hdr *) (skb2->data + off2);
- return (ip1->nexthdr == ip2->nexthdr &&
- ipv6_addr_cmp(&ip1->saddr, &ip2->saddr) == 0 &&
- ipv6_addr_cmp(&ip1->daddr, &ip2->daddr) == 0);
+ ip_proto = ip1->nexthdr;
+ if (ip_proto != ip2->nexthdr ||
+ ipv6_addr_cmp(&ip1->saddr, &ip2->saddr) ||
+ ipv6_addr_cmp(&ip1->daddr, &ip2->daddr))
+ return false;
+ off1 += 40;
+ off2 += 40;
}
default: /* Maybe compare MAC header here? */
return false;
}
- /* not reached */
+ poff = proto_ports_offset(ip_proto);
+ if (poff < 0)
+ return true;
+ off1 += poff;
+ off2 += poff;
+ if (!pskb_may_pull(skb1, off1 + 4))
+ return false;
+
+ if (!pskb_may_pull(skb2, off2 + 4))
+ return false;
+
+ ports1 = (__force u32 *)(skb1->data + off1);
+ ports2 = (__force u32 *)(skb2->data + off2);
+ return *ports1 == *ports2;
}
static inline void choke_set_classid(struct sk_buff *skb, u16 classid)
@@ -319,10 +284,10 @@ static struct sk_buff *choke_peek_random(const struct choke_sched_data *q,
* returns true if matched and sets *pidx
*/
static bool choke_match_random(const struct choke_sched_data *q,
- const struct sk_buff *nskb,
+ struct sk_buff *nskb,
unsigned int *pidx)
{
- const struct sk_buff *oskb;
+ struct sk_buff *oskb;
if (q->head == q->tail)
return false;
@@ -331,7 +296,6 @@ static bool choke_match_random(const struct choke_sched_data *q,
if (q->filter_list)
return choke_get_classid(nskb) == choke_get_classid(oskb);
-
return choke_match_flow(oskb, nskb);
}
@@ -345,10 +309,6 @@ static int choke_enqueue(struct sk_buff *skb, struct Qdisc *sch)
/* If using external classifiers, get result and record it. */
if (!choke_classify(skb, sch, &ret))
goto other_drop; /* Packet was eaten by filter */
- } else {
- /* for internal classifier, make header accessible */
- if (!choke_linearize_header(skb))
- goto other_drop;
}
/* Compute average queue usage (see RED) */
next prev parent reply other threads:[~2011-01-20 22:46 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-01-13 17:27 [PATCH] CHOKe flow scheduler (0.7) Stephen Hemminger
2011-01-13 17:48 ` [PATCH] CHOKe flow scheduler (iproute) Stephen Hemminger
2011-01-13 21:01 ` Eric Dumazet
2011-01-13 18:00 ` [PATCH] CHOKe flow scheduler (0.7) Eric Dumazet
2011-01-13 18:02 ` Eric Dumazet
2011-01-13 20:37 ` Eric Dumazet
2011-01-13 23:34 ` [PATCH] CHOKe flow scheduler (0.8) Stephen Hemminger
2011-01-14 3:29 ` Eric Dumazet
2011-01-14 3:34 ` Eric Dumazet
2011-01-14 3:58 ` Eric Dumazet
2011-01-14 11:32 ` Eric Dumazet
2011-01-14 13:54 ` Patrick McHardy
2011-01-14 13:55 ` Patrick McHardy
2011-01-14 14:24 ` Eric Dumazet
2011-01-14 23:45 ` [PATCH] CHOKe flow scheduler (0.9) Stephen Hemminger
2011-01-15 7:45 ` Eric Dumazet
2011-01-17 17:25 ` Stephen Hemminger
2011-01-17 17:54 ` Eric Dumazet
2011-01-18 19:06 ` Stephen Hemminger
2011-01-18 19:34 ` Eric Dumazet
2011-01-20 17:38 ` [PATCH] CHOKe flow scheduler (0.10) Stephen Hemminger
2011-01-20 18:19 ` Eric Dumazet
2011-01-20 22:46 ` Eric Dumazet [this message]
2011-02-03 1:21 ` [PATCH net-next] CHOKe flow scheduler (0.11) Stephen Hemminger
2011-02-03 1:59 ` Eric Dumazet
2011-02-03 4:53 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1295563611.2613.41.camel@edumazet-laptop \
--to=eric.dumazet@gmail.com \
--cc=davem@davemloft.net \
--cc=kaber@trash.net \
--cc=netdev@vger.kernel.org \
--cc=shemminger@vyatta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox