| Date | Wed, 01 Jun 2011 17:10:34 +0900 | From | Greg KH <> | Subject | [064/165] sch_sfq: avoid giving spurious NET_XMIT_CN signals |
| |
2.6.39-stable review patch. If anyone has any objections, please let us know.
------------------ Content-Length: 1719 Lines: 55
From: Eric Dumazet <eric.dumazet@gmail.com>
[ Upstream commit 8efa885406359af300d46910642b50ca82c0fe47 ]
While chasing a possible net_sched bug, I found that IP fragments have litle chance to pass a congestioned SFQ qdisc :
- Say SFQ qdisc is full because one flow is non responsive. - ip_fragment() wants to send two fragments belonging to an idle flow. - sfq_enqueue() queues first packet, but see queue limit reached : - sfq_enqueue() drops one packet from 'big consumer', and returns NET_XMIT_CN. - ip_fragment() cancel remaining fragments.
This patch restores fairness, making sure we return NET_XMIT_CN only if we dropped a packet from the same flow.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> CC: Patrick McHardy <kaber@trash.net> CC: Jarek Poplawski <jarkao2@gmail.com> CC: Jamal Hadi Salim <hadi@cyberus.ca> CC: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> --- net/sched/sch_sfq.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -361,7 +361,7 @@ sfq_enqueue(struct sk_buff *skb, struct { struct sfq_sched_data *q = qdisc_priv(sch); unsigned int hash; - sfq_index x; + sfq_index x, qlen; struct sfq_slot *slot; int uninitialized_var(ret); @@ -405,8 +405,12 @@ sfq_enqueue(struct sk_buff *skb, struct if (++sch->q.qlen <= q->limit) return NET_XMIT_SUCCESS; + qlen = slot->qlen; sfq_drop(sch); - return NET_XMIT_CN; + /* Return Congestion Notification only if we dropped a packet + * from this flow. + */ + return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; } static struct sk_buff *
|