]> git.itanic.dy.fi Git - linux-stable/commitdiff
LoongArch/smp: Call rcutree_report_cpu_starting() at tlb_init()
authorHuacai Chen <chenhuacai@loongson.cn>
Fri, 26 Jan 2024 08:22:07 +0000 (16:22 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 5 Feb 2024 20:14:38 +0000 (20:14 +0000)
commit 5056c596c3d1848021a4eaa76ee42f4c05c50346 upstream.

Machines which have more than 8 nodes fail to boot SMP after commit
a2ccf46333d7b2cf96 ("LoongArch/smp: Call rcutree_report_cpu_starting()
earlier"). Because such machines use tlb-based per-cpu base address
rather than dmw-based per-cpu base address, resulting per-cpu variables
can only be accessed after tlb_init(). But rcutree_report_cpu_starting()
is now called before tlb_init() and accesses per-cpu variables indeed.

Since the original patch want to avoid the lockdep warning caused by
page allocation in tlb_init(), we can move rcutree_report_cpu_starting()
to tlb_init() where after tlb exception configuration but before page
allocation.

Fixes: a2ccf46333d7b2cf96 ("LoongArch/smp: Call rcutree_report_cpu_starting() earlier")
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/loongarch/kernel/smp.c
arch/loongarch/mm/tlb.c

index 42e3a0e18956fd72cfc4fb619ea85cf2047c6382..2fbf541d7b4f6a174b503b2c2925250dbcf3fd09 100644 (file)
@@ -506,7 +506,6 @@ asmlinkage void start_secondary(void)
        sync_counter();
        cpu = raw_smp_processor_id();
        set_my_cpu_offset(per_cpu_offset(cpu));
-       rcu_cpu_starting(cpu);
 
        cpu_probe();
        constant_clockevent_init();
index 2c0a411f23aa778bb62160bd511252736fc987be..56bf1dd5358aa1b31ed61e4f1a82f579643771c8 100644 (file)
@@ -284,12 +284,16 @@ static void setup_tlb_handler(int cpu)
                set_handler(EXCCODE_TLBNR * VECSIZE, handle_tlb_protect, VECSIZE);
                set_handler(EXCCODE_TLBNX * VECSIZE, handle_tlb_protect, VECSIZE);
                set_handler(EXCCODE_TLBPE * VECSIZE, handle_tlb_protect, VECSIZE);
-       }
+       } else {
+               int vec_sz __maybe_unused;
+               void *addr __maybe_unused;
+               struct page *page __maybe_unused;
+
+               /* Avoid lockdep warning */
+               rcu_cpu_starting(cpu);
+
 #ifdef CONFIG_NUMA
-       else {
-               void *addr;
-               struct page *page;
-               const int vec_sz = sizeof(exception_handlers);
+               vec_sz = sizeof(exception_handlers);
 
                if (pcpu_handlers[cpu])
                        return;
@@ -305,8 +309,8 @@ static void setup_tlb_handler(int cpu)
                csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_EENTRY);
                csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_MERRENTRY);
                csr_write64(pcpu_handlers[cpu] + 80*VECSIZE, LOONGARCH_CSR_TLBRENTRY);
-       }
 #endif
+       }
 }
 
 void tlb_init(int cpu)