From: Thomas Gleixner <tglx@linutronix.de>
To: netdev@vger.kernel.org
Cc: LKML <linux-kernel@vger.kernel.org>,
David Miller <davem@davemloft.net>,
Patrick McHardy <kaber@trash.net>,
Peter Zijlstra <peterz@infradead.org>
Subject: [patch 2/3] net: sanitize hrtimer usage in sched_cbq
Date: Thu, 09 Jul 2009 21:59:30 -0000 [thread overview]
Message-ID: <20090709215606.626294588@linutronix.de> (raw)
In-Reply-To: <20090709215455.703939259@linutronix.de>
[-- Attachment #1: net-sched-cbq-sanitize-hrtimer-usage.patch --]
[-- Type: text/plain, Size: 3134 bytes --]
The usage of hrtimer in cbq_ovl_delay() is less than obvious and in
two aspects wrong.
The intention of the code is to arm an hrtimer with the expiry time
X. If the timer is already armed the code needs to check whether the
expiry time X is earlier than the expiry time of the armed timer and
either keep the active timer or rearm it to X. If the timer is not
armed it needs to schedule it to X. That's not what the code does.
It calls hrtimer_try_to_cancel() unconditionally and checks the return
value. If the return value is non zero then it compares the expiry
time of the timer with the new expiry time and picks the earlier
one. The return value check does not take into account that the timer
might run its callback (expressed by a return value of -1). In that
case the expiry time of the timer is probably earlier than the new
expiry time so it rearms the already expired timer with the expiry
value in the past.
If the timer is not active (hrtimer_try_to_cancel() returns 0) it does
not set the new expiry time X but instead restarts the timer with the
expiry time which was active when the timer fired last. That's in the
past as well.
Change the code to check whether the timer is enqueued. If it is
enqueued then the expiry time of the timer is checked against the new
expiry time and it only calls hrtimer_start when the new expiry time
is earlier than the already armed timer. If the timer is not active
then arm it unconditionally with the new expiry time.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Patrick McHardy <kaber@trash.net>
---
net/sched/sch_cbq.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
Index: linux-2.6/net/sched/sch_cbq.c
===================================================================
--- linux-2.6.orig/net/sched/sch_cbq.c
+++ linux-2.6/net/sched/sch_cbq.c
@@ -494,7 +494,6 @@ static void cbq_ovl_delay(struct cbq_cla
if (!cl->delayed) {
psched_time_t sched = q->now;
- ktime_t expires;
delay += cl->offtime;
if (cl->avgidle < 0)
@@ -504,6 +503,7 @@ static void cbq_ovl_delay(struct cbq_cla
cl->undertime = q->now + delay;
if (delay > 0) {
+ ktime_t expires, actexp;
unsigned long flags;
spin_lock_irqsave(&q->lock, flags);
@@ -514,12 +514,19 @@ static void cbq_ovl_delay(struct cbq_cla
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);
+ /*
+ * If the timer is queued check whether the
+ * new expiry time is earlier than the current
+ * one.
+ */
+ if (hrtimer_is_queued(&q->delay_timer)) {
+ actexp = hrtimer_get_expires(&q->delay_timer);
+ if (expires.tv64 >= actexp.tv64)
+ expires.tv64 = 0;
+ }
+ if (expires.tv64)
+ hrtimer_start(&q->delay_timer, expires,
+ HRTIMER_MODE_ABS);
cl->delayed = 1;
cl->xstats.overactions++;
spin_unlock_irqrestore(&q->lock, flags);
next prev parent reply other threads:[~2009-07-09 22:00 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-09 21:59 [patch 0/3] net: Sanitizing hrtimer usage in net/sched/sch_cbq.c Thomas Gleixner
2009-07-09 21:59 ` [patch 1/3] net: serialize hrtimer callback in sched_cbq Thomas Gleixner
2009-07-12 20:55 ` David Miller
2009-07-14 8:22 ` Patrick McHardy
2009-07-14 8:30 ` Peter Zijlstra
2009-07-14 16:01 ` David Miller
2009-07-14 8:55 ` Thomas Gleixner
2009-07-14 16:00 ` David Miller
2009-07-14 16:28 ` Peter Zijlstra
2009-07-14 16:42 ` Linus Torvalds
2009-07-17 12:14 ` Peter Zijlstra
2009-07-17 13:26 ` Oliver Hartkopp
2009-07-17 15:44 ` Linus Torvalds
2009-07-22 3:18 ` David Miller
2009-07-22 6:29 ` Peter Zijlstra
2009-07-22 12:28 ` [PATCH] softirq: tasklet_hrtimer Peter Zijlstra
2009-07-22 14:01 ` [tip:timers/urgent] softirq: introduce tasklet_hrtimer infrastructure tip-bot for Peter Zijlstra
2009-07-22 15:03 ` [tip:core/urgent] " tip-bot for Peter Zijlstra
2009-07-22 15:39 ` [PATCH] softirq: tasklet_hrtimer David Miller
2009-07-22 16:01 ` Linus Torvalds
2009-07-15 9:56 ` [patch 1/3] net: serialize hrtimer callback in sched_cbq Oliver Hartkopp
2009-07-09 21:59 ` Thomas Gleixner [this message]
2009-07-09 21:59 ` [patch 3/3] net: use HRTIMER_RESTART " Thomas Gleixner
2009-07-10 0:39 ` [patch 0/3] net: Sanitizing hrtimer usage in net/sched/sch_cbq.c David Miller
2009-07-12 20:57 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090709215606.626294588@linutronix.de \
--to=tglx@linutronix.de \
--cc=davem@davemloft.net \
--cc=kaber@trash.net \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®