diff mbox series

linux: Use /sys/devices/system/cpu on __get_nprocs_conf (BZ#28991)

Message ID 20220323203835.3653589-1-adhemerval.zanella@linaro.org
State New
Headers show
Series linux: Use /sys/devices/system/cpu on __get_nprocs_conf (BZ#28991) | expand

Commit Message

Adhemerval Zanella Netto March 23, 2022, 8:38 p.m. UTC
Currently on Linux __get_nprocs_conf first tries to enumerate the
cpus present in the system by iterating on /sys/devices/system/cpuX
directories.  This only enumerates the CPUs that are present in
system (but possibly offline), not taking in account possible CPU
that might added in the system through hotplugging.

Linux provides the maximum number of configured cpus on the
/sys/devices/system/cpu file.  Although it might present a larger
value of possible active CPUs on some system (where kernel either
get the information from firmaware or is configured at boot time),
the information is what kernel presents to userland.

This also change the returned value of _SC_NPROCESSORS_CONF, which
aligns as the maximum configure cpu in the system.

Checked on x86_64-linux-gnu.
---
 sysdeps/unix/sysv/linux/getsysstats.c | 36 +++------------------------
 1 file changed, 4 insertions(+), 32 deletions(-)

Comments

Florian Weimer May 16, 2022, 11:42 a.m. UTC | #1
* Adhemerval Zanella via Libc-alpha:

> @@ -239,8 +213,7 @@ get_nprocs_fallback (void)
>  int
>  __get_nprocs (void)
>  {
> -  /* Try /sys/devices/system/cpu/online first.  */
> -  int result = get_nprocs_cpu_online ();
> +  int result = read_sysfs_file ("/sys/devices/system/cpu/online");
>    if (result != 0)
>      return result;
>  
> @@ -255,8 +228,7 @@ weak_alias (__get_nprocs, get_nprocs)
>  int
>  __get_nprocs_conf (void)
>  {
> -  /* Try /sys/devices/system/cpu/ first.  */
> -  int result = get_nprocs_cpu ();
> +  int result = read_sysfs_file ("/sys/devices/system/cpu/possible");
>    if (result != 0)
>      return result;

I reviewed the kernel documentation and a tiny part of the kernel
sources, and I think this change is okay.

Reviewed-by: Florian Weimer <fweimer@redhat.com>

(It still does not give you the maximum CPU *index*, but that's okay.)

Thanks,
Florian
diff mbox series

Patch

diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index d1ea074f0d..064eaa08ae 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -19,7 +19,6 @@ 
 #include <array_length.h>
 #include <assert.h>
 #include <ctype.h>
-#include <dirent.h>
 #include <errno.h>
 #include <ldsodefs.h>
 #include <limits.h>
@@ -136,7 +135,7 @@  get_nproc_stat (void)
 }
 
 static int
-get_nprocs_cpu_online (void)
+read_sysfs_file (const char *fname)
 {
   enum { buffer_size = 1024 };
   char buffer[buffer_size];
@@ -146,7 +145,7 @@  get_nprocs_cpu_online (void)
 
   const int flags = O_RDONLY | O_CLOEXEC;
   /* This file contains comma-separated ranges.  */
-  int fd = __open_nocancel ("/sys/devices/system/cpu/online", flags);
+  int fd = __open_nocancel (fname, flags);
   char *l;
   int result = 0;
   if (fd != -1)
@@ -190,31 +189,6 @@  get_nprocs_cpu_online (void)
   return result;
 }
 
-static int
-get_nprocs_cpu (void)
-{
-  int count = 0;
-  DIR *dir = __opendir ("/sys/devices/system/cpu");
-  if (dir != NULL)
-    {
-      struct dirent64 *d;
-
-      while ((d = __readdir64 (dir)) != NULL)
-	/* NB: the sysfs has d_type support.  */
-	if (d->d_type == DT_DIR && strncmp (d->d_name, "cpu", 3) == 0)
-	  {
-	    char *endp;
-	    unsigned long int nr = strtoul (d->d_name + 3, &endp, 10);
-	    if (nr != ULONG_MAX && endp != d->d_name + 3 && *endp == '\0')
-	      ++count;
-	  }
-
-      __closedir (dir);
-
-    }
-  return count;
-}
-
 static int
 get_nprocs_fallback (void)
 {
@@ -239,8 +213,7 @@  get_nprocs_fallback (void)
 int
 __get_nprocs (void)
 {
-  /* Try /sys/devices/system/cpu/online first.  */
-  int result = get_nprocs_cpu_online ();
+  int result = read_sysfs_file ("/sys/devices/system/cpu/online");
   if (result != 0)
     return result;
 
@@ -255,8 +228,7 @@  weak_alias (__get_nprocs, get_nprocs)
 int
 __get_nprocs_conf (void)
 {
-  /* Try /sys/devices/system/cpu/ first.  */
-  int result = get_nprocs_cpu ();
+  int result = read_sysfs_file ("/sys/devices/system/cpu/possible");
   if (result != 0)
     return result;