From 1cf5452bee14da7354e15f6d8e29ee9a44541276 Mon Sep 17 00:00:00 2001
From: Daniel Hokka Zakrisson <dhokka@cs.princeton.edu>
Date: Wed, 12 Nov 2008 17:05:22 +0000
Subject: [PATCH] Add patch for DRL.

---
 kernel-2.6.spec                        |  2 +
 linux-2.6-680-htb-hysteresis-tso.patch | 76 ++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)
 create mode 100644 linux-2.6-680-htb-hysteresis-tso.patch

diff --git a/kernel-2.6.spec b/kernel-2.6.spec
index 3a006484c..6e8c27513 100644
--- a/kernel-2.6.spec
+++ b/kernel-2.6.spec
@@ -184,6 +184,7 @@ Patch660: linux-2.6-660-nmi-watchdog-default.patch
 %if "%{distroname}" == "f9"
 Patch670: linux-2.6-670-gcc43.patch
 %endif
+Patch680: linux-2.6-680-htb-hysteresis-tso.patch
 
 # See also the file named 'sources' here for the related checksums
 # NOTE. iwlwifi should be in-kernel starting from 2.6.24
@@ -393,6 +394,7 @@ KERNEL_PREVIOUS=vanilla
 %if "%{distroname}" == "f9"
 %ApplyPatch 670
 %endif
+%ApplyPatch 680
 
 
 # NetNS conflict-resolving patch for VINI. Will work with patch vini_pl_patch-1 but may
diff --git a/linux-2.6-680-htb-hysteresis-tso.patch b/linux-2.6-680-htb-hysteresis-tso.patch
new file mode 100644
index 000000000..c8c99de0a
--- /dev/null
+++ b/linux-2.6-680-htb-hysteresis-tso.patch
@@ -0,0 +1,76 @@
+diff -Nurp linux-2.6.22-660/net/sched/sch_htb.c linux-2.6.22-670/net/sched/sch_htb.c
+--- linux-2.6.22-660/net/sched/sch_htb.c	2007-07-09 01:32:17.000000000 +0200
++++ linux-2.6.22-670/net/sched/sch_htb.c	2008-11-12 17:35:17.000000000 +0100
+@@ -71,7 +71,7 @@
+ #define HTB_HSIZE 16		/* classid hash size */
+ #define HTB_EWMAC 2		/* rate average over HTB_EWMAC*HTB_HSIZE sec */
+ #define HTB_RATECM 1		/* whether to use rate computer */
+-#define HTB_HYSTERESIS 1	/* whether to use mode hysteresis for speedup */
++#define HTB_HYSTERESIS 0	/* whether to use mode hysteresis for speedup */
+ #define HTB_VER 0x30011		/* major must be matched with number suplied by TC as version */
+ 
+ #if HTB_VER >> 16 != TC_HTB_PROTOVER
+@@ -153,15 +153,12 @@ struct htb_class {
+ 				/* of un.leaf originals should be done. */
+ };
+ 
+-/* TODO: maybe compute rate when size is too large .. or drop ? */
+ static inline long L2T(struct htb_class *cl, struct qdisc_rate_table *rate,
+ 			   int size)
+ {
+ 	int slot = size >> rate->rate.cell_log;
+-	if (slot > 255) {
+-		cl->xstats.giants++;
+-		slot = 255;
+-	}
++	if (slot > 255)
++		return (rate->data[255]*(slot >> 8) + rate->data[slot & 0xFF]);
+ 	return rate->data[slot];
+ }
+ 
+@@ -634,13 +631,13 @@ static int htb_enqueue(struct sk_buff *s
+ 		cl->qstats.drops++;
+ 		return NET_XMIT_DROP;
+ 	} else {
+-		cl->bstats.packets++;
++		cl->bstats.packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1;
+ 		cl->bstats.bytes += skb->len;
+ 		htb_activate(q, cl);
+ 	}
+ 
+ 	sch->q.qlen++;
+-	sch->bstats.packets++;
++	sch->bstats.packets += skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1;
+ 	sch->bstats.bytes += skb->len;
+ 	return NET_XMIT_SUCCESS;
+ }
+@@ -717,8 +714,9 @@ static void htb_rate_timer(unsigned long
+  * In such case we remove class from event queue first.
+  */
+ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
+-			     int level, int bytes)
++			     int level, struct sk_buff *skb)
+ {
++	int bytes = skb->len;
+ 	long toks, diff;
+ 	enum htb_cmode old_mode;
+ 
+@@ -759,7 +757,8 @@ static void htb_charge_class(struct htb_
+ 		/* update byte stats except for leaves which are already updated */
+ 		if (cl->level) {
+ 			cl->bstats.bytes += bytes;
+-			cl->bstats.packets++;
++			cl->bstats.packets +=
++				skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1;
+ 		}
+ 		cl = cl->parent;
+ 	}
+@@ -943,7 +942,7 @@ next:
+ 		   gives us slightly better performance */
+ 		if (!cl->un.leaf.q->q.qlen)
+ 			htb_deactivate(q, cl);
+-		htb_charge_class(q, cl, level, skb->len);
++		htb_charge_class(q, cl, level, skb);
+ 	}
+ 	return skb;
+ }
-- 
2.47.0