[LTP] [PATCH] tst_ncpus_max: use kernel_max if available

Jan Stancek
2014-08-26T10:01:09Z

sched_getaffinity() and sched_setaffinity() cares about number of possible
CPUs the OS or hardware can support, which can be larger than what
sysconf(_SC_NPROCESSORS_CONF) currently provides (by enumarating
/sys/devices/system/cpu/cpu* entries).

Use /sys/devices/system/cpu/kernel_max, if available. This represents
NR_CPUS-1, a compile time option which specifies "maximum number of CPUs
which this kernel will support". This should give us cpu mask size
large enough for any purposes.

If the kernel_max sysfs file is not available, fall back to
_SC_NPROCESSORS_CONF.

Signed-off-by: Jan Stancek <jstancek@redhat.com>
---
lib/tst_cpu.c | 26 ++++++++++++++++++++++++--
1 files changed, 24 insertions(+), 2 deletions(-)

Tested on system supporting CPU hotplug:
NR_CPUS:4096 nr_cpumask_bits:144 nr_cpu_ids:144 nr_node_ids:1

# cat /sys/devices/system/cpu/online
0-15
# cat /sys/devices/system/cpu/offline
16-143
# cat /sys/devices/system/cpu/possible
0-143
# cat /sys/devices/system/cpu/kernel_max
4095

diff --git a/lib/tst_cpu.c b/lib/tst_cpu.c
index e8ab34e..b492dc2 100644
--- a/lib/tst_cpu.c
+++ b/lib/tst_cpu.c
@@ -33,13 +33,35 @@ long tst_ncpus(void)
return ncpus;
}

+#define KERNEL_MAX "/sys/devices/system/cpu/kernel_max"
+
long tst_ncpus_max(void)
{
long ncpus_max = -1;
+ struct stat buf;
+
+ /* sched_getaffinity() and sched_setaffinity() cares about number of
+ * possible CPUs the OS or hardware can support, which can be larger
+ * than what sysconf(_SC_NPROCESSORS_CONF) currently provides
+ * (by enumarating /sys/devices/system/cpu/cpu* entries).
+ *
+ * Use /sys/devices/system/cpu/kernel_max, if available. This
+ * represents NR_CPUS-1, a compile time option which specifies
+ * "maximum number of CPUs which this kernel will support".
+ * This should provide cpu mask size large enough for any purposes. */
+ if (stat(KERNEL_MAX, &buf) == 0) {
+ SAFE_FILE_SCANF(NULL, KERNEL_MAX, "%ld", &ncpus_max);
+ /* this is maximum CPU index allowed by the kernel
+ * configuration, so # of cpus allowed by config is +1 */
+ ncpus_max++;
+ } else {
+ /* fall back to _SC_NPROCESSORS_CONF */
#ifdef _SC_NPROCESSORS_CONF
- ncpus_max = SAFE_SYSCONF(NULL, _SC_NPROCESSORS_CONF);
+ ncpus_max = SAFE_SYSCONF(NULL, _SC_NPROCESSORS_CONF);
#else
- tst_brkm(TBROK, NULL, "could not determine number of CPUs configured");
+ tst_brkm(TBROK, NULL, "could not determine number of CPUs"
+ " configured");
#endif
+ }
return ncpus_max;
}
--
1.7.1