linux: fix accurarcy of get_nprocs and get_nprocs_conf [BZ #28865]
This commit is contained in:
parent
089a28fab1
commit
0e1ffabe6f
@ -66,7 +66,7 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
Name: glibc
|
Name: glibc
|
||||||
Version: 2.34
|
Version: 2.34
|
||||||
Release: 54
|
Release: 55
|
||||||
Summary: The GNU libc libraries
|
Summary: The GNU libc libraries
|
||||||
License: %{all_license}
|
License: %{all_license}
|
||||||
URL: http://www.gnu.org/software/glibc/
|
URL: http://www.gnu.org/software/glibc/
|
||||||
@ -189,6 +189,7 @@ Patch101: Linux-Only-generate-64-bit-timestamps-for-64-bit-tim.patch
|
|||||||
Patch102: socket-Do-not-use-AF_NETLINK-in-__opensock.patch
|
Patch102: socket-Do-not-use-AF_NETLINK-in-__opensock.patch
|
||||||
Patch103: tst-socket-timestamp-compat.c-Check-__TIMESIZE-BZ-28.patch
|
Patch103: tst-socket-timestamp-compat.c-Check-__TIMESIZE-BZ-28.patch
|
||||||
Patch104: linux-Fix-missing-__convert_scm_timestamps-BZ-28860.patch
|
Patch104: linux-Fix-missing-__convert_scm_timestamps-BZ-28860.patch
|
||||||
|
Patch105: linux-fix-accuracy-of-get_nprocs-and-get_nprocs_conf.patch
|
||||||
|
|
||||||
Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
|
Patch9000: turn-default-value-of-x86_rep_stosb_threshold_form_2K_to_1M.patch
|
||||||
Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch
|
Patch9001: delete-no-hard-link-to-avoid-all_language-package-to.patch
|
||||||
@ -1292,6 +1293,9 @@ fi
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Feb 9 2022 Qingqing Li <liqingqing3@huawei.com> - 2.34-55
|
||||||
|
- linux: fix accurarcy of get_nprocs and get_nprocs_conf [BZ #28865]
|
||||||
|
|
||||||
* Tue Feb 8 2022 Yang Yanchao <yangyanchao6@huawei.com> - 2.34-54
|
* Tue Feb 8 2022 Yang Yanchao <yangyanchao6@huawei.com> - 2.34-54
|
||||||
- disable rt/tst-cpuclock2 which often fails in CI.
|
- disable rt/tst-cpuclock2 which often fails in CI.
|
||||||
|
|
||||||
|
|||||||
212
linux-fix-accuracy-of-get_nprocs-and-get_nprocs_conf.patch
Normal file
212
linux-fix-accuracy-of-get_nprocs-and-get_nprocs_conf.patch
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
From 007e054d786be340699c634e3a3b30ab1fde1a7a Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Dmitry V. Levin" <ldv@altlinux.org>
|
||||||
|
Date: Sat, 5 Feb 2022 08:00:00 +0000
|
||||||
|
Subject: [PATCH] linux: fix accuracy of get_nprocs and get_nprocs_conf [BZ
|
||||||
|
#28865]
|
||||||
|
|
||||||
|
get_nprocs() and get_nprocs_conf() use various methods to obtain an
|
||||||
|
accurate number of processors. Re-introduce __get_nprocs_sched() as
|
||||||
|
a source of information, and fix the order in which these methods are
|
||||||
|
used to return the most accurate information. The primary source of
|
||||||
|
information used in both functions remains unchanged.
|
||||||
|
|
||||||
|
This also changes __get_nprocs_sched() error return value from 2 to 0,
|
||||||
|
but all its users are already prepared to handle that.
|
||||||
|
|
||||||
|
Old fallback order:
|
||||||
|
get_nprocs:
|
||||||
|
/sys/devices/system/cpu/online -> /proc/stat -> 2
|
||||||
|
get_nprocs_conf:
|
||||||
|
/sys/devices/system/cpu/ -> /proc/stat -> 2
|
||||||
|
|
||||||
|
New fallback order:
|
||||||
|
get_nprocs:
|
||||||
|
/sys/devices/system/cpu/online -> /proc/stat -> sched_getaffinity -> 2
|
||||||
|
get_nprocs_conf:
|
||||||
|
/sys/devices/system/cpu/ -> /proc/stat -> sched_getaffinity -> 2
|
||||||
|
|
||||||
|
Fixes: 342298278e ("linux: Revert the use of sched_getaffinity on get_nproc")
|
||||||
|
Closes: BZ #28865
|
||||||
|
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
(cherry picked from commit e1d32b836410767270a3adf1f82b1a47e6e4cd51)
|
||||||
|
---
|
||||||
|
NEWS | 2 +
|
||||||
|
sysdeps/unix/sysv/linux/getsysstats.c | 94 ++++++++++++++++++---------
|
||||||
|
2 files changed, 65 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/NEWS b/NEWS
|
||||||
|
index 87c9517e1a..aef051122e 100644
|
||||||
|
--- a/NEWS
|
||||||
|
+++ b/NEWS
|
||||||
|
@@ -29,6 +29,8 @@ The following bugs are resolved with this release:
|
||||||
|
[28349] libc: Segfault for ping -R on qemux86 caused by recvmsg()
|
||||||
|
[28350] libc: ping receives SIGABRT on lib32-qemux86-64 caused by
|
||||||
|
recvmsg()
|
||||||
|
+ [28865] linux: _SC_NPROCESSORS_CONF and _SC_NPROCESSORS_ONLN are inaccurate
|
||||||
|
+ without /sys and /proc
|
||||||
|
|
||||||
|
|
||||||
|
Version 2.34
|
||||||
|
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
|
||||||
|
index 7babd947aa..327802b14c 100644
|
||||||
|
--- a/sysdeps/unix/sysv/linux/getsysstats.c
|
||||||
|
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
|
||||||
|
@@ -51,9 +51,8 @@ __get_nprocs_sched (void)
|
||||||
|
is an arbitrary values assuming such systems should be rare and there
|
||||||
|
is no offline cpus. */
|
||||||
|
return max_num_cpus;
|
||||||
|
- /* Some other error. 2 is conservative (not a uniprocessor system, so
|
||||||
|
- atomics are needed). */
|
||||||
|
- return 2;
|
||||||
|
+ /* Some other error. */
|
||||||
|
+ return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
@@ -109,22 +108,19 @@ next_line (int fd, char *const buffer, char **cp, char **re,
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-get_nproc_stat (char *buffer, size_t buffer_size)
|
||||||
|
+get_nproc_stat (void)
|
||||||
|
{
|
||||||
|
+ enum { buffer_size = 1024 };
|
||||||
|
+ char buffer[buffer_size];
|
||||||
|
char *buffer_end = buffer + buffer_size;
|
||||||
|
char *cp = buffer_end;
|
||||||
|
char *re = buffer_end;
|
||||||
|
-
|
||||||
|
- /* Default to an SMP system in case we cannot obtain an accurate
|
||||||
|
- number. */
|
||||||
|
- int result = 2;
|
||||||
|
+ int result = 0;
|
||||||
|
|
||||||
|
const int flags = O_RDONLY | O_CLOEXEC;
|
||||||
|
int fd = __open_nocancel ("/proc/stat", flags);
|
||||||
|
if (fd != -1)
|
||||||
|
{
|
||||||
|
- result = 0;
|
||||||
|
-
|
||||||
|
char *l;
|
||||||
|
while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL)
|
||||||
|
/* The current format of /proc/stat has all the cpu* entries
|
||||||
|
@@ -140,8 +136,8 @@ get_nproc_stat (char *buffer, size_t buffer_size)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int
|
||||||
|
-__get_nprocs (void)
|
||||||
|
+static int
|
||||||
|
+get_nprocs_cpu_online (void)
|
||||||
|
{
|
||||||
|
enum { buffer_size = 1024 };
|
||||||
|
char buffer[buffer_size];
|
||||||
|
@@ -180,7 +176,8 @@ __get_nprocs (void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- result += m - n + 1;
|
||||||
|
+ if (m >= n)
|
||||||
|
+ result += m - n + 1;
|
||||||
|
|
||||||
|
l = endp;
|
||||||
|
if (l < re && *l == ',')
|
||||||
|
@@ -189,28 +186,18 @@ __get_nprocs (void)
|
||||||
|
while (l < re && *l != '\n');
|
||||||
|
|
||||||
|
__close_nocancel_nostatus (fd);
|
||||||
|
-
|
||||||
|
- if (result > 0)
|
||||||
|
- return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return get_nproc_stat (buffer, buffer_size);
|
||||||
|
+ return result;
|
||||||
|
}
|
||||||
|
-libc_hidden_def (__get_nprocs)
|
||||||
|
-weak_alias (__get_nprocs, get_nprocs)
|
||||||
|
-
|
||||||
|
|
||||||
|
-/* On some architectures it is possible to distinguish between configured
|
||||||
|
- and active cpus. */
|
||||||
|
-int
|
||||||
|
-__get_nprocs_conf (void)
|
||||||
|
+static int
|
||||||
|
+get_nprocs_cpu (void)
|
||||||
|
{
|
||||||
|
- /* Try to use the sysfs filesystem. It has actual information about
|
||||||
|
- online processors. */
|
||||||
|
+ int count = 0;
|
||||||
|
DIR *dir = __opendir ("/sys/devices/system/cpu");
|
||||||
|
if (dir != NULL)
|
||||||
|
{
|
||||||
|
- int count = 0;
|
||||||
|
struct dirent64 *d;
|
||||||
|
|
||||||
|
while ((d = __readdir64 (dir)) != NULL)
|
||||||
|
@@ -225,12 +212,57 @@ __get_nprocs_conf (void)
|
||||||
|
|
||||||
|
__closedir (dir);
|
||||||
|
|
||||||
|
- return count;
|
||||||
|
}
|
||||||
|
+ return count;
|
||||||
|
+}
|
||||||
|
|
||||||
|
- enum { buffer_size = 1024 };
|
||||||
|
- char buffer[buffer_size];
|
||||||
|
- return get_nproc_stat (buffer, buffer_size);
|
||||||
|
+static int
|
||||||
|
+get_nprocs_fallback (void)
|
||||||
|
+{
|
||||||
|
+ int result;
|
||||||
|
+
|
||||||
|
+ /* Try /proc/stat first. */
|
||||||
|
+ result = get_nproc_stat ();
|
||||||
|
+ if (result != 0)
|
||||||
|
+ return result;
|
||||||
|
+
|
||||||
|
+ /* Try sched_getaffinity. */
|
||||||
|
+ result = __get_nprocs_sched ();
|
||||||
|
+ if (result != 0)
|
||||||
|
+ return result;
|
||||||
|
+
|
||||||
|
+ /* We failed to obtain an accurate number. Be conservative: return
|
||||||
|
+ the smallest number meaning that this is not a uniprocessor system,
|
||||||
|
+ so atomics are needed. */
|
||||||
|
+ return 2;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int
|
||||||
|
+__get_nprocs (void)
|
||||||
|
+{
|
||||||
|
+ /* Try /sys/devices/system/cpu/online first. */
|
||||||
|
+ int result = get_nprocs_cpu_online ();
|
||||||
|
+ if (result != 0)
|
||||||
|
+ return result;
|
||||||
|
+
|
||||||
|
+ /* Fall back to /proc/stat and sched_getaffinity. */
|
||||||
|
+ return get_nprocs_fallback ();
|
||||||
|
+}
|
||||||
|
+libc_hidden_def (__get_nprocs)
|
||||||
|
+weak_alias (__get_nprocs, get_nprocs)
|
||||||
|
+
|
||||||
|
+/* On some architectures it is possible to distinguish between configured
|
||||||
|
+ and active cpus. */
|
||||||
|
+int
|
||||||
|
+__get_nprocs_conf (void)
|
||||||
|
+{
|
||||||
|
+ /* Try /sys/devices/system/cpu/ first. */
|
||||||
|
+ int result = get_nprocs_cpu ();
|
||||||
|
+ if (result != 0)
|
||||||
|
+ return result;
|
||||||
|
+
|
||||||
|
+ /* Fall back to /proc/stat and sched_getaffinity. */
|
||||||
|
+ return get_nprocs_fallback ();
|
||||||
|
}
|
||||||
|
libc_hidden_def (__get_nprocs_conf)
|
||||||
|
weak_alias (__get_nprocs_conf, get_nprocs_conf)
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user