Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1262543
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | Re: [PATCH] timer: add_timer_on() should perform proper migration |
| Date | 2015-11-04 20:40 +0100 |
| Message-ID | <qrc4y-4EN-17@gated-at.bofh.it> (permalink) |
| References | (6 earlier) <qqO2e-5XS-1@gated-at.bofh.it> <qqSIz-vE-19@gated-at.bofh.it> <qqTOh-1pC-7@gated-at.bofh.it> <qr4JH-8jO-3@gated-at.bofh.it> <qr9T4-3m9-13@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
Tejun,
On Wed, 4 Nov 2015, Tejun Heo wrote:
> Regardless of the previous CPU a timer was on, add_timer_on()
> currently simply sets timer->flags to the new CPU. As the caller must
> be seeing the timer as idle, this is locally fine, but the timer
> leaving the old base while unlocked can lead to race conditions as
> follows.
nice detective work. This has been there forever. I really wonder why
nobody ever triggered this before.
@stable:
The patch does only apply to kernels >= 4.2. Backport for older
kernels is below.
Thanks,
tglx
----------->
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -966,13 +966,26 @@ EXPORT_SYMBOL(add_timer);
*/
void add_timer_on(struct timer_list *timer, int cpu)
{
- struct tvec_base *base = per_cpu(tvec_bases, cpu);
+ struct tvec_base *new_base = per_cpu(tvec_bases, cpu);
+ struct tvec_base *base;
unsigned long flags;
timer_stats_timer_set_start_info(timer);
BUG_ON(timer_pending(timer) || !timer->function);
- spin_lock_irqsave(&base->lock, flags);
- timer_set_base(timer, base);
+
+ /*
+ * If @timer was on a different CPU, it should be migrated with the
+ * old base locked to prevent other operations proceeding with the
+ * wrong base locked. See lock_timer_base().
+ */
+ base = lock_timer_base(timer, &flags);
+ if (base != new_base) {
+ timer_set_base(timer, NULL);
+ spin_unlock(&base->lock);
+ base = new_base;
+ spin_lock(&base->lock);
+ timer_set_base(timer, base);
+ }
debug_activate(timer, timer->expires);
internal_add_timer(base, timer);
spin_unlock_irqrestore(&base->lock, flags);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Re: timer code oops when calling mod_delayed_work Tejun Heo <tj@kernel.org> - 2015-10-31 22:40 +0100
Re: timer code oops when calling mod_delayed_work Jeff Layton <jlayton@poochiereds.net> - 2015-10-31 23:00 +0100
Re: timer code oops when calling mod_delayed_work Chris Worley <chris.worley@primarydata.com> - 2015-11-02 20:50 +0100
Re: timer code oops when calling mod_delayed_work Jeff Layton <jlayton@poochiereds.net> - 2015-11-02 21:00 +0100
Re: timer code oops when calling mod_delayed_work Jeff Layton <jlayton@poochiereds.net> - 2015-11-03 02:40 +0100
Re: timer code oops when calling mod_delayed_work Jeff Layton <jlayton@poochiereds.net> - 2015-11-03 19:00 +0100
Re: timer code oops when calling mod_delayed_work Tejun Heo <tj@kernel.org> - 2015-11-04 00:00 +0100
Re: timer code oops when calling mod_delayed_work Tejun Heo <tj@kernel.org> - 2015-11-04 01:10 +0100
Re: timer code oops when calling mod_delayed_work Jeff Layton <jlayton@poochiereds.net> - 2015-11-04 12:50 +0100
[PATCH] timer: add_timer_on() should perform proper migration Tejun Heo <tj@kernel.org> - 2015-11-04 18:20 +0100
[tip:timers/urgent] timers: Use proper base migration in add_timer_on() tip-bot for Tejun Heo <tipbot@zytor.com> - 2015-11-04 20:30 +0100
Re: [PATCH] timer: add_timer_on() should perform proper migration Thomas Gleixner <tglx@linutronix.de> - 2015-11-04 20:40 +0100
Re: [PATCH] timer: add_timer_on() should perform proper migration Tejun Heo <tj@kernel.org> - 2015-11-04 20:50 +0100
csiph-web