Skip to content

Commit 6825c7a

Browse files
atishp04palmer-dabbelt
authored andcommitted
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>
1 parent a37d56f commit 6825c7a

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

arch/riscv/include/asm/smp.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@
1818
#include <linux/irqreturn.h>
1919
#include <linux/thread_info.h>
2020

21+
#define INVALID_HARTID ULONG_MAX
22+
/*
23+
* Mapping between linux logical cpu index and hartid.
24+
*/
25+
extern unsigned long __cpuid_to_hartid_map[NR_CPUS];
26+
#define cpuid_to_hartid_map(cpu) __cpuid_to_hartid_map[cpu]
27+
2128
#ifdef CONFIG_SMP
2229

2330
/* SMP initialization hook for setup_arch */
@@ -29,12 +36,27 @@ void arch_send_call_function_ipi_mask(struct cpumask *mask);
2936
/* Hook for the generic smp_call_function_single() routine. */
3037
void arch_send_call_function_single_ipi(int cpu);
3138

39+
int riscv_hartid_to_cpuid(int hartid);
40+
void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out);
41+
3242
/*
3343
* Obtains the hart ID of the currently executing task. This relies on
3444
* THREAD_INFO_IN_TASK, but we define that unconditionally.
3545
*/
3646
#define raw_smp_processor_id() (current_thread_info()->cpu)
3747

38-
#endif /* CONFIG_SMP */
48+
#else
49+
50+
static inline int riscv_hartid_to_cpuid(int hartid)
51+
{
52+
return 0;
53+
}
3954

55+
static 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 */
4062
#endif /* _ASM_RISCV_SMP_H */

arch/riscv/kernel/setup.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ EXPORT_SYMBOL(empty_zero_page);
8282
/* The lucky hart to first increment this variable will boot the other cores */
8383
atomic_t hart_lottery;
8484

85+
unsigned long __cpuid_to_hartid_map[NR_CPUS] = {
86+
[0 ... NR_CPUS-1] = INVALID_HARTID
87+
};
88+
8589
#ifdef CONFIG_BLK_DEV_INITRD
8690
static void __init setup_initrd(void)
8791
{

arch/riscv/kernel/smp.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,26 @@ enum ipi_message_type {
3838
IPI_MAX
3939
};
4040

41+
int 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+
}
4153

54+
void 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+
}
4261
/* Unsupported */
4362
int setup_profiling_timer(unsigned int multiplier)
4463
{

0 commit comments

Comments
 (0)