Hello Dave, I just spotted the second bug too. (For those interested it is described in the patch). Please revert the small patch I sent you yesterday before applying the new one. It contains yesterday's one too (it is because it is for 2.4 too). Please apply it against both 2.4.23 and 2.6.0-test10. It should apply cleanly in 2.4.23 case and with some offsets to 2.6.0-test10. Patch comments: - Fixed oops in debugging of enqueue/requeue. - Fixed oops in htb_destroy. Note that I tested 2.6 only because I'm still downloading 2.4.22 patch on my slow line. I just wanted to sent the patch ASAP. I'll inform you about result later but I expect no problems. ------------------------------- Martin Devera aka devik Linux kernel QoS/HTB maintainer http://luxik.cdi.cz/~devik/ On Sat, 6 Dec 2003, David S. Miller wrote: > On Sat, 6 Dec 2003 15:18:37 +0100 (CET) > devik <devik@cdi.cz> wrote: > > > I discovered reason of the first Daniel's OOPS. It is change > > which was not forward-ported to 2.6. > > It is attached. > > Thanks a lot for tracking this problem down Devik. > > Patch applied, thanks again. > >
--- sch_htb.2423.c Sun Dec 7 11:50:42 2003 +++ sch_htb.c Sun Dec 7 12:12:39 2003 @@ -23,7 +23,7 @@ * spotted bug in dequeue code and helped with fix * and many others. thanks. * - * $Id: sch_htb.c,v 1.24 2003/07/28 15:25:23 devik Exp devik $ + * $Id: sch_htb.c,v 1.25 2003/12/07 11:08:25 devik Exp devik $ */ #include <linux/config.h> #include <linux/module.h> @@ -75,7 +75,7 @@ #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */ #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock) #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock) -#define HTB_VER 0x3000d /* major must be matched with number suplied by TC as version */ +#define HTB_VER 0x3000e /* major must be matched with number suplied by TC as version */ #if HTB_VER >> 16 != TC_HTB_PROTOVER #error "Mismatched sch_htb.c and pkt_sch.h" @@ -717,7 +717,7 @@ sch->q.qlen++; sch->stats.packets++; sch->stats.bytes += skb->len; - HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); + HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb); return NET_XMIT_SUCCESS; } @@ -745,7 +745,7 @@ htb_activate (q,cl); sch->q.qlen++; - HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); + HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb); return NET_XMIT_SUCCESS; } @@ -1396,11 +1396,16 @@ #ifdef HTB_RATECM del_timer_sync (&q->rttim); #endif + /* This line used to be after htb_destroy_class call below + and surprisingly it worked in 2.4. But it must precede it + because filter need its target class alive to be able to call + unbind_filter on it (without Oops). */ + htb_destroy_filters(&q->filter_list); + while (!list_empty(&q->root)) htb_destroy_class (sch,list_entry(q->root.next, struct htb_class,sibling)); - htb_destroy_filters(&q->filter_list); __skb_queue_purge(&q->direct_queue); MOD_DEC_USE_COUNT; } @@ -1493,7 +1498,7 @@ cl->magic = HTB_CMAGIC; #endif - /* create leaf qdisc early because it uses kmalloc(GPF_KERNEL) + /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL) so that can't be used inside of sch_tree_lock -- thanks to Karlis Peisenieks */ new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops);