[PATCH 14/17] kernel/cpu: add num_present_cpu counter
From: Yury Norov <yury.norov@gmail.com>
Date: 2021-12-18 21:22:34
Also in:
kvm, linux-crypto, linux-mips, linux-mm, linux-perf-users, linux-riscv, linux-s390, lkml
Subsystem:
bitmap api, cpu hotplug, the rest · Maintainers:
Yury Norov, Thomas Gleixner, Peter Zijlstra, Linus Torvalds
Similarly to the online cpus, the cpu_present_mask is actively used in the kernel. This patch adds a counter for present cpus, so that users that call num_present_cpus() would know the result immediately, instead of calling the bitmap_weight for the mask. Suggested-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Yury Norov <yury.norov@gmail.com> --- include/linux/cpumask.h | 25 +++++++++++++++---------- kernel/cpu.c | 16 ++++++++++++++++ 2 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 0be2504d8e4c..c2a9d15e2cbd 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h@@ -100,6 +100,7 @@ extern struct cpumask __cpu_dying_mask; extern atomic_t __num_online_cpus; extern atomic_t __num_possible_cpus; +extern atomic_t __num_present_cpus; extern cpumask_t cpus_booted_once_mask;
@@ -873,15 +874,7 @@ void init_cpu_online(const struct cpumask *src); void set_cpu_possible(unsigned int cpu, bool possible); void reset_cpu_possible_mask(void); - -static inline void -set_cpu_present(unsigned int cpu, bool present) -{ - if (present) - cpumask_set_cpu(cpu, &__cpu_present_mask); - else - cpumask_clear_cpu(cpu, &__cpu_present_mask); -} +void set_cpu_present(unsigned int cpu, bool present); void set_cpu_online(unsigned int cpu, bool online);
@@ -965,7 +958,19 @@ static inline unsigned int num_possible_cpus(void) { return atomic_read(&__num_possible_cpus); } -#define num_present_cpus() cpumask_weight(cpu_present_mask) + +/** + * num_present_cpus() - Read the number of present CPUs + * + * Despite the fact that __num_present_cpus is of type atomic_t, this + * interface gives only a momentary snapshot and is not protected against + * concurrent CPU hotplug operations unless invoked from a cpuhp_lock held + * region. + */ +static inline unsigned int num_present_cpus(void) +{ + return atomic_read(&__num_present_cpus); +} #define num_active_cpus() cpumask_weight(cpu_active_mask) static inline bool cpu_online(unsigned int cpu)
diff --git a/kernel/cpu.c b/kernel/cpu.c
index a0a815911173..1f7ea1bdde1a 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c@@ -2597,6 +2597,9 @@ EXPORT_SYMBOL(__cpu_online_mask); struct cpumask __cpu_present_mask __read_mostly; EXPORT_SYMBOL(__cpu_present_mask); +atomic_t __num_present_cpus __read_mostly; +EXPORT_SYMBOL(__num_present_cpus); + struct cpumask __cpu_active_mask __read_mostly; EXPORT_SYMBOL(__cpu_active_mask);
@@ -2609,6 +2612,7 @@ EXPORT_SYMBOL(__num_online_cpus); void init_cpu_present(const struct cpumask *src) { cpumask_copy(&__cpu_present_mask, src); + atomic_set(&__num_present_cpus, cpumask_weight(cpu_present_mask)); } void init_cpu_possible(const struct cpumask *src)
@@ -2662,6 +2666,18 @@ void set_cpu_possible(unsigned int cpu, bool possible) } EXPORT_SYMBOL(set_cpu_possible); +void set_cpu_present(unsigned int cpu, bool present) +{ + if (present) { + if (!cpumask_test_and_set_cpu(cpu, &__cpu_present_mask)) + atomic_inc(&__num_present_cpus); + } else { + if (cpumask_test_and_clear_cpu(cpu, &__cpu_present_mask)) + atomic_dec(&__num_present_cpus); + } +} +EXPORT_SYMBOL(set_cpu_present); + /* * Activate the first processor. */
--
2.30.2