powerpc: Account mm_cpumask and active_cpus in init_mm
authorNicholas Piggin <npiggin@gmail.com>
Wed, 24 May 2023 06:08:18 +0000 (16:08 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 2 Aug 2023 12:22:18 +0000 (22:22 +1000)
init_mm mm_cpumask and context.active_cpus is not maintained at boot
and hotplug. This seems to be harmless because init_mm does not have a
userspace and so never gets user TLBs flushed, but it looks odd and it
prevents some sanity checks being added.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20230524060821.148015-2-npiggin@gmail.com
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/smp.c
arch/powerpc/mm/mmu_context.c

index d2a446216444f28e187bea720df8da8d90c1534b..16843294d978cfad216ae7935807df372e9f41fa 100644 (file)
@@ -969,8 +969,12 @@ void __init setup_arch(char **cmdline_p)
        klp_init_thread_info(&init_task);
 
        setup_initial_init_mm(_stext, _etext, _edata, _end);
-
+       /* sched_init() does the mmgrab(&init_mm) for the primary CPU */
+       VM_WARN_ON(cpumask_test_cpu(smp_processor_id(), mm_cpumask(&init_mm)));
+       cpumask_set_cpu(smp_processor_id(), mm_cpumask(&init_mm));
+       inc_mm_active_cpus(&init_mm);
        mm_iommu_init(&init_mm);
+
        irqstack_early_init();
        exc_lvl_early_init();
        emergency_stack_init();
index fbbb695bae3d25753e8c11d1c77af64761fa8699..8cb6d1c9026696095f8828c3158ada26ee5d7679 100644 (file)
@@ -47,6 +47,7 @@
 #include <asm/smp.h>
 #include <asm/time.h>
 #include <asm/machdep.h>
+#include <asm/mmu_context.h>
 #include <asm/cputhreads.h>
 #include <asm/cputable.h>
 #include <asm/mpic.h>
@@ -1616,6 +1617,9 @@ void start_secondary(void *unused)
 
        mmgrab_lazy_tlb(&init_mm);
        current->active_mm = &init_mm;
+       VM_WARN_ON(cpumask_test_cpu(smp_processor_id(), mm_cpumask(&init_mm)));
+       cpumask_set_cpu(cpu, mm_cpumask(&init_mm));
+       inc_mm_active_cpus(&init_mm);
 
        smp_store_cpu_info(cpu);
        set_dec(tb_ticks_per_jiffy);
@@ -1751,6 +1755,14 @@ int __cpu_disable(void)
 
 void __cpu_die(unsigned int cpu)
 {
+       /*
+        * This could perhaps be a generic call in idlea_task_dead(), but
+        * that requires testing from all archs, so first put it here to
+        */
+       VM_WARN_ON_ONCE(!cpumask_test_cpu(cpu, mm_cpumask(&init_mm)));
+       dec_mm_active_cpus(&init_mm);
+       cpumask_clear_cpu(cpu, mm_cpumask(&init_mm));
+
        if (smp_ops->cpu_die)
                smp_ops->cpu_die(cpu);
 }
index 1fb9c99f86797a3211db4291df9cd4697b4c005a..894468975a441d3823c070629216f3f1ff320912 100644 (file)
@@ -47,6 +47,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
 
        /* Mark this context has been used on the new CPU */
        if (!cpumask_test_cpu(smp_processor_id(), mm_cpumask(next))) {
+               VM_WARN_ON_ONCE(next == &init_mm);
                cpumask_set_cpu(smp_processor_id(), mm_cpumask(next));
                inc_mm_active_cpus(next);