netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org
Subject: Re: [NET_SCHED 11/11]: qdisc: avoid dequeue while throttled
Date: Fri, 23 Mar 2007 15:39:42 +0100	[thread overview]
Message-ID: <4603E6AE.6000606@trash.net> (raw)
In-Reply-To: <20070323133528.10264.68156.sendpatchset@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 672 bytes --]

Patrick McHardy wrote:
> [NET_SCHED]: qdisc: avoid dequeue while throttled


It just occured to me that this doesn't work properly with qdiscs
that have multiple classes since they all don't properly maintain
the TCQ_F_THROTTLED flag. They set it on dequeue when no active
class is willing to give out packets, but when enqueueing to a
non-active class (thereby activating it) it is still set even though
we don't know if that class could be dequeued.

So this updated patch unsets the TCQ_F_THROTTLED flag whenever we
activate a class. Additionally it removes the unsetting of
TCQ_F_THROTTLED on successful dequeue since we're now guaranteed
that it was not set before.


[-- Attachment #2: 11.diff --]
[-- Type: text/x-diff, Size: 4394 bytes --]

[NET_SCHED]: qdisc: avoid dequeue while throttled

Avoid dequeueing while the device is throttled.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 073456c84a46736a3aa1ae4cc9d953a9e97b327c
tree 805a29224001180c88a429e65812b97a489c427a
parent e2459acd7dee06fb4d5e980f26c23d31db0e5de1
author Patrick McHardy <kaber@trash.net> Fri, 23 Mar 2007 15:37:51 +0100
committer Patrick McHardy <kaber@trash.net> Fri, 23 Mar 2007 15:37:51 +0100

 net/sched/sch_cbq.c     |    5 +++--
 net/sched/sch_generic.c |    4 ++++
 net/sched/sch_hfsc.c    |    5 +++--
 net/sched/sch_htb.c     |    6 ++++--
 net/sched/sch_netem.c   |    4 ----
 net/sched/sch_tbf.c     |    1 -
 6 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index a294542..151f8e3 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -424,8 +424,10 @@ cbq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		sch->bstats.packets++;
 		sch->bstats.bytes+=len;
 		cbq_mark_toplevel(q, cl);
-		if (!cl->next_alive)
+		if (!cl->next_alive) {
 			cbq_activate_class(cl);
+			sch->flags &= ~TCQ_F_THROTTLED;
+		}
 		return ret;
 	}
 
@@ -1030,7 +1032,6 @@ cbq_dequeue(struct Qdisc *sch)
 		skb = cbq_dequeue_1(sch);
 		if (skb) {
 			sch->q.qlen--;
-			sch->flags &= ~TCQ_F_THROTTLED;
 			return skb;
 		}
 
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 52eb343..39c5312 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -93,6 +93,10 @@ static inline int qdisc_restart(struct net_device *dev)
 	struct Qdisc *q = dev->qdisc;
 	struct sk_buff *skb;
 
+	smp_rmb();
+	if (q->flags & TCQ_F_THROTTLED)
+		return q->q.qlen;
+
 	/* Dequeue packet */
 	if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
 		unsigned nolock = (dev->features & NETIF_F_LLTX);
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 22cec11..c6da436 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -1597,8 +1597,10 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		return err;
 	}
 
-	if (cl->qdisc->q.qlen == 1)
+	if (cl->qdisc->q.qlen == 1) {
 		set_active(cl, len);
+		sch->flags &= ~TCQ_F_THROTTLED;
+	}
 
 	cl->bstats.packets++;
 	cl->bstats.bytes += len;
@@ -1672,7 +1674,6 @@ hfsc_dequeue(struct Qdisc *sch)
 	}
 
  out:
-	sch->flags &= ~TCQ_F_THROTTLED;
 	sch->q.qlen--;
 
 	return skb;
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 71db121..1387b7b 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -615,6 +615,8 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		/* enqueue to helper queue */
 		if (q->direct_queue.qlen < q->direct_qlen) {
 			__skb_queue_tail(&q->direct_queue, skb);
+			if (q->direct_queue.qlen == 1)
+				sch->flags &= ~TCQ_F_THROTTLED;
 			q->direct_pkts++;
 		} else {
 			kfree_skb(skb);
@@ -637,6 +639,8 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		cl->bstats.packets++;
 		cl->bstats.bytes += skb->len;
 		htb_activate(q, cl);
+		if (cl->un.leaf.q->q.qlen == 1)
+			sch->flags &= ~TCQ_F_THROTTLED;
 	}
 
 	sch->q.qlen++;
@@ -958,7 +962,6 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
 	/* try to dequeue direct packets as high prio (!) to minimize cpu work */
 	skb = __skb_dequeue(&q->direct_queue);
 	if (skb != NULL) {
-		sch->flags &= ~TCQ_F_THROTTLED;
 		sch->q.qlen--;
 		return skb;
 	}
@@ -991,7 +994,6 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
 			skb = htb_dequeue_tree(q, prio, level);
 			if (likely(skb != NULL)) {
 				sch->q.qlen--;
-				sch->flags &= ~TCQ_F_THROTTLED;
 				goto fin;
 			}
 		}
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 5d9d8bc..4c7a8d8 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -273,10 +273,6 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
 	struct netem_sched_data *q = qdisc_priv(sch);
 	struct sk_buff *skb;
 
-	smp_mb();
-	if (sch->flags & TCQ_F_THROTTLED)
-		return NULL;
-
 	skb = q->qdisc->dequeue(q->qdisc);
 	if (skb) {
 		const struct netem_skb_cb *cb
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 5386295..ed7e581 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -218,7 +218,6 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
 			q->tokens = toks;
 			q->ptokens = ptoks;
 			sch->q.qlen--;
-			sch->flags &= ~TCQ_F_THROTTLED;
 			return skb;
 		}
 

  reply	other threads:[~2007-03-23 14:40 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-03-23 13:35 [NET_SCHED 00/11]: pkt_sched.h cleanup + misc changes Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 01/11]: sch_netem: fix off-by-one in send time comparison Patrick McHardy
2007-03-23 16:34   ` Stephen Hemminger
2007-03-23 13:35 ` [NET_SCHED 02/11]: kill PSCHED_AUDIT_TDIFF Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 03/11]: kill PSCHED_TADD/PSCHED_TADD2 Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 04/11]: kill PSCHED_TLESS Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 05/11]: kill PSCHED_SET_PASTPERFECT/PSCHED_IS_PASTPERFECT Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 06/11]: kill PSCHED_TDIFF Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 07/11]: turn PSCHED_TDIFF_SAFE into inline function Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 08/11]: turn PSCHED_GET_TIME " Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 09/11]: Unline tcf_destroy Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 10/11]: qdisc: remove unnecessary memory barriers Patrick McHardy
2007-03-23 13:35 ` [NET_SCHED 11/11]: qdisc: avoid dequeue while throttled Patrick McHardy
2007-03-23 14:39   ` Patrick McHardy [this message]
2007-03-23 14:57     ` Patrick McHardy
2007-03-23 18:26       ` David Miller
2007-03-23 18:30 ` [NET_SCHED 00/11]: pkt_sched.h cleanup + misc changes 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=4603E6AE.6000606@trash.net \
    --to=kaber@trash.net \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).