Commit 67d0d7fe authored by Yury Norov's avatar Yury Norov Committed by Lu Jialin
Browse files

lib/cpumask: add FORCE_NR_CPUS config option

mainline inclusion
from mainline-v6.1-rc1
commit 6f9c07be
category: cleanup
bugzilla: https://gitee.com/openeuler/kernel/issues/I8KQBZ
CVE: NA

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6f9c07be9d020489326098801f0661f754c7c865



--------------------------------

The size of cpumasks is hard-limited by compile-time parameter NR_CPUS,
but defined at boot-time when kernel parses ACPI/DT tables, and stored in
nr_cpu_ids. In many practical cases, number of CPUs for a target is known
at compile time, and can be provided with NR_CPUS.

In that case, compiler may be instructed to rely on NR_CPUS as on actual
number of CPUs, not an upper limit. It allows to optimize many cpumask
routines and significantly shrink size of the kernel image.

This patch adds FORCE_NR_CPUS option to teach the compiler to rely on
NR_CPUS and enable corresponding optimizations.

If FORCE_NR_CPUS=y, kernel will not set nr_cpu_ids at boot, but only check
that the actual number of possible CPUs is equal to NR_CPUS, and WARN if
that doesn't hold.

The new option is especially useful in embedded applications because
kernel configurations are unique for each SoC, the number of CPUs is
constant and known well, and memory limitations are typically harder.

For my 4-CPU ARM64 build with NR_CPUS=4, FORCE_NR_CPUS=y saves 46KB:
  add/remove: 3/4 grow/shrink: 46/729 up/down: 652/-46952 (-46300)

Signed-off-by: default avatarYury Norov <yury.norov@gmail.com>
Signed-off-by: default avatarZheng Zucheng <zhengzucheng@huawei.com>
parent 7808c41b
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -33,16 +33,20 @@ typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
 */
#define cpumask_pr_args(maskp)		nr_cpu_ids, cpumask_bits(maskp)

#if NR_CPUS == 1
#define nr_cpu_ids		1U
#if (NR_CPUS == 1) || defined(CONFIG_FORCE_NR_CPUS)
#define nr_cpu_ids ((unsigned int)NR_CPUS)
#else
extern unsigned int nr_cpu_ids;
#endif

static inline void set_nr_cpu_ids(unsigned int nr)
{
#if (NR_CPUS == 1) || defined(CONFIG_FORCE_NR_CPUS)
	WARN_ON(nr != nr_cpu_ids);
#else
	nr_cpu_ids = nr;
}
#endif
}

/* Deprecated. Always use nr_cpu_ids. */
#define nr_cpumask_bits	nr_cpu_ids
+1 −1
Original line number Diff line number Diff line
@@ -852,7 +852,7 @@ static int __init maxcpus(char *str)

early_param("maxcpus", maxcpus);

#if (NR_CPUS > 1)
#if (NR_CPUS > 1) && !defined(CONFIG_FORCE_NR_CPUS)
/* Setup number of possible processor ids */
unsigned int nr_cpu_ids __read_mostly = NR_CPUS;
EXPORT_SYMBOL(nr_cpu_ids);
+9 −0
Original line number Diff line number Diff line
@@ -494,6 +494,15 @@ config CPUMASK_OFFSTACK
	  them on the stack.  This is a bit more expensive, but avoids
	  stack overflow.

config FORCE_NR_CPUS
       bool "NR_CPUS is set to an actual number of CPUs"
       depends on SMP
       help
         Say Yes if you have NR_CPUS set to an actual number of possible
         CPUs in your system, not to a default value. This forces the core
         code to rely on compile-time value and optimize kernel routines
         better.

config CPU_RMAP
	bool
	depends on SMP