diff options
| author | Ingo Molnar <mingo@elte.hu> | 2003-08-14 11:26:03 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.osdl.org> | 2003-08-14 11:26:03 -0700 |
| commit | d563c54ed534eb37283c397a6a4146996c83b350 (patch) | |
| tree | a0b3cd57d970a7e43abb6cf207cbea8386f5218d /kernel | |
| parent | 00ed8a2c5e66ab1e6339f59b290d3e3f370b76cb (diff) | |
[PATCH] More timer race fixes
Patch from Julie DeWandel.
This patch has solved the crashes observed during TPC-C runs on the
16-way box. (I'm confident it will fix the other reported cases as
well.)
The race is the setting of timer->base to NULL, by del_timer() or
__run_timers(). If new_base == old_base in __mod_timer() then we do not
re-check timer->base after getting the lock. (the only case where we do
not have to re-check the base is in the !old_base case, but the else
branch also includes the old_base==new_base case.)
The __run_timers() case made the lock_timer() patch not work fully - we
cannot use lock_timer() in __run_timers() due to lock ordering.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/timer.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/kernel/timer.c b/kernel/timer.c index 81bb979fb7e7..ab083d12eb3a 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -179,8 +179,13 @@ repeat: spin_unlock(&old_base->lock); goto repeat; } - } else + } else { spin_lock(&new_base->lock); + if (timer->base != old_base) { + spin_unlock(&new_base->lock); + goto repeat; + } + } /* * Delete the previous timeout (if there was any), and install |
