* [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer.
@ 2009-08-22 0:03 David Miller
2009-08-22 9:17 ` Thomas Gleixner
2009-08-28 15:54 ` Eric Dumazet
0 siblings, 2 replies; 8+ messages in thread
From: David Miller @ 2009-08-22 0:03 UTC (permalink / raw)
To: netdev; +Cc: tglx
This code expects to run in softirq context, and bare hrtimers
run in hw IRQ context.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
net/sched/sch_cbq.c | 23 +++++++++++++----------
1 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index d5798e1..81652d6 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -163,7 +163,7 @@ struct cbq_sched_data
psched_time_t now_rt; /* Cached real time */
unsigned pmask;
- struct hrtimer delay_timer;
+ struct tasklet_hrtimer delay_timer;
struct qdisc_watchdog watchdog; /* Watchdog timer,
started when CBQ has
backlog, but cannot
@@ -503,6 +503,8 @@ static void cbq_ovl_delay(struct cbq_class *cl)
cl->undertime = q->now + delay;
if (delay > 0) {
+ struct hrtimer *ht;
+
sched += delay + cl->penalty;
cl->penalized = sched;
cl->cpriority = TC_CBQ_MAXPRIO;
@@ -510,12 +512,12 @@ static void cbq_ovl_delay(struct cbq_class *cl)
expires = ktime_set(0, 0);
expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched));
- if (hrtimer_try_to_cancel(&q->delay_timer) &&
- ktime_to_ns(ktime_sub(
- hrtimer_get_expires(&q->delay_timer),
- expires)) > 0)
- hrtimer_set_expires(&q->delay_timer, expires);
- hrtimer_restart(&q->delay_timer);
+ ht = &q->delay_timer.timer;
+ if (hrtimer_try_to_cancel(ht) &&
+ ktime_to_ns(ktime_sub(hrtimer_get_expires(ht),
+ expires)) > 0)
+ hrtimer_set_expires(ht, expires);
+ hrtimer_restart(ht);
cl->delayed = 1;
cl->xstats.overactions++;
return;
@@ -621,7 +623,7 @@ static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
time = ktime_set(0, 0);
time = ktime_add_ns(time, PSCHED_TICKS2NS(now + delay));
- hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
+ tasklet_hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
}
sch->flags &= ~TCQ_F_THROTTLED;
@@ -1214,7 +1216,7 @@ cbq_reset(struct Qdisc* sch)
q->tx_class = NULL;
q->tx_borrowed = NULL;
qdisc_watchdog_cancel(&q->watchdog);
- hrtimer_cancel(&q->delay_timer);
+ tasklet_hrtimer_cancel(&q->delay_timer);
q->toplevel = TC_CBQ_MAXLEVEL;
q->now = psched_get_time();
q->now_rt = q->now;
@@ -1397,7 +1399,8 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
q->link.minidle = -0x7FFFFFFF;
qdisc_watchdog_init(&q->watchdog, sch);
- hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ tasklet_hrtimer_init(&q->delay_timer, cbq_undelay,
+ CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
q->delay_timer.function = cbq_undelay;
q->toplevel = TC_CBQ_MAXLEVEL;
q->now = psched_get_time();
--
1.6.3.4
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer.
2009-08-22 0:03 [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer David Miller
@ 2009-08-22 9:17 ` Thomas Gleixner
2009-08-23 1:08 ` David Miller
2009-08-28 15:54 ` Eric Dumazet
1 sibling, 1 reply; 8+ messages in thread
From: Thomas Gleixner @ 2009-08-22 9:17 UTC (permalink / raw)
To: David Miller; +Cc: netdev
On Fri, 21 Aug 2009, David Miller wrote:
> This code expects to run in softirq context, and bare hrtimers
> run in hw IRQ context.
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> @@ -510,12 +512,12 @@ static void cbq_ovl_delay(struct cbq_class *cl)
>
> expires = ktime_set(0, 0);
> expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched));
> - if (hrtimer_try_to_cancel(&q->delay_timer) &&
> - ktime_to_ns(ktime_sub(
> - hrtimer_get_expires(&q->delay_timer),
> - expires)) > 0)
> - hrtimer_set_expires(&q->delay_timer, expires);
> - hrtimer_restart(&q->delay_timer);
> + ht = &q->delay_timer.timer;
> + if (hrtimer_try_to_cancel(ht) &&
> + ktime_to_ns(ktime_sub(hrtimer_get_expires(ht),
> + expires)) > 0)
> + hrtimer_set_expires(ht, expires);
> + hrtimer_restart(ht);
This code looks still wrong. The new expiry time is only set when the
timer is already active. If the timer is not active then you restart
it with the last stale expiry time which is probably in the past, but
might be somewhere in the future as well. I doubt that this is the
intention.
So what you really want is:
cl->cpriority = TC_CBQ_MAXPRIO;
q->pmask |= (1<<TC_CBQ_MAXPRIO);
- expires = ktime_set(0, 0);
- expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched));
- if (hrtimer_try_to_cancel(&q->delay_timer) &&
- ktime_to_ns(ktime_sub(
- hrtimer_get_expires(&q->delay_timer),
- expires)) > 0)
- hrtimer_set_expires(&q->delay_timer, expires);
- hrtimer_restart(&q->delay_timer);
+ ht = &q->delay_timer.timer;
+ expires = ns_to_ktime(PSCHED_TICKS2NS(sched));
+ if (!hrtimer_active(ht) ||
+ expires.tv64 < hrtimer_get_expires(ht).tv64)
+ hrtimer_start(ht, expires, HRTIMER_MODE_ABS);
cl->delayed = 1;
cl->xstats.overactions++;
return;
This starts the timer when
1) the timer is not active
2) the timer is active and the new expiry time is before the
current one. (hrtimer_start takes care of stopping the active
timer)
Thanks,
tglx
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer.
2009-08-22 9:17 ` Thomas Gleixner
@ 2009-08-23 1:08 ` David Miller
2009-08-23 7:22 ` Thomas Gleixner
0 siblings, 1 reply; 8+ messages in thread
From: David Miller @ 2009-08-23 1:08 UTC (permalink / raw)
To: tglx; +Cc: netdev
From: Thomas Gleixner <tglx@linutronix.de>
Date: Sat, 22 Aug 2009 11:17:53 +0200 (CEST)
> On Fri, 21 Aug 2009, David Miller wrote:
>> This code expects to run in softirq context, and bare hrtimers
>> run in hw IRQ context.
>>
>> Signed-off-by: David S. Miller <davem@davemloft.net>
>
>> @@ -510,12 +512,12 @@ static void cbq_ovl_delay(struct cbq_class *cl)
>>
>> expires = ktime_set(0, 0);
>> expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched));
>> - if (hrtimer_try_to_cancel(&q->delay_timer) &&
>> - ktime_to_ns(ktime_sub(
>> - hrtimer_get_expires(&q->delay_timer),
>> - expires)) > 0)
>> - hrtimer_set_expires(&q->delay_timer, expires);
>> - hrtimer_restart(&q->delay_timer);
>> + ht = &q->delay_timer.timer;
>> + if (hrtimer_try_to_cancel(ht) &&
>> + ktime_to_ns(ktime_sub(hrtimer_get_expires(ht),
>> + expires)) > 0)
>> + hrtimer_set_expires(ht, expires);
>> + hrtimer_restart(ht);
>
> This code looks still wrong.
I'm not convinced either way, the code logic here has been like
this since at least 2.2.x, where it reads:
if (!cl->delayed) {
unsigned long sched = jiffies;
...
if (delay > 0) {
sched += PSCHED_US2JIFFIE(delay) + cl->penalty;
...
if (del_timer(&q->delay_timer) &&
(long)(q->delay_timer.expires - sched) > 0)
q->delay_timer.expires = sched;
add_timer(&q->delay_timer);
And what we have there now is a conversion to hrtimers. The intention
to always schedule the timer is very clear in the above code snippet.
Furthermore, fixing this logic is a seperate change from dealing with
the softirq context issue.
So please review my patch in the context of a straight conversion to
tasklet_hrtimer, and let's deal with the timer offset logic here
seperately (and in -next, not 2.6.31-rcX)
Thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer.
2009-08-23 1:08 ` David Miller
@ 2009-08-23 7:22 ` Thomas Gleixner
2009-08-24 1:54 ` David Miller
0 siblings, 1 reply; 8+ messages in thread
From: Thomas Gleixner @ 2009-08-23 7:22 UTC (permalink / raw)
To: David Miller; +Cc: netdev
B1;2005;0cOn Sat, 22 Aug 2009, David Miller wrote:
> From: Thomas Gleixner <tglx@linutronix.de>
> Date: Sat, 22 Aug 2009 11:17:53 +0200 (CEST)
>
> > On Fri, 21 Aug 2009, David Miller wrote:
> >> This code expects to run in softirq context, and bare hrtimers
> >> run in hw IRQ context.
> >>
> >> Signed-off-by: David S. Miller <davem@davemloft.net>
> >
> >> @@ -510,12 +512,12 @@ static void cbq_ovl_delay(struct cbq_class *cl)
> >>
> >> expires = ktime_set(0, 0);
> >> expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched));
> >> - if (hrtimer_try_to_cancel(&q->delay_timer) &&
> >> - ktime_to_ns(ktime_sub(
> >> - hrtimer_get_expires(&q->delay_timer),
> >> - expires)) > 0)
> >> - hrtimer_set_expires(&q->delay_timer, expires);
> >> - hrtimer_restart(&q->delay_timer);
> >> + ht = &q->delay_timer.timer;
> >> + if (hrtimer_try_to_cancel(ht) &&
> >> + ktime_to_ns(ktime_sub(hrtimer_get_expires(ht),
> >> + expires)) > 0)
> >> + hrtimer_set_expires(ht, expires);
> >> + hrtimer_restart(ht);
> >
> > This code looks still wrong.
>
> I'm not convinced either way, the code logic here has been like
> this since at least 2.2.x, where it reads:
>
> if (!cl->delayed) {
> unsigned long sched = jiffies;
> ...
> if (delay > 0) {
> sched += PSCHED_US2JIFFIE(delay) + cl->penalty;
> ...
> if (del_timer(&q->delay_timer) &&
> (long)(q->delay_timer.expires - sched) > 0)
> q->delay_timer.expires = sched;
> add_timer(&q->delay_timer);
That does not make more sense than the hrtimer version :)
> And what we have there now is a conversion to hrtimers. The intention
> to always schedule the timer is very clear in the above code snippet.
>
> Furthermore, fixing this logic is a seperate change from dealing with
> the softirq context issue.
Sure. Just mentioned it as a reminder.
> So please review my patch in the context of a straight conversion to
> tasklet_hrtimer, and let's deal with the timer offset logic here
> seperately (and in -next, not 2.6.31-rcX)
The straight conversion looks fine. Add my Acked-by.
Thanks,
tglx
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer.
2009-08-23 7:22 ` Thomas Gleixner
@ 2009-08-24 1:54 ` David Miller
0 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2009-08-24 1:54 UTC (permalink / raw)
To: tglx; +Cc: netdev
From: Thomas Gleixner <tglx@linutronix.de>
Date: Sun, 23 Aug 2009 09:22:48 +0200 (CEST)
> B1;2005;0cOn Sat, 22 Aug 2009, David Miller wrote:
>> I'm not convinced either way, the code logic here has been like
>> this since at least 2.2.x, where it reads:
>>
>> if (!cl->delayed) {
>> unsigned long sched = jiffies;
>> ...
>> if (delay > 0) {
>> sched += PSCHED_US2JIFFIE(delay) + cl->penalty;
>> ...
>> if (del_timer(&q->delay_timer) &&
>> (long)(q->delay_timer.expires - sched) > 0)
>> q->delay_timer.expires = sched;
>> add_timer(&q->delay_timer);
>
> That does not make more sense than the hrtimer version :)
Sure it does, at least to me.
It says: When 'delay > 0', either the timer fires immediately
('jiffies') or at some point in the future ('jiffies + delay +
penalty' or existing expiration, whichever is sooner).
The intention of the code seems very clear.
>> So please review my patch in the context of a straight conversion to
>> tasklet_hrtimer, and let's deal with the timer offset logic here
>> seperately (and in -next, not 2.6.31-rcX)
>
> The straight conversion looks fine. Add my Acked-by.
Thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer.
2009-08-22 0:03 [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer David Miller
2009-08-22 9:17 ` Thomas Gleixner
@ 2009-08-28 15:54 ` Eric Dumazet
2009-08-28 19:30 ` David Miller
1 sibling, 1 reply; 8+ messages in thread
From: Eric Dumazet @ 2009-08-28 15:54 UTC (permalink / raw)
To: David Miller; +Cc: netdev, tglx
David Miller a écrit :
> This code expects to run in softirq context, and bare hrtimers
> run in hw IRQ context.
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
...
> sch->flags &= ~TCQ_F_THROTTLED;
> @@ -1214,7 +1216,7 @@ cbq_reset(struct Qdisc* sch)
> q->tx_class = NULL;
> q->tx_borrowed = NULL;
> qdisc_watchdog_cancel(&q->watchdog);
> - hrtimer_cancel(&q->delay_timer);
> + tasklet_hrtimer_cancel(&q->delay_timer);
> q->toplevel = TC_CBQ_MAXLEVEL;
> q->now = psched_get_time();
> q->now_rt = q->now;
David
I now have these dmesg warnings when playing with cbq
# tc qdisc del dev eth3 root
# tc qdisc add dev eth3 root handle 1: est 1sec 8sec cbq avpkt 1000 rate 1000Mbit bandwidth 1000Mbit
# tc qdisc del dev eth3 root
[12786.458485] Attempt to kill tasklet from interrupt
[12786.458522] Attempt to kill tasklet from interrupt
[12786.465261] Attempt to kill tasklet from interrupt
[12786.465286] Attempt to kill tasklet from interrupt
probably becauce cbq_reset() being called from interrupt context ?
Thanks
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer.
2009-08-28 15:54 ` Eric Dumazet
@ 2009-08-28 19:30 ` David Miller
2009-08-28 19:51 ` Thomas Gleixner
0 siblings, 1 reply; 8+ messages in thread
From: David Miller @ 2009-08-28 19:30 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, tglx
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Fri, 28 Aug 2009 17:54:53 +0200
> I now have these dmesg warnings when playing with cbq
>
> # tc qdisc del dev eth3 root
> # tc qdisc add dev eth3 root handle 1: est 1sec 8sec cbq avpkt 1000 rate 1000Mbit bandwidth 1000Mbit
> # tc qdisc del dev eth3 root
>
> [12786.458485] Attempt to kill tasklet from interrupt
> [12786.458522] Attempt to kill tasklet from interrupt
> [12786.465261] Attempt to kill tasklet from interrupt
> [12786.465286] Attempt to kill tasklet from interrupt
>
> probably becauce cbq_reset() being called from interrupt context ?
Grumble... I guess the tasklet_hrtimer infrastructure is less
of a direct plugin replacement for plain hrtimers than I thought.
Anyone have any ideas about how to deal with stuff like this?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer.
2009-08-28 19:30 ` David Miller
@ 2009-08-28 19:51 ` Thomas Gleixner
0 siblings, 0 replies; 8+ messages in thread
From: Thomas Gleixner @ 2009-08-28 19:51 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, netdev
On Fri, 28 Aug 2009, David Miller wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Fri, 28 Aug 2009 17:54:53 +0200
>
> > I now have these dmesg warnings when playing with cbq
> >
> > # tc qdisc del dev eth3 root
> > # tc qdisc add dev eth3 root handle 1: est 1sec 8sec cbq avpkt 1000 rate 1000Mbit bandwidth 1000Mbit
> > # tc qdisc del dev eth3 root
> >
> > [12786.458485] Attempt to kill tasklet from interrupt
> > [12786.458522] Attempt to kill tasklet from interrupt
> > [12786.465261] Attempt to kill tasklet from interrupt
> > [12786.465286] Attempt to kill tasklet from interrupt
> >
> > probably becauce cbq_reset() being called from interrupt context ?
>
> Grumble... I guess the tasklet_hrtimer infrastructure is less
> of a direct plugin replacement for plain hrtimers than I thought.
>
> Anyone have any ideas about how to deal with stuff like this?
Hmm. Is it sufficient to cancel just the timer and let an eventually
scheduled tasklet deal with the cleanup ?
Thanks,
tglx
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-08-28 19:51 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-22 0:03 [PATCH 2/2]: pkt_sched: Convert CBQ to tasklet_hrtimer David Miller
2009-08-22 9:17 ` Thomas Gleixner
2009-08-23 1:08 ` David Miller
2009-08-23 7:22 ` Thomas Gleixner
2009-08-24 1:54 ` David Miller
2009-08-28 15:54 ` Eric Dumazet
2009-08-28 19:30 ` David Miller
2009-08-28 19:51 ` Thomas Gleixner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).