Skip to content

Commit 71fdb70

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
sched/clock: Fix clear_sched_clock_stable() preempt wobbly
Paul reported a problems with clear_sched_clock_stable(). Since we run all of __clear_sched_clock_stable() from workqueue context, there's a preempt problem. Solve it by only running the static_key_disable() from workqueue. Reported-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: fweisbec@gmail.com Link: http://lkml.kernel.org/r/20170313124621.GA3328@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 093b995 commit 71fdb70

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

kernel/sched/clock.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,14 @@ static void __set_sched_clock_stable(void)
141141
tick_dep_clear(TICK_DEP_BIT_CLOCK_UNSTABLE);
142142
}
143143

144-
static void __clear_sched_clock_stable(struct work_struct *work)
144+
static void __sched_clock_work(struct work_struct *work)
145+
{
146+
static_branch_disable(&__sched_clock_stable);
147+
}
148+
149+
static DECLARE_WORK(sched_clock_work, __sched_clock_work);
150+
151+
static void __clear_sched_clock_stable(void)
145152
{
146153
struct sched_clock_data *scd = this_scd();
147154

@@ -160,11 +167,11 @@ static void __clear_sched_clock_stable(struct work_struct *work)
160167
scd->tick_gtod, gtod_offset,
161168
scd->tick_raw, raw_offset);
162169

163-
static_branch_disable(&__sched_clock_stable);
164170
tick_dep_set(TICK_DEP_BIT_CLOCK_UNSTABLE);
165-
}
166171

167-
static DECLARE_WORK(sched_clock_work, __clear_sched_clock_stable);
172+
if (sched_clock_stable())
173+
schedule_work(&sched_clock_work);
174+
}
168175

169176
void clear_sched_clock_stable(void)
170177
{
@@ -173,7 +180,7 @@ void clear_sched_clock_stable(void)
173180
smp_mb(); /* matches sched_clock_init_late() */
174181

175182
if (sched_clock_running == 2)
176-
schedule_work(&sched_clock_work);
183+
__clear_sched_clock_stable();
177184
}
178185

179186
void sched_clock_init_late(void)

0 commit comments

Comments
 (0)