diff options
| author | Linus Torvalds <torvalds@home.osdl.org> | 2003-10-13 02:30:26 -0700 |
|---|---|---|
| committer | David S. Miller <davem@kernel.bkbits.net> | 2003-10-13 02:30:26 -0700 |
| commit | 511f1ac6f35faccfa496885e6aa138ff2e56124a (patch) | |
| tree | bba3fb3edc8bd036e1e4a875eb49fc540f7d0153 /kernel/timer.c | |
| parent | 2b6ebba8e5c7b381e49e7be51ec35290c9e716b0 (diff) | |
Revert recent SMP timer changes - they cause deadlocks
Cset exclude: mingo@elte.hu[torvalds]|ChangeSet|20031012025453|05000
Diffstat (limited to 'kernel/timer.c')
| -rw-r--r-- | kernel/timer.c | 46 |
1 files changed, 7 insertions, 39 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index eb7df932e11a..176d2c3215b4 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -315,30 +315,23 @@ EXPORT_SYMBOL(del_timer); * the timer it also makes sure the handler has finished executing on other * CPUs. * - * Synchronization rules: callers must prevent restarting of the timer - * (except restarting the timer from the timer function itself), otherwise - * this function is meaningless. It must not be called from interrupt - * contexts. Upon exit the timer is not queued and the handler is not - * running on any CPU. + * Synchronization rules: callers must prevent restarting of the timer, + * otherwise this function is meaningless. It must not be called from + * interrupt contexts. Upon exit the timer is not queued and the handler + * is not running on any CPU. * - * The function returns the number of times it has deactivated a pending - * timer. + * The function returns whether it has deactivated a pending timer or not. */ int del_timer_sync(struct timer_list *timer) { - int i, ret = 0, again; - unsigned long flags; tvec_base_t *base; + int i, ret = 0; check_timer(timer); del_again: ret += del_timer(timer); - /* - * First do a lighter but racy check, whether the - * timer is running on any other CPU: - */ for (i = 0; i < NR_CPUS; i++) { if (!cpu_online(i)) continue; @@ -352,33 +345,8 @@ del_again: break; } } - - /* - * Do a heavy but race-free re-check to make sure both that - * the timer is neither running nor pending: - */ - again = 0; - local_irq_save(flags); - - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i)) - spin_lock(&per_cpu(tvec_bases, i).lock); - + smp_rmb(); if (timer_pending(timer)) - again = 1; - else - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i) && - (per_cpu(tvec_bases, i).running_timer == timer)) - again = 1; - - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i)) - spin_unlock(&per_cpu(tvec_bases, i).lock); - - local_irq_restore(flags); - - if (again) goto del_again; return ret; |
