Commit a73be040 authored by Jarek Poplawski's avatar Jarek Poplawski Committed by David S. Miller

pkt_sched: sch_htb: Break all htb_do_events() after 2 jiffies

Currently htb_do_events() breaks events recounting for a level after 2
jiffies, but there is no reason to repeat this for next levels and
increase delays even more (with softirqs disabled). htb_dequeue_tree()
can add to this too, btw. In such a case q->now time is invalid anyway.

Thanks to Patrick McHardy for spotting an error around earlier version
of this patch.
Signed-off-by: default avatarJarek Poplawski <jarkao2@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c0851347
...@@ -661,12 +661,13 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, ...@@ -661,12 +661,13 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl,
* next pending event (0 for no event in pq). * next pending event (0 for no event in pq).
* Note: Applied are events whose have cl->pq_key <= q->now. * Note: Applied are events whose have cl->pq_key <= q->now.
*/ */
static psched_time_t htb_do_events(struct htb_sched *q, int level) static psched_time_t htb_do_events(struct htb_sched *q, int level,
unsigned long start)
{ {
/* don't run for longer than 2 jiffies; 2 is used instead of /* don't run for longer than 2 jiffies; 2 is used instead of
1 to simplify things when jiffy is going to be incremented 1 to simplify things when jiffy is going to be incremented
too soon */ too soon */
unsigned long stop_at = jiffies + 2; unsigned long stop_at = start + 2;
while (time_before(jiffies, stop_at)) { while (time_before(jiffies, stop_at)) {
struct htb_class *cl; struct htb_class *cl;
long diff; long diff;
...@@ -845,6 +846,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) ...@@ -845,6 +846,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
struct htb_sched *q = qdisc_priv(sch); struct htb_sched *q = qdisc_priv(sch);
int level; int level;
psched_time_t next_event; psched_time_t next_event;
unsigned long start_at;
/* try to dequeue direct packets as high prio (!) to minimize cpu work */ /* try to dequeue direct packets as high prio (!) to minimize cpu work */
skb = __skb_dequeue(&q->direct_queue); skb = __skb_dequeue(&q->direct_queue);
...@@ -857,6 +859,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) ...@@ -857,6 +859,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
if (!sch->q.qlen) if (!sch->q.qlen)
goto fin; goto fin;
q->now = psched_get_time(); q->now = psched_get_time();
start_at = jiffies;
next_event = q->now + 5 * PSCHED_TICKS_PER_SEC; next_event = q->now + 5 * PSCHED_TICKS_PER_SEC;
...@@ -866,7 +869,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) ...@@ -866,7 +869,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch)
psched_time_t event; psched_time_t event;
if (q->now >= q->near_ev_cache[level]) { if (q->now >= q->near_ev_cache[level]) {
event = htb_do_events(q, level); event = htb_do_events(q, level, start_at);
if (!event) if (!event)
event = q->now + PSCHED_TICKS_PER_SEC; event = q->now + PSCHED_TICKS_PER_SEC;
q->near_ev_cache[level] = event; q->near_ev_cache[level] = event;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment