lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Sun, 25 May 2014 18:31:16 +0400
From:	Konstantin Khlebnikov <koct9i@...il.com>
To:	linux-kernel@...r.kernel.org
Cc:	Ulrich Drepper <drepper@...il.com>,
	Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Subject: [PATCH RFC] sysfs/cpu: add attributes for count of cpus and last
 cpu index

Surprisingly there is no straight way to get number of processors.
Sysfs attributes /sys/devices/system/cpu/online, "present" and "possible"
shows cpus bitmap as comma-separated list of numbers and ranges. This format
is human-freindly but it's hard to parse and unusable for scripts.

This patchs adds new attributes into /sys/devices/system/cpu/
nr_online, nr_present, nr_possible, last_online, last_present, last_possible.

nr_* shows count of cpus as plain decimal number.
last_* shows highest index, it might not equal to NR-1 if bitmap is sparse.
This might be useful for preallocating arrays for ranges of cpu indexes.

Signed-off-by: Konstantin Khlebnikov <koct9i@...il.com>

---

Currently GNU C Library does weird things in the implementation of get_nprocs()
and get_nprocs_conf() (sysconf(_SC_NPROCESSORS_ONLN / _SC_NPROCESSORS_CONF)).

get_nprocs() parses "/sys/devices/system/cpu/online", counts lines started with
"cpu" in "/proc/stat" and even parses "/proc/cpuinfo".
And because all this is expensive it caches result for one second.

get_nprocs_conf() counts subdirs in /sys/devices/system/cpu named "cpu*"
It also parses "/proc/cpuinfo" on alpha and sparc. This function returns
count of present CPUs, probably it should return number of possible CPUs
otherwise userspace isn't able to handle cpu-hotplug.
This should be common situation for virtual-machines like XEN or KVM.

If nothing works well both functions return 1. They cannot report error.

For example hotspot JVM uses sysconf(_SC_NPROCESSORS_CONF) to detect
UP machine where it can drop 'lock' prefix in atomic operations.
If sysfs and proc aren't available it crashes or hangs inside GC =)
[ http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/os/linux/vm/os_linux.cpp#l291 ]

Other user which I've found is userspace-RCU. It uses per-cpu arrays indexed by
getcpu() and uses sysconf(_SC_NPROCESSORS_CONF) - 1 as last possible cpu.
So this doesn't work for sparse bitmap, also I'm not sure about cpu-hotplug.
---
 Documentation/ABI/testing/sysfs-devices-system-cpu |   17 +++++++++
 drivers/base/cpu.c                                 |   37 +++++++++++++++++++-
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu
index d5a0d33..e05edb7 100644
--- a/Documentation/ABI/testing/sysfs-devices-system-cpu
+++ b/Documentation/ABI/testing/sysfs-devices-system-cpu
@@ -37,6 +37,23 @@ Description:	CPU topology files that describe kernel limits related to
 		See Documentation/cputopology.txt for more information.
 
 
+What:		/sys/devices/system/cpu/nr_online
+		/sys/devices/system/cpu/nr_present
+		/sys/devices/system/cpu/nr_possible
+		/sys/devices/system/cpu/last_online
+		/sys/devices/system/cpu/last_present
+		/sys/devices/system/cpu/last_possible
+Date:		May 2014
+Contact:	Linux kernel mailing list <linux-kernel@...r.kernel.org>
+Description:	Number and last index of processors in the system
+
+		nr_{online,possible,present}: count of cpus
+
+		last_{online,possible,present}: highest cpu index
+
+		See also /sys/devices/system/cpu/{online,possible,present} above
+
+
 What:		/sys/devices/system/cpu/probe
 		/sys/devices/system/cpu/release
 Date:		November 2009
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 006b1bc..1ca73c7 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -214,14 +214,43 @@ static ssize_t show_cpus_attr(struct device *dev,
 	return n;
 }
 
+static ssize_t show_nr_cpus_attr(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", cpumask_weight(*ca->map));
+}
+
+static ssize_t show_last_cpus_attr(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
+	unsigned last_cpu = find_last_bit(cpumask_bits(*ca->map), NR_CPUS);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", last_cpu);
+}
+
 #define _CPU_ATTR(name, map) \
 	{ __ATTR(name, 0444, show_cpus_attr, NULL), map }
 
-/* Keep in sync with cpu_subsys_attrs */
+#define _NR_CPU_ATTR(name, map) \
+	{ __ATTR(name, 0444, show_nr_cpus_attr, NULL), map }
+
+#define _LAST_CPU_ATTR(name, map) \
+	{ __ATTR(name, 0444, show_last_cpus_attr, NULL), map }
+
+/* Keep in sync with cpu_root_attrs */
 static struct cpu_attr cpu_attrs[] = {
 	_CPU_ATTR(online, &cpu_online_mask),
 	_CPU_ATTR(possible, &cpu_possible_mask),
 	_CPU_ATTR(present, &cpu_present_mask),
+	_NR_CPU_ATTR(nr_online, &cpu_online_mask),
+	_NR_CPU_ATTR(nr_possible, &cpu_possible_mask),
+	_NR_CPU_ATTR(nr_present, &cpu_present_mask),
+	_LAST_CPU_ATTR(last_online, &cpu_online_mask),
+	_LAST_CPU_ATTR(last_possible, &cpu_possible_mask),
+	_LAST_CPU_ATTR(last_present, &cpu_present_mask),
 };
 
 /*
@@ -378,6 +407,12 @@ static struct attribute *cpu_root_attrs[] = {
 	&cpu_attrs[0].attr.attr,
 	&cpu_attrs[1].attr.attr,
 	&cpu_attrs[2].attr.attr,
+	&cpu_attrs[3].attr.attr,
+	&cpu_attrs[4].attr.attr,
+	&cpu_attrs[5].attr.attr,
+	&cpu_attrs[6].attr.attr,
+	&cpu_attrs[7].attr.attr,
+	&cpu_attrs[8].attr.attr,
 	&dev_attr_kernel_max.attr,
 	&dev_attr_offline.attr,
 #ifdef CONFIG_GENERIC_CPU_AUTOPROBE

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ