aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAtish Patra <atish.patra@wdc.com>2018-10-02 15:15:04 -0400
committerPalmer Dabbelt <palmer@sifive.com>2018-10-22 20:03:37 -0400
commit6825c7a80f1863b975a00042abe140ea24813af2 (patch)
treee70a0f3aea2fbc7fbe69af60a864f998e1b69c55
parenta37d56fc401108f39dec9ba83ed923a453937a26 (diff)
RISC-V: Add logical CPU indexing for RISC-V
Currently, both Linux CPU id and hart id are same. This is not recommended as it will lead to discontinuous CPU indexing in Linux. Moreover, kdump kernel will run from CPU0 which would be absent if we follow existing scheme. Implement a logical mapping between Linux CPU id and hart id to decouple these two. Always mark the boot processor as CPU0 and all other CPUs get the logical CPU id based on their booting order. Signed-off-by: Atish Patra <atish.patra@wdc.com> Reviewed-by: Anup Patel <anup@brainfault.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
-rw-r--r--arch/riscv/include/asm/smp.h24
-rw-r--r--arch/riscv/kernel/setup.c4
-rw-r--r--arch/riscv/kernel/smp.c19
3 files changed, 46 insertions, 1 deletions
diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h
index 85d7619eb927..47fd61dfc897 100644
--- a/arch/riscv/include/asm/smp.h
+++ b/arch/riscv/include/asm/smp.h
@@ -18,6 +18,13 @@
18#include <linux/irqreturn.h> 18#include <linux/irqreturn.h>
19#include <linux/thread_info.h> 19#include <linux/thread_info.h>
20 20
21#define INVALID_HARTID ULONG_MAX
22/*
23 * Mapping between linux logical cpu index and hartid.
24 */
25extern unsigned long __cpuid_to_hartid_map[NR_CPUS];
26#define cpuid_to_hartid_map(cpu) __cpuid_to_hartid_map[cpu]
27
21#ifdef CONFIG_SMP 28#ifdef CONFIG_SMP
22 29
23/* SMP initialization hook for setup_arch */ 30/* SMP initialization hook for setup_arch */
@@ -29,12 +36,27 @@ void arch_send_call_function_ipi_mask(struct cpumask *mask);
29/* Hook for the generic smp_call_function_single() routine. */ 36/* Hook for the generic smp_call_function_single() routine. */
30void arch_send_call_function_single_ipi(int cpu); 37void arch_send_call_function_single_ipi(int cpu);
31 38
39int riscv_hartid_to_cpuid(int hartid);
40void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out);
41
32/* 42/*
33 * Obtains the hart ID of the currently executing task. This relies on 43 * Obtains the hart ID of the currently executing task. This relies on
34 * THREAD_INFO_IN_TASK, but we define that unconditionally. 44 * THREAD_INFO_IN_TASK, but we define that unconditionally.
35 */ 45 */
36#define raw_smp_processor_id() (current_thread_info()->cpu) 46#define raw_smp_processor_id() (current_thread_info()->cpu)
37 47
38#endif /* CONFIG_SMP */ 48#else
49
50static inline int riscv_hartid_to_cpuid(int hartid)
51{
52 return 0;
53}
39 54
55static inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in,
56 struct cpumask *out)
57{
58 cpumask_set_cpu(cpuid_to_hartid_map(0), out);
59}
60
61#endif /* CONFIG_SMP */
40#endif /* _ASM_RISCV_SMP_H */ 62#endif /* _ASM_RISCV_SMP_H */
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index b2d26d9d8489..d5d8611066d5 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -82,6 +82,10 @@ EXPORT_SYMBOL(empty_zero_page);
82/* The lucky hart to first increment this variable will boot the other cores */ 82/* The lucky hart to first increment this variable will boot the other cores */
83atomic_t hart_lottery; 83atomic_t hart_lottery;
84 84
85unsigned long __cpuid_to_hartid_map[NR_CPUS] = {
86 [0 ... NR_CPUS-1] = INVALID_HARTID
87};
88
85#ifdef CONFIG_BLK_DEV_INITRD 89#ifdef CONFIG_BLK_DEV_INITRD
86static void __init setup_initrd(void) 90static void __init setup_initrd(void)
87{ 91{
diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c
index 906fe21ea21b..0bd48935f886 100644
--- a/arch/riscv/kernel/smp.c
+++ b/arch/riscv/kernel/smp.c
@@ -38,7 +38,26 @@ enum ipi_message_type {
38 IPI_MAX 38 IPI_MAX
39}; 39};
40 40
41int riscv_hartid_to_cpuid(int hartid)
42{
43 int i = -1;
44
45 for (i = 0; i < NR_CPUS; i++)
46 if (cpuid_to_hartid_map(i) == hartid)
47 return i;
48
49 pr_err("Couldn't find cpu id for hartid [%d]\n", hartid);
50 BUG();
51 return i;
52}
41 53
54void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out)
55{
56 int cpu;
57
58 for_each_cpu(cpu, in)
59 cpumask_set_cpu(cpuid_to_hartid_map(cpu), out);
60}
42/* Unsupported */ 61/* Unsupported */
43int setup_profiling_timer(unsigned int multiplier) 62int setup_profiling_timer(unsigned int multiplier)
44{ 63{