Linux Advanced Routing and Traffic Control list
 help / color / mirror / Atom feed
From: Wilfried Weissmann <Wilfried.Weissmann@gmx.at>
To: lartc@vger.kernel.org
Subject: Re: [LARTC] [HTB] htb_dequeue_tree assertion (kernel 2.4.21-ac4)
Date: Wed, 23 Jul 2003 18:35:00 +0000	[thread overview]
Message-ID: <marc-lartc-105898530109436@msgid-missing> (raw)
In-Reply-To: <marc-lartc-105855808906499@msgid-missing>

devik wrote:
> Hi,
> 
> try attached fix please (it duplicates last one too so that
> you might get a reject).

Thanks, but now the rb_tree may become empty and this causes an oops in 
htb_lookup_leaf() (tree-rb_node = NULL). I think the kernel crashes in 
"while ((*sp->pptr)->rb_left)". Catching that case is easy. But we must 
not forget to leave the do{}while() loop in htb_dequeue_tree() when an 
empty tree is detected.

I cannot provide you any patches right now. I will send them tomorrow if 
everything works.

Greetings,
Wilfried

> 
> -------------------------------
>     Martin Devera aka devik
> Linux kernel QoS/HTB maintainer
>   http://luxik.cdi.cz/~devik/
> 
> On Sun, 20 Jul 2003, Wilfried Weissmann wrote:
> 
> 
>>devik wrote:
>>
>>>>>If you read comment above htb_dequeue_tree, it should be called
>>>>>only when it is sure that there are packets inside of the level/prio.
>>>>>It is known by other HTB mechanism (per-level activity lists).
>>>>>
>>>>>Thus the bugtrap is to catch case where class was inserted
>>>>>into activity list because it had packets in its sub-qdisc
>>>>>but when we actually decide to dequeue - it has no packet.
>>>>>It is weird - can qdisc lose packets even when dequeue was
>>>>>not called ??
>>>>
>>>>If you change the depth of the leave queue then it is possible to drop
>>>>packets or if you completely exchange the queue. Which would also
>>>>explain why the assertion only occurs when the configuration is altered.
>>>
>>>
>>>Well, I agree that there is something wrong. Now it is neccessary to
>>>find scenario where it does happen so that it is fixed in right way.
>>>I have not much time these days to test these cases but your informations
>>>would lead to following hypothesis:
>>>
>>>Classe's child qdisc is replaced while old one still has nonzero queue.
>>>New empty qdisc is grafted under class instead. What about attached
>>>patch (it is against my latest version so you can see offset warnings) ?
>>
>>This would not work if there are several intermediates HTB queues from
>>the device to the leave queue. In this case every queue from the queue
>>that was changed to the root has to be notified about the change. (The
>>setup we want to use involves such a configuration.) Maybe it is better
>>to just deactivate a class when a dequeue from its leave failes due to a
>>zero queue length. If you are concerned about performance then an audit
>>process could be implemented. For example to check one leave queue every
>>64 packets +/- initial random offset to create some entropy similar to
>>the maximum mount count in the ext2 filesystem. Maybe there are better
>>ways to do this. I am not so familiar with the code.
>>
>>I will make some tests with the patch tomorrow. If my theory is true
>>then it should still help a lot.
>>
>>bye,
>>wilfried
>>
>>
>>>devik
>>>
>>>
>>>------------------------------------------------------------------------
>>>
>>>--- sch_htb.c	2003/07/05 10:37:11	1.21
>>>+++ sch_htb.c	2003/07/20 07:24:59
>>>@@ -1286,6 +1286,10 @@ static int htb_graft(struct Qdisc *sch,
>>> 					return -ENOBUFS;
>>> 		sch_tree_lock(sch);
>>> 		if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) {
>>>+			/* TODO: test it */
>>>+			if (cl->prio_activity)
>>>+				htb_deactivate ((struct htb_sched*)sch->data,cl);
>>>+
>>> 			/* TODO: is it correct ? Why CBQ doesn't do it ? */
>>> 			sch->q.qlen -= (*old)->q.qlen;
>>> 			qdisc_reset(*old);
>>
>>
>>
>>
>>
>>
>>
>>------------------------------------------------------------------------
>>
>>--- sch_htb.c	2003/07/05 10:37:11	1.21
>>+++ sch_htb.c	2003/07/23 07:37:52
>>@@ -947,15 +947,24 @@ static struct sk_buff *
>> htb_dequeue_tree(struct htb_sched *q,int prio,int level)
>> {
>> 	struct sk_buff *skb = NULL;
>>-	//struct htb_sched *q = (struct htb_sched *)sch->data;
>> 	struct htb_class *cl,*start;
>> 	/* look initial class up in the row */
>> 	start = cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
>> 	
>> 	do {
>>-		BUG_TRAP(cl && cl->un.leaf.q->q.qlen); if (!cl) return NULL;
>>+		BUG_TRAP(cl); 
>>+		if (!cl) return NULL;
>> 		HTB_DBG(4,1,"htb_deq_tr prio=%d lev=%d cl=%X defic=%d\n",
>> 				prio,level,cl->classid,cl->un.leaf.deficit[level]);
>>+
>>+		/* class can be empty - it is unlikely but can be true if leaf
>>+		   qdisc drops packets in enqueue routine or if someone used
>>+		   graft operation on the leaf since last dequeue; 
>>+		   simply deactivate and skip such class */
>>+		if (unlikely(cl->un.leaf.q->q.qlen = 0)) {
>>+			htb_deactivate(q,cl);
>>+			goto new_lookup;
>>+		}
>> 	
>> 		if (likely((skb = cl->un.leaf.q->dequeue(cl->un.leaf.q)) != NULL)) 
>> 			break;
>>@@ -965,6 +974,7 @@ htb_dequeue_tree(struct htb_sched *q,int
>> 		}
>> 		q->nwc_hit++;
>> 		htb_next_rb_node((level?cl->parent->un.inner.ptr:q->ptr[0])+prio);
>>+new_lookup:
>> 		cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
>> 	} while (cl != start);
>> 
>>@@ -1286,6 +1296,10 @@ static int htb_graft(struct Qdisc *sch, 
>> 					return -ENOBUFS;
>> 		sch_tree_lock(sch);
>> 		if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) {
>>+			/* TODO: test it */
>>+			if (cl->prio_activity)
>>+				htb_deactivate ((struct htb_sched*)sch->data,cl);
>>+
>> 			/* TODO: is it correct ? Why CBQ doesn't do it ? */
>> 			sch->q.qlen -= (*old)->q.qlen;	
>> 			qdisc_reset(*old);
> 



_______________________________________________
LARTC mailing list / LARTC@mailman.ds9a.nl
http://mailman.ds9a.nl/mailman/listinfo/lartc HOWTO: http://lartc.org/

      parent reply	other threads:[~2003-07-23 18:35 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-18 19:53 [LARTC] [HTB] htb_dequeue_tree assertion (kernel 2.4.21-ac4) Wilfried Weissmann
2003-07-19  9:25 ` devik
2003-07-19 11:42 ` Wilfried Weissmann
2003-07-20  7:28 ` devik
2003-07-20 20:59 ` Wilfried Weissmann
2003-07-21  8:49 ` Wilfried.Weissmann
2003-07-21  9:10 ` devik
2003-07-23  7:39 ` devik
2003-07-23 18:35 ` Wilfried Weissmann [this message]

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=marc-lartc-105898530109436@msgid-missing \
    --to=wilfried.weissmann@gmx.at \
    --cc=lartc@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