netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] sch_htb: ix the deficit overflows
@ 2009-11-27  8:14 Changli Gao
  2009-11-28  0:04 ` Jarek Poplawski
  0 siblings, 1 reply; 14+ messages in thread
From: Changli Gao @ 2009-11-27  8:14 UTC (permalink / raw)
  To: Jamal Hadi Salim, David S. Miller; +Cc: netdev, xiaosuo

fix the deficit overflows.

HTB uses WDRR(Weighted Deficit Round Robin) algorithm to schedule the spare bandwidth, but it doesn't check if the deficit is big enough for the skb when dequeuing skb from a class. In some case(the quantum is smaller than the packet size), the deficit will be decreased, even when it is smaller than ZERO. At last, the deficit will overflows, and become MAX_INT.

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
----
 sch_htb.c |   25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 2e38d1a..293983e 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -783,6 +783,7 @@ static struct sk_buff *htb_dequeue_tree(struct htb_sched *q, int prio,
 {
 	struct sk_buff *skb = NULL;
 	struct htb_class *cl, *start;
+	unsigned int len;
 	/* look initial class up in the row */
 	start = cl = htb_lookup_leaf(q->row[level] + prio, prio,
 				     q->ptr[level] + prio,
@@ -815,9 +816,23 @@ next:
 			goto next;
 		}
 
-		skb = cl->un.leaf.q->dequeue(cl->un.leaf.q);
-		if (likely(skb != NULL))
-			break;
+		skb = cl->un.leaf.q->ops->peek(cl->un.leaf.q);
+		if (likely(skb != NULL)) {
+			len = qdisc_pkt_len(skb);
+			if (len <= cl->un.leaf.deficit[level]) {
+				skb = qdisc_dequeue_peeked(cl->un.leaf.q);
+				break;
+			}
+			skb = NULL;
+			cl->un.leaf.deficit[level] += cl->quantum;
+			htb_next_rb_node((level ? cl->parent->un.inner.ptr :
+					  q->ptr[0]) + prio);
+			cl = htb_lookup_leaf(q->row[level] + prio, prio,
+					     q->ptr[level] + prio,
+					     q->last_ptr_id[level] + prio);
+			start = cl;
+			goto next;
+		}
 
 		qdisc_warn_nonwc("htb", cl->un.leaf.q);
 		htb_next_rb_node((level ? cl->parent->un.inner.ptr : q->
@@ -829,8 +844,8 @@ next:
 	} while (cl != start);
 
 	if (likely(skb != NULL)) {
-		cl->un.leaf.deficit[level] -= qdisc_pkt_len(skb);
-		if (cl->un.leaf.deficit[level] < 0) {
+		cl->un.leaf.deficit[level] -= len;
+		if (cl->un.leaf.deficit[level] <= 0) {
 			cl->un.leaf.deficit[level] += cl->quantum;
 			htb_next_rb_node((level ? cl->parent->un.inner.ptr : q->
 					  ptr[0]) + prio);


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2009-12-02 11:07 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-11-27  8:14 [PATCH] sch_htb: ix the deficit overflows Changli Gao
2009-11-28  0:04 ` Jarek Poplawski
2009-11-30  4:26   ` Changli Gao
2009-11-30 11:10     ` Jarek Poplawski
2009-12-01  2:32       ` Changli Gao
2009-12-01  8:01         ` Jarek Poplawski
2009-12-01  8:43           ` Jarek Poplawski
2009-12-01  9:18             ` Changli Gao
2009-12-01  9:39               ` Jarek Poplawski
2009-12-01 19:12             ` Jarek Poplawski
2009-12-01 19:18               ` Jarek Poplawski
2009-12-02  9:20       ` David Miller
2009-12-02 10:32         ` Jarek Poplawski
2009-12-02 11:07           ` Martin Devera

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).