Russell Stuart
2006-Jun-15 09:01 UTC
[PATCH 2/2] Runtime configuration of HTB''s HYSTERESIS option (userspace)
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@stuart.id.au>
Signed-off-by: Jesper Dangaard Brouer <hawk@comx.dk>
---
diff -Nurp iproute2.orig/include/linux/pkt_sched.h
iproute2/include/linux/pkt_sched.h
--- iproute2.orig/include/linux/pkt_sched.h 2006-06-13 11:53:27.000000000 +1000
+++ iproute2/include/linux/pkt_sched.h 2006-06-13 11:54:50.000000000 +1000
@@ -232,6 +232,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;
@@ -259,6 +263,7 @@ enum
TCA_HTB_INIT,
TCA_HTB_CTAB,
TCA_HTB_RTAB,
+ TCA_HTB_NOHYST,
__TCA_HTB_MAX,
};
diff -Nurp iproute2.orig/tc/q_htb.c iproute2/tc/q_htb.c
--- iproute2.orig/tc/q_htb.c 2006-06-13 11:53:27.000000000 +1000
+++ iproute2/tc/q_htb.c 2006-06-13 11:54:50.000000000 +1000
@@ -35,7 +35,7 @@ static void explain(void)
" r2q DRR quantums are computed as rate in Bps/r2q {10}\n"
" debug string of 16 numbers each 0-3 {0}\n\n"
"... class add ... htb rate R1 [burst B1] [mpu B] [overhead O]
[atm]\n"
- " [prio P] [slot S] [pslot PS]\n"
+ " [prio P] [slot S] [pslot PS] [nohyst]\n"
" [ceil R2] [cburst B2] [mtu MTU] [quantum
Q]\n"
" rate rate allocated to this class (class can still borrow)\n"
" burst max bytes burst which can be accumulated during idle period
{computed}\n"
@@ -46,6 +46,7 @@ static void explain(void)
" cburst burst but for ceil {computed}\n"
" mtu max packet size we create rate map for {1600}\n"
" prio priority of leaf; lower are served first {0}\n"
+ " nohyst disable hysteresis (heavier on CPU but more accurate)\n"
" quantum how much bytes to serve from leaf at once {use r2q}\n"
"\nTC HTB version
%d.%d\n",HTB_TC_VER>>16,HTB_TC_VER&0xffff
);
@@ -104,6 +105,7 @@ static int htb_parse_class_opt(struct qd
{
int ok=0;
struct tc_htb_opt opt;
+ struct tc_htb_hopt hopt;
__u32 rtab[256],ctab[256];
unsigned buffer=0,cbuffer=0;
int cell_log=-1,ccell_log = -1;
@@ -114,6 +116,7 @@ static int htb_parse_class_opt(struct qd
struct rtattr *tail;
memset(&opt, 0, sizeof(opt)); mtu = 1600; /* eth packet len */
+ memset(&hopt, 0, sizeof(hopt));
while (argc > 0) {
if (matches(*argv, "prio") == 0) {
@@ -132,6 +135,8 @@ static int htb_parse_class_opt(struct qd
if (get_u8(&mpu8, *argv, 10)) {
explain1("mpu"); return -1;
}
+ } else if (matches(*argv, "nohyst") == 0) {
+ hopt.nohyst = 1;
} else if (matches(*argv, "overhead") == 0) {
NEXT_ARG();
if (get_s8(&overhead, *argv, 10)) {
@@ -221,14 +226,16 @@ static int htb_parse_class_opt(struct qd
addattr_l(n, 2024, TCA_HTB_PARMS, &opt, sizeof(opt));
addattr_l(n, 3024, TCA_HTB_RTAB, rtab, 1024);
addattr_l(n, 4024, TCA_HTB_CTAB, ctab, 1024);
+ addattr_l(n, 5024, TCA_HTB_NOHYST, &hopt, sizeof(hopt));
tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
return 0;
}
static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
{
- struct rtattr *tb[TCA_HTB_RTAB+1];
+ struct rtattr *tb[TCA_HTB_MAX+1];
struct tc_htb_opt *hopt;
+ struct tc_htb_hopt *uhopt;
struct tc_htb_glob *gopt;
double buffer,cbuffer;
SPRINT_BUF(b1);
@@ -238,7 +245,7 @@ static int htb_print_opt(struct qdisc_ut
if (opt == NULL)
return 0;
- parse_rtattr_nested(tb, TCA_HTB_RTAB, opt);
+ parse_rtattr_nested(tb, TCA_HTB_MAX, opt);
if (tb[TCA_HTB_PARMS]) {
@@ -278,6 +285,13 @@ static int htb_print_opt(struct qdisc_ut
fprintf(f, "buffer [%08x] cbuffer [%08x] ",
hopt->buffer,hopt->cbuffer);
}
+ if (tb[TCA_HTB_NOHYST]) {
+ uhopt = RTA_DATA(tb[TCA_HTB_NOHYST]);
+ if (RTA_PAYLOAD(tb[TCA_HTB_NOHYST]) < sizeof(*uhopt)) return -1;
+
+ if (uhopt->nohyst)
+ fprintf(f, "nohyst ");
+ }
if (tb[TCA_HTB_INIT]) {
gopt = RTA_DATA(tb[TCA_HTB_INIT]);
if (RTA_PAYLOAD(tb[TCA_HTB_INIT]) < sizeof(*gopt)) return -1;
