Commit de5b55c1 authored by Thomas Gleixner's avatar Thomas Gleixner

stop_machine: Use raw spinlocks

Use raw-locks in stop_machine() to allow locking in irq-off and
preempt-disabled regions on -RT. This also documents the possible locking
context in general.

[bigeasy: update patch description.]
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://lkml.kernel.org/r/20180423191635.6014-1-bigeasy@linutronix.de
parent 02acc80d
...@@ -36,7 +36,7 @@ struct cpu_stop_done { ...@@ -36,7 +36,7 @@ struct cpu_stop_done {
struct cpu_stopper { struct cpu_stopper {
struct task_struct *thread; struct task_struct *thread;
spinlock_t lock; raw_spinlock_t lock;
bool enabled; /* is this stopper enabled? */ bool enabled; /* is this stopper enabled? */
struct list_head works; /* list of pending works */ struct list_head works; /* list of pending works */
...@@ -78,13 +78,13 @@ static bool cpu_stop_queue_work(unsigned int cpu, struct cpu_stop_work *work) ...@@ -78,13 +78,13 @@ static bool cpu_stop_queue_work(unsigned int cpu, struct cpu_stop_work *work)
unsigned long flags; unsigned long flags;
bool enabled; bool enabled;
spin_lock_irqsave(&stopper->lock, flags); raw_spin_lock_irqsave(&stopper->lock, flags);
enabled = stopper->enabled; enabled = stopper->enabled;
if (enabled) if (enabled)
__cpu_stop_queue_work(stopper, work); __cpu_stop_queue_work(stopper, work);
else if (work->done) else if (work->done)
cpu_stop_signal_done(work->done); cpu_stop_signal_done(work->done);
spin_unlock_irqrestore(&stopper->lock, flags); raw_spin_unlock_irqrestore(&stopper->lock, flags);
return enabled; return enabled;
} }
...@@ -231,8 +231,8 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, ...@@ -231,8 +231,8 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1,
struct cpu_stopper *stopper2 = per_cpu_ptr(&cpu_stopper, cpu2); struct cpu_stopper *stopper2 = per_cpu_ptr(&cpu_stopper, cpu2);
int err; int err;
retry: retry:
spin_lock_irq(&stopper1->lock); raw_spin_lock_irq(&stopper1->lock);
spin_lock_nested(&stopper2->lock, SINGLE_DEPTH_NESTING); raw_spin_lock_nested(&stopper2->lock, SINGLE_DEPTH_NESTING);
err = -ENOENT; err = -ENOENT;
if (!stopper1->enabled || !stopper2->enabled) if (!stopper1->enabled || !stopper2->enabled)
...@@ -255,8 +255,8 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, ...@@ -255,8 +255,8 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1,
__cpu_stop_queue_work(stopper1, work1); __cpu_stop_queue_work(stopper1, work1);
__cpu_stop_queue_work(stopper2, work2); __cpu_stop_queue_work(stopper2, work2);
unlock: unlock:
spin_unlock(&stopper2->lock); raw_spin_unlock(&stopper2->lock);
spin_unlock_irq(&stopper1->lock); raw_spin_unlock_irq(&stopper1->lock);
if (unlikely(err == -EDEADLK)) { if (unlikely(err == -EDEADLK)) {
while (stop_cpus_in_progress) while (stop_cpus_in_progress)
...@@ -448,9 +448,9 @@ static int cpu_stop_should_run(unsigned int cpu) ...@@ -448,9 +448,9 @@ static int cpu_stop_should_run(unsigned int cpu)
unsigned long flags; unsigned long flags;
int run; int run;
spin_lock_irqsave(&stopper->lock, flags); raw_spin_lock_irqsave(&stopper->lock, flags);
run = !list_empty(&stopper->works); run = !list_empty(&stopper->works);
spin_unlock_irqrestore(&stopper->lock, flags); raw_spin_unlock_irqrestore(&stopper->lock, flags);
return run; return run;
} }
...@@ -461,13 +461,13 @@ static void cpu_stopper_thread(unsigned int cpu) ...@@ -461,13 +461,13 @@ static void cpu_stopper_thread(unsigned int cpu)
repeat: repeat:
work = NULL; work = NULL;
spin_lock_irq(&stopper->lock); raw_spin_lock_irq(&stopper->lock);
if (!list_empty(&stopper->works)) { if (!list_empty(&stopper->works)) {
work = list_first_entry(&stopper->works, work = list_first_entry(&stopper->works,
struct cpu_stop_work, list); struct cpu_stop_work, list);
list_del_init(&work->list); list_del_init(&work->list);
} }
spin_unlock_irq(&stopper->lock); raw_spin_unlock_irq(&stopper->lock);
if (work) { if (work) {
cpu_stop_fn_t fn = work->fn; cpu_stop_fn_t fn = work->fn;
...@@ -541,7 +541,7 @@ static int __init cpu_stop_init(void) ...@@ -541,7 +541,7 @@ static int __init cpu_stop_init(void)
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu); struct cpu_stopper *stopper = &per_cpu(cpu_stopper, cpu);
spin_lock_init(&stopper->lock); raw_spin_lock_init(&stopper->lock);
INIT_LIST_HEAD(&stopper->works); INIT_LIST_HEAD(&stopper->works);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment