projects
/
cascardo
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
timers: Plug locking race vs. timer migration
[cascardo/linux.git]
/
kernel
/
time
/
timer.c
diff --git
a/kernel/time/timer.c
b/kernel/time/timer.c
index
32bf6f7
..
0d4b91c
100644
(file)
--- a/
kernel/time/timer.c
+++ b/
kernel/time/timer.c
@@
-943,7
+943,14
@@
static struct timer_base *lock_timer_base(struct timer_list *timer,
{
for (;;) {
struct timer_base *base;
{
for (;;) {
struct timer_base *base;
- u32 tf = timer->flags;
+ u32 tf;
+
+ /*
+ * We need to use READ_ONCE() here, otherwise the compiler
+ * might re-read @tf between the check for TIMER_MIGRATING
+ * and spin_lock().
+ */
+ tf = READ_ONCE(timer->flags);
if (!(tf & TIMER_MIGRATING)) {
base = get_timer_base(tf);
if (!(tf & TIMER_MIGRATING)) {
base = get_timer_base(tf);
@@
-1633,7
+1640,7
@@
static inline void __run_timers(struct timer_base *base)
/*
* This function runs timers and the timer-tq in bottom half context.
*/
/*
* This function runs timers and the timer-tq in bottom half context.
*/
-static void run_timer_softirq(struct softirq_action *h)
+static
__latent_entropy
void run_timer_softirq(struct softirq_action *h)
{
struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
{
struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);