All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.