summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Devera <devik@cdi.cz>2008-04-06 23:42:10 -0700
committerChris Wright <chrisw@sous-sol.org>2008-04-18 18:53:26 -0700
commited03865a4621b60f8c1b4c3932db85303c3ec349 (patch)
tree4a24c944ae0e47dd1b77e67bc72b1b629f11171f
parentd55db74d5dbb56eb8f4fc874a97af7294a3b3008 (diff)
sch_htb: fix "too many events" situation
Upstream commit: 8f3ea33a5078a09eba12bfe57424507809367756 HTB is event driven algorithm and part of its work is to apply scheduled events at proper times. It tried to defend itself from livelock by processing only limited number of events per dequeue. Because of faster computers some users already hit this hardcoded limit. This patch limits processing up to 2 jiffies (why not 1 jiffie ? because it might stop prematurely when only fraction of jiffie remains). Signed-off-by: Martin Devera <devik@cdi.cz> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Chris Wright <chrisw@sous-sol.org>
-rw-r--r--net/sched/sch_htb.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 5e608a64935a..88860dd3c1bf 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -708,9 +708,11 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
*/
static psched_time_t htb_do_events(struct htb_sched *q, int level)
{
- int i;
-
- for (i = 0; i < 500; i++) {
+ /* don't run for longer than 2 jiffies; 2 is used instead of
+ 1 to simplify things when jiffy is going to be incremented
+ too soon */
+ unsigned long stop_at = jiffies + 2;
+ while (time_before(jiffies, stop_at)) {
struct htb_class *cl;
long diff;
struct rb_node *p = rb_first(&q->wait_pq[level]);
@@ -728,9 +730,8 @@ static psched_time_t htb_do_events(struct htb_sched *q, int level)
if (cl->cmode != HTB_CAN_SEND)
htb_add_to_wait_tree(q, cl, diff);
}
- if (net_ratelimit())
- printk(KERN_WARNING "htb: too many events !\n");
- return q->now + PSCHED_TICKS_PER_SEC / 10;
+ /* too much load - let's continue on next jiffie */
+ return q->now + PSCHED_TICKS_PER_SEC / HZ;
}
/* Returns class->node+prio from id-tree where classe's id is >= id. NULL