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: Jarek Poplawski <jarkao2@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
c085134719
commit
a73be04065
@@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user