[PATCH] arc: use hardware ARCNUM in smp_processor_id()
We used to think that ARC cores in SMP SoC start consequentially, i.e. core0 -> core1 -> core2 -> core4. Moreover we treat core0 as a master core which does some low-level initialization before allowing other cores to start doing real stuff. In that case everything works as expected - smp_processor_id() returns expected values for all cores, i.e.: 0 for core0 1 for core1 etc. But what if instead of core0 we want core1 to be the master? That might be the case if we want to use only one core out of SMP setup and that core is not core0 or for some other reason modify core start-up sequence to say: core3 -> core1 > ... In that case smp_processor_id() returns values that differ from real hardware core index. For the first/master core that we'l get 0, the next one will be 1 etc. The problem here is we'll use improper cpu indexes in MCIP commands and inevitably commands will be sent to unexpected cores causing all sorts of unexpected behavior. But if we use hardware core index out out IDENTITY AUX reg that problem won't happen because cpu value will match its hardware index. Signed-off-by: Alexey Brodkin Cc: sta...@vger.kernel.org --- arch/arc/include/asm/smp.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h index 0861007d9ef3..5aad65d3defd 100644 --- a/arch/arc/include/asm/smp.h +++ b/arch/arc/include/asm/smp.h @@ -14,8 +14,9 @@ #include #include #include +#include -#define raw_smp_processor_id() (current_thread_info()->cpu) +#define raw_smp_processor_id() ((int)(read_aux_reg(AUX_IDENTITY) >> 8) & 0xFF) /* including cpumask.h leads to cyclic deps hence this Forward declaration */ struct cpumask; -- 2.7.4 ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
[PATCH] arc: Allow selection of master core
We used to think that core0 is always so-called master-core which is executed before all other cores and does some preparation before allowing other cores to start or continue execution. But in some cases we may want another core to be that master or we may only run Linux on subset of cores in SMP SoC so core0 won't be an option any longer. That change introduces new Kconfig option that allows explicit selection of the master core. Signed-off-by: Alexey Brodkin --- arch/arc/Kconfig | 17 + arch/arc/kernel/head.S | 2 +- arch/arc/kernel/smp.c | 6 +++--- arch/arc/mm/cache.c| 4 +++- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index 6e89585b5ea0..c0969274874f 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -204,6 +204,23 @@ config ARC_SMP_HALT_ON_RESET at designated entry point. For other case, all jump to common entry point and spin wait for Master's signal. +config ARC_MASTER_CORE + int "Master core index" + range 0 NR_CPUS + default "0" + help + Any core might be used as a master, i.e. the one which does initial + low-level setup before real SMP stuff is ready to be used. + Default 0 (the first core) is what you most probably need but if you + know what you are doing other cores might be used as a master. + This is especially useful if one wants to run Linux just on one core out of + many in SMP SoC and that core to be not the first one. + + Note that value MUST BE <= (NR_CPUS - 1), i.e. if NR_CPUS=4 then master core + MUST BE in a range 0, 1, 2, 3. Unfortunately in Kconfig there's no way to + set a range with expression, so it checks for <= NR_CPUS which is not entirely + correct! + endif #SMP config ARC_MCIP diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S index 689dd867fdff..92d203e9c57f 100644 --- a/arch/arc/kernel/head.S +++ b/arch/arc/kernel/head.S @@ -69,7 +69,7 @@ ENTRY(stext) #ifdef CONFIG_SMP GET_CPU_ID r5 - cmp r5, 0 + cmp r5, CONFIG_ARC_MASTER_CORE mov.nz r0, r5 #ifdef CONFIG_ARC_SMP_HALT_ON_RESET ; Non-Master can proceed as system would be booted sufficiently diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c index 88674d972c9d..3b1642a9c0b5 100644 --- a/arch/arc/kernel/smp.c +++ b/arch/arc/kernel/smp.c @@ -92,13 +92,13 @@ static volatile int wake_flag; static void arc_default_smp_cpu_kick(int cpu, unsigned long pc) { - BUG_ON(cpu == 0); - wake_flag = cpu; + BUG_ON(cpu == CONFIG_ARC_MASTER_CORE); + wake_flag = BIT(cpu); } void arc_platform_smp_wait_to_boot(int cpu) { - while (wake_flag != cpu) + while (wake_flag != BIT(cpu)) ; wake_flag = 0; diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 3f443ab770e0..1260ff34 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -933,14 +933,16 @@ void arc_cache_init(void) printk(arc_cache_mumbojumbo(0, str, sizeof(str))); +#ifdef CONFIG_SMP /* * Only master CPU needs to execute rest of function: * - Assume SMP so all cores will have same cache config so *any geomtry checks will be same for all * - IOC setup / dma callbacks only need to be setup once */ - if (cpu) + if (cpu != CONFIG_ARC_MASTER_CORE) return; +#endif if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) { struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; -- 2.7.4 ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH] arc: use hardware ARCNUM in smp_processor_id()
+CC PeterZ, Andy On 12/07/2016 07:36 AM, Alexey Brodkin wrote: > We used to think that ARC cores in SMP SoC start > consequentially, i.e. core0 -> core1 -> core2 -> core4. > > Moreover we treat core0 as a master core which does some > low-level initialization before allowing other cores to > start doing real stuff. > > In that case everything works as expected - smp_processor_id() > returns expected values for all cores, i.e.: > 0 for core0 > 1 for core1 etc. > > But what if instead of core0 we want core1 to be the master? > That might be the case if we want to use only one core out of > SMP setup and that core is not core0 or for some other reason > modify core start-up sequence to say: core3 -> core1 > ... > > In that case smp_processor_id() returns values that differ > from real hardware core index. For the first/master core that > we'l get 0, the next one will be 1 etc. > > The problem here is we'll use improper cpu indexes in MCIP commands > and inevitably commands will be sent to unexpected cores causing all > sorts of unexpected behavior. > > But if we use hardware core index out out IDENTITY AUX reg that problem > won't happen because cpu value will match its hardware index. > > Signed-off-by: Alexey Brodkin > Cc: sta...@vger.kernel.org > --- > arch/arc/include/asm/smp.h | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h > index 0861007d9ef3..5aad65d3defd 100644 > --- a/arch/arc/include/asm/smp.h > +++ b/arch/arc/include/asm/smp.h > @@ -14,8 +14,9 @@ > #include > #include > #include > +#include > > -#define raw_smp_processor_id() (current_thread_info()->cpu) > +#define raw_smp_processor_id() ((int)(read_aux_reg(AUX_IDENTITY) >> 8) & > 0xFF) So I also wondered about this when debugging the SMP bringup on FPGA last year. It seems kernel code never changes this field and only sets it up so it would be OK to do above. However most arches seem to use the per thread "soft" value (x86 uses a per cpu "soft" value"), blackfin seems to be using a hardware value. However if the value can't possibly be changes (by say scheduler etc) then there is no point retrieving it from memory - if it is relatively cheap derive it from to core reg. Peter, Andy ? -Vineet > > /* including cpumask.h leads to cyclic deps hence this Forward declaration */ > struct cpumask; ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc
Re: [PATCH] arc: use hardware ARCNUM in smp_processor_id()
On 12/07/2016 07:36 AM, Alexey Brodkin wrote: > We used to think that ARC cores in SMP SoC start > consequentially, i.e. core0 -> core1 -> core2 -> core4. > > Moreover we treat core0 as a master core which does some > low-level initialization before allowing other cores to > start doing real stuff. > > In that case everything works as expected - smp_processor_id() > returns expected values for all cores, i.e.: > 0 for core0 > 1 for core1 etc. > > But what if instead of core0 we want core1 to be the master? > That might be the case if we want to use only one core out of > SMP setup and that core is not core0 or for some other reason > modify core start-up sequence to say: core3 -> core1 > ... > > In that case smp_processor_id() returns values that differ > from real hardware core index. For the first/master core that > we'l get 0, the next one will be 1 etc. But then the problem is you are not setting up thread_info->cpu correctly. And that needs fixing. Say we already had ur next patch which doesn't assume 0 based masters, then is this patch still needed. Essentially this change can be taken as an optimization (mem vz. aux reg read) but I don't think it is a fix ! > The problem here is we'll use improper cpu indexes in MCIP commands > and inevitably commands will be sent to unexpected cores causing all > sorts of unexpected behavior. > > But if we use hardware core index out out IDENTITY AUX reg that problem > won't happen because cpu value will match its hardware index. > > Signed-off-by: Alexey Brodkin > Cc: sta...@vger.kernel.org > --- > arch/arc/include/asm/smp.h | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/arch/arc/include/asm/smp.h b/arch/arc/include/asm/smp.h > index 0861007d9ef3..5aad65d3defd 100644 > --- a/arch/arc/include/asm/smp.h > +++ b/arch/arc/include/asm/smp.h > @@ -14,8 +14,9 @@ > #include > #include > #include > +#include > > -#define raw_smp_processor_id() (current_thread_info()->cpu) > +#define raw_smp_processor_id() ((int)(read_aux_reg(AUX_IDENTITY) >> 8) & > 0xFF) > > /* including cpumask.h leads to cyclic deps hence this Forward declaration */ > struct cpumask; ___ linux-snps-arc mailing list linux-snps-arc@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-snps-arc