[PATCH 1/2] Runtime configuration of HTB's HYSTERESIS option (kernel)

Linux Advanced Routing and Traffic Control

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The HTB qdisc has a compile time option, HTB_HYSTERESIS, 
that trades accuracy of traffic classification for CPU 
time.  These patches change hysteresis to be a runtime 
option under the control of "tc".

The effects of HYSTERESIS on HTB's accuracy are significant 
(see chapter 7, section 7.3.1, pp 69-70 in Jesper Brouer's
thesis: http://www.adsl-optimizer.dk/thesis/ ), whereas 
HTB's CPU usage on modern machines using broadband links 
is minimal.  Currently HYSTERESIS is on by default, and 
requires a kernel re-compile to change.  Altering it to 
be a runtime option will make life easier for the bulk of 
its users.

Further documentation on the patch and its usage can be
found here:
  http://www.stuart.id.au/russell/files/tc/tc-atm

Signed-off-by: Russell Stuart <russell-tcatm@xxxxxxxxxxxx>
Signed-off-by: Jesper Dangaard Brouer <hawk@xxxxxxx>
---

diff -Nurp kernel-source-2.6.11.orig/include/linux/pkt_sched.h kernel-source-2.6.11/include/linux/pkt_sched.h
--- kernel-source-2.6.11.orig/include/linux/pkt_sched.h	2005-03-02 17:38:13.000000000 +1000
+++ kernel-source-2.6.11/include/linux/pkt_sched.h	2006-06-13 11:34:25.000000000 +1000
@@ -231,6 +231,10 @@ struct tc_gred_sopt
 #define TC_HTB_MAXDEPTH		8
 #define TC_HTB_PROTOVER		3 /* the same as HTB and TC's major */
 
+struct tc_htb_hopt
+{
+	__u32	nohyst;
+};
 struct tc_htb_opt
 {
 	struct tc_ratespec 	rate;
@@ -258,6 +262,7 @@ enum
 	TCA_HTB_INIT,
 	TCA_HTB_CTAB,
 	TCA_HTB_RTAB,
+	TCA_HTB_NOHYST,
 	__TCA_HTB_MAX,
 };
 
diff -Nurp kernel-source-2.6.11.orig/net/sched/sch_htb.c kernel-source-2.6.11/net/sched/sch_htb.c
--- kernel-source-2.6.11.orig/net/sched/sch_htb.c	2005-03-02 17:38:12.000000000 +1000
+++ kernel-source-2.6.11/net/sched/sch_htb.c	2006-06-13 11:34:25.000000000 +1000
@@ -73,7 +73,6 @@
 #define HTB_EWMAC 2	/* rate average over HTB_EWMAC*HTB_HSIZE sec */
 #undef HTB_DEBUG	/* compile debugging support (activated by tc tool) */
 #define HTB_RATECM 1    /* whether to use rate computer */
-#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 0x30011	/* major must be matched with number suplied by TC as version */
@@ -190,6 +189,7 @@ struct htb_class
     /* class attached filters */
     struct tcf_proto *filter_list;
     int filter_cnt;
+    int nohyst;		/* Don't use hysteresis htb_class_mode */
 
     int warned;		/* only one warning about non work conserving .. */
 
@@ -622,20 +622,14 @@ static __inline__ enum htb_cmode 
 htb_class_mode(struct htb_class *cl,long *diff)
 {
     long toks;
+    long hysteresis =
+	    (cl->nohyst || cl->cmode == HTB_CANT_SEND) ? 0 : -cl->cbuffer;
 
-    if ((toks = (cl->ctokens + *diff)) < (
-#if HTB_HYSTERESIS
-	    cl->cmode != HTB_CANT_SEND ? -cl->cbuffer :
-#endif
-       	    0)) {
+    if ((toks = (cl->ctokens + *diff)) < hysteresis) {
 	    *diff = -toks;
 	    return HTB_CANT_SEND;
     }
-    if ((toks = (cl->tokens + *diff)) >= (
-#if HTB_HYSTERESIS
-	    cl->cmode == HTB_CAN_SEND ? -cl->buffer :
-#endif
-	    0))
+    if ((toks = (cl->tokens + *diff)) >= hysteresis)
 	    return HTB_CAN_SEND;
 
     *diff = -toks;
@@ -1323,6 +1317,7 @@ static int htb_dump_class(struct Qdisc *
 	unsigned char	 *b = skb->tail;
 	struct rtattr *rta;
 	struct tc_htb_opt opt;
+	struct tc_htb_hopt hopt;
 
 	HTB_DBG(0,1,"htb_dump_class handle=%X clid=%X\n",sch->handle,cl->classid);
 
@@ -1342,6 +1337,8 @@ static int htb_dump_class(struct Qdisc *
 	opt.quantum = cl->un.leaf.quantum; opt.prio = cl->un.leaf.prio;
 	opt.level = cl->level; 
 	RTA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
+	hopt.nohyst = cl->nohyst;
+	RTA_PUT(skb, TCA_HTB_NOHYST, sizeof(hopt), &hopt);
 	rta->rta_len = skb->tail - b;
 	HTB_QUNLOCK(sch);
 	return skb->len;
@@ -1527,11 +1524,12 @@ static int htb_change_class(struct Qdisc
 	struct htb_class *cl = (struct htb_class*)*arg,*parent;
 	struct rtattr *opt = tca[TCA_OPTIONS-1];
 	struct qdisc_rate_table *rtab = NULL, *ctab = NULL;
-	struct rtattr *tb[TCA_HTB_RTAB];
+	struct rtattr *tb[TCA_HTB_MAX];
 	struct tc_htb_opt *hopt;
+	struct tc_htb_hopt *uhopt;
 
 	/* extract all subattrs from opt attr */
-	if (!opt || rtattr_parse_nested(tb, TCA_HTB_RTAB, opt) ||
+	if (!opt || rtattr_parse_nested(tb, TCA_HTB_MAX, opt) ||
 			tb[TCA_HTB_PARMS-1] == NULL ||
 			RTA_PAYLOAD(tb[TCA_HTB_PARMS-1]) < sizeof(*hopt))
 		goto failure;
@@ -1544,6 +1542,10 @@ static int htb_change_class(struct Qdisc
 	ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB-1]);
 	if (!rtab || !ctab) goto failure;
 
+	uhopt = RTA_DATA(tb[TCA_HTB_NOHYST-1]);
+	if (uhopt != NULL && RTA_PAYLOAD(tb[TCA_HTB_NOHYST-1]) < sizeof(*uhopt))
+		goto failure;
+
 	if (!cl) { /* new class */
 		struct Qdisc *new_q;
 		/* check for valid classid */
@@ -1636,6 +1638,7 @@ static int htb_change_class(struct Qdisc
 	cl->cbuffer = hopt->cbuffer;
 	if (cl->rate) qdisc_put_rtab(cl->rate); cl->rate = rtab;
 	if (cl->ceil) qdisc_put_rtab(cl->ceil); cl->ceil = ctab;
+	if (uhopt) cl->nohyst = uhopt->nohyst;
 	sch_tree_unlock(sch);
 
 	*arg = (unsigned long)cl;



Attachment: signature.asc
Description: This is a digitally signed message part

_______________________________________________
LARTC mailing list
LARTC@xxxxxxxxxxxxxxx
http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc

[Index of Archives]     [LARTC Home Page]     [Netfilter]     [Netfilter Development]     [Network Development]     [Bugtraq]     [GCC Help]     [Yosemite News]     [Linux Kernel]     [Fedora Users]
  Powered by Linux