From: Peter Zijlstra peterz@infradead.org
mainline inclusion from mainline-v5.13-rc1 commit e40f74c535b8a0ecf3ef0388b51a34cdadb34fb5 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I6VS35
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Introduce a cpumask that indicates (for each CPU) what direction the CPU hotplug is currently going. Notably, it tracks rollbacks. Eg. when an up fails and we do a roll-back down, it will accurately reflect the direction.
Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Reviewed-by: Valentin Schneider valentin.schneider@arm.com Link: https://lkml.kernel.org/r/20210310150109.151441252@infradead.org Signed-off-by: Zeng Heng zengheng4@huawei.com --- include/linux/cpumask.h | 19 +++++++++++++++++++ kernel/cpu.c | 6 ++++++ 2 files changed, 25 insertions(+)
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 0159986ac9ce..92d5ecad8de6 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -91,10 +91,12 @@ extern struct cpumask __cpu_possible_mask; extern struct cpumask __cpu_online_mask; extern struct cpumask __cpu_present_mask; extern struct cpumask __cpu_active_mask; +extern struct cpumask __cpu_dying_mask; #define cpu_possible_mask ((const struct cpumask *)&__cpu_possible_mask) #define cpu_online_mask ((const struct cpumask *)&__cpu_online_mask) #define cpu_present_mask ((const struct cpumask *)&__cpu_present_mask) #define cpu_active_mask ((const struct cpumask *)&__cpu_active_mask) +#define cpu_dying_mask ((const struct cpumask *)&__cpu_dying_mask)
extern atomic_t __num_online_cpus;
@@ -118,6 +120,11 @@ static inline unsigned int num_online_cpus(void) #define cpu_possible(cpu) cpumask_test_cpu((cpu), cpu_possible_mask) #define cpu_present(cpu) cpumask_test_cpu((cpu), cpu_present_mask) #define cpu_active(cpu) cpumask_test_cpu((cpu), cpu_active_mask) +static inline int cpumask_test_cpu(int cpu, const struct cpumask *cpumask); +static inline bool cpu_dying(unsigned int cpu) +{ + return cpumask_test_cpu(cpu, cpu_dying_mask); +} #else #define num_online_cpus() 1U #define num_possible_cpus() 1U @@ -127,6 +134,10 @@ static inline unsigned int num_online_cpus(void) #define cpu_possible(cpu) ((cpu) == 0) #define cpu_present(cpu) ((cpu) == 0) #define cpu_active(cpu) ((cpu) == 0) +static inline bool cpu_dying(unsigned int cpu) +{ + return false; +} #endif
extern cpumask_t cpus_booted_once_mask; @@ -851,6 +862,14 @@ set_cpu_active(unsigned int cpu, bool active) cpumask_clear_cpu(cpu, &__cpu_active_mask); }
+static inline void +set_cpu_dying(unsigned int cpu, bool dying) +{ + if (dying) + cpumask_set_cpu(cpu, &__cpu_dying_mask); + else + cpumask_clear_cpu(cpu, &__cpu_dying_mask); +}
/** * to_cpumask - convert an NR_CPUS bitmap to a struct cpumask * diff --git a/kernel/cpu.c b/kernel/cpu.c index c06ced18f78a..2a81a9dae3a7 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -157,6 +157,9 @@ static int cpuhp_invoke_callback(unsigned int cpu, enum cpuhp_state state, int (*cb)(unsigned int cpu); int ret, cnt;
+ if (cpu_dying(cpu) != !bringup) + set_cpu_dying(cpu, !bringup); + if (st->fail == state) { st->fail = CPUHP_INVALID;
@@ -2502,6 +2505,9 @@ EXPORT_SYMBOL(__cpu_present_mask); struct cpumask __cpu_active_mask __read_mostly; EXPORT_SYMBOL(__cpu_active_mask);
+struct cpumask __cpu_dying_mask __read_mostly; +EXPORT_SYMBOL(__cpu_dying_mask); + atomic_t __num_online_cpus __read_mostly; EXPORT_SYMBOL(__num_online_cpus);