powerpc/64s/radix: add warning and comments in mm_cpumask trim
Add a comment explaining part of the logic for mm_cpumask trimming, and add a (hopefully graceful) check and warning in case something gets it wrong. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20201217134731.488135-2-npiggin@gmail.com
This commit is contained in:
parent
e79b76e03b
commit
a2496049f1
@ -653,13 +653,14 @@ static void do_exit_flush_lazy_tlb(void *arg)
|
||||
{
|
||||
struct mm_struct *mm = arg;
|
||||
unsigned long pid = mm->context.id;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
/*
|
||||
* A kthread could have done a mmget_not_zero() after the flushing CPU
|
||||
* checked mm_is_singlethreaded, and be in the process of
|
||||
* kthread_use_mm when interrupted here. In that case, current->mm will
|
||||
* be set to mm, because kthread_use_mm() setting ->mm and switching to
|
||||
* the mm is done with interrupts off.
|
||||
* checked mm_cpumask, and be in the process of kthread_use_mm when
|
||||
* interrupted here. In that case, current->mm will be set to mm,
|
||||
* because kthread_use_mm() setting ->mm and switching to the mm is
|
||||
* done with interrupts off.
|
||||
*/
|
||||
if (current->mm == mm)
|
||||
goto out_flush;
|
||||
@ -673,8 +674,22 @@ static void do_exit_flush_lazy_tlb(void *arg)
|
||||
mmdrop(mm);
|
||||
}
|
||||
|
||||
atomic_dec(&mm->context.active_cpus);
|
||||
cpumask_clear_cpu(smp_processor_id(), mm_cpumask(mm));
|
||||
/*
|
||||
* This IPI is only initiated from a CPU which is running mm which
|
||||
* is a single-threaded process, so there will not be another racing
|
||||
* IPI coming in where we would find our cpumask already clear.
|
||||
*
|
||||
* Nothing else clears our bit in the cpumask except CPU offlining,
|
||||
* in which case we should not be taking IPIs here. However check
|
||||
* this just in case the logic is wrong somewhere, and don't underflow
|
||||
* the active_cpus count.
|
||||
*/
|
||||
if (cpumask_test_cpu(cpu, mm_cpumask(mm))) {
|
||||
atomic_dec(&mm->context.active_cpus);
|
||||
cpumask_clear_cpu(cpu, mm_cpumask(mm));
|
||||
} else {
|
||||
WARN_ON_ONCE(1);
|
||||
}
|
||||
|
||||
out_flush:
|
||||
_tlbiel_pid(pid, RIC_FLUSH_ALL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user