Fix affinity mask handling in nproc for large CPU counts
Kudos to Florian Weimer for fixing this issue in Fedora! Resolves: RHEL-54139
This commit is contained in:
parent
afd6388b5a
commit
e02e49c0ff
55
coreutils-nproc-affinity-1.patch
Normal file
55
coreutils-nproc-affinity-1.patch
Normal file
@ -0,0 +1,55 @@
|
||||
commit 45c2456a56337ebcafe0dd9faa2bd995ccbc3357
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 11 14:05:53 2024 +0100
|
||||
|
||||
nproc: Use affinity mask even on systems with more than 1024 CPUs.
|
||||
|
||||
* lib/nproc.c (num_processors_via_affinity_mask): Retry
|
||||
with larger affinity masks if CPU_ALLOC_SIZE is available.
|
||||
|
||||
diff --git a/lib/nproc.c b/lib/nproc.c
|
||||
index 92a07e8289..48bc3d06fa 100644
|
||||
--- a/lib/nproc.c
|
||||
+++ b/lib/nproc.c
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <config.h>
|
||||
#include "nproc.h"
|
||||
|
||||
+#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -124,6 +125,33 @@ num_processors_via_affinity_mask (void)
|
||||
return count;
|
||||
}
|
||||
}
|
||||
+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \
|
||||
+ && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */
|
||||
+ {
|
||||
+ unsigned int alloc_count = 1024;
|
||||
+ while (1)
|
||||
+ {
|
||||
+ cpu_set_t *set = CPU_ALLOC (alloc_count);
|
||||
+ if (set == NULL)
|
||||
+ return 0;
|
||||
+ unsigned int size = CPU_ALLOC_SIZE (alloc_count);
|
||||
+ if (sched_getaffinity (0, size, set) == 0)
|
||||
+ {
|
||||
+ unsigned int count = CPU_COUNT_S (size, set);
|
||||
+ CPU_FREE (set);
|
||||
+ return count;
|
||||
+ }
|
||||
+ if (errno != EINVAL)
|
||||
+ {
|
||||
+ CPU_FREE (set);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ CPU_FREE (set);
|
||||
+ alloc_count *= 2;
|
||||
+ if (alloc_count == 0)
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
|
||||
{
|
||||
cpu_set_t set;
|
64
coreutils-nproc-affinity-2.patch
Normal file
64
coreutils-nproc-affinity-2.patch
Normal file
@ -0,0 +1,64 @@
|
||||
commit ee0bc695303775da5026091a65e8ec2b764f4a26
|
||||
Author: Bruno Haible <bruno@clisp.org>
|
||||
Date: Mon Nov 11 15:40:52 2024 +0100
|
||||
|
||||
nproc: Use affinity mask even in out-of-memory situations.
|
||||
|
||||
* lib/nproc.c (num_processors_via_affinity_mask): Use a stack-allocated
|
||||
cpu_set_t as fallback. Add comments.
|
||||
|
||||
diff --git a/lib/nproc.c b/lib/nproc.c
|
||||
index 48bc3d06fa..0b5898d88f 100644
|
||||
--- a/lib/nproc.c
|
||||
+++ b/lib/nproc.c
|
||||
@@ -125,15 +125,25 @@ num_processors_via_affinity_mask (void)
|
||||
return count;
|
||||
}
|
||||
}
|
||||
-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC \
|
||||
- && defined CPU_ALLOC_SIZE /* glibc >= 2.6 */
|
||||
+#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
|
||||
+ /* There are two ways to use the sched_getaffinity() function:
|
||||
+ - With a statically-sized cpu_set_t.
|
||||
+ - With a dynamically-sized cpu_set_t.
|
||||
+ Documentation:
|
||||
+ <https://www.kernel.org/doc/man-pages/online/pages/man2/sched_getaffinity.2.html>
|
||||
+ <https://www.kernel.org/doc/man-pages/online/pages/man3/CPU_SET.3.html>
|
||||
+ The second way has the advantage that it works on systems with more than
|
||||
+ 1024 CPUs. The first way has the advantage that it works also when memory
|
||||
+ is tight. */
|
||||
+# if defined CPU_ALLOC_SIZE /* glibc >= 2.6 */
|
||||
{
|
||||
unsigned int alloc_count = 1024;
|
||||
- while (1)
|
||||
+ for (;;)
|
||||
{
|
||||
cpu_set_t *set = CPU_ALLOC (alloc_count);
|
||||
if (set == NULL)
|
||||
- return 0;
|
||||
+ /* Out of memory. */
|
||||
+ break;
|
||||
unsigned int size = CPU_ALLOC_SIZE (alloc_count);
|
||||
if (sched_getaffinity (0, size, set) == 0)
|
||||
{
|
||||
@@ -143,16 +153,19 @@ num_processors_via_affinity_mask (void)
|
||||
}
|
||||
if (errno != EINVAL)
|
||||
{
|
||||
+ /* Some other error. */
|
||||
CPU_FREE (set);
|
||||
return 0;
|
||||
}
|
||||
CPU_FREE (set);
|
||||
+ /* Retry with some larger cpu_set_t. */
|
||||
alloc_count *= 2;
|
||||
if (alloc_count == 0)
|
||||
+ /* Integer overflow. Avoid an endless loop. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
-#elif HAVE_SCHED_GETAFFINITY_LIKE_GLIBC /* glibc >= 2.3.4 */
|
||||
+# endif
|
||||
{
|
||||
cpu_set_t set;
|
||||
|
@ -1,7 +1,7 @@
|
||||
Summary: A set of basic GNU tools commonly used in shell scripts
|
||||
Name: coreutils
|
||||
Version: 8.32
|
||||
Release: 37%{?dist}
|
||||
Release: 38%{?dist}
|
||||
License: GPLv3+
|
||||
Url: https://www.gnu.org/software/coreutils/
|
||||
Source0: https://ftp.gnu.org/gnu/%{name}/%{name}-%{version}.tar.xz
|
||||
@ -76,6 +76,11 @@ Patch20: coreutils-8.32-tail-64kpages.patch
|
||||
# fix extended upstream test suite failures (RHEL-60290)
|
||||
Patch21: coreutils-8.32-fix-extended-testsuite.patch
|
||||
|
||||
# Fix affinity mask handling in nproc for large CPU counts (RHEL-54139)
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2325167
|
||||
Patch22: coreutils-nproc-affinity-1.patch
|
||||
Patch23: coreutils-nproc-affinity-2.patch
|
||||
|
||||
# disable the test-lock gnulib test prone to deadlock
|
||||
Patch100: coreutils-8.26-test-lock.patch
|
||||
|
||||
@ -325,7 +330,10 @@ rm -f $RPM_BUILD_ROOT%{_infodir}/dir
|
||||
%license COPYING
|
||||
|
||||
%changelog
|
||||
* Tue Oct 22 2024 Lukáš Zaoral <lzaoral@redhat.com>
|
||||
* Tue Nov 26 2024 Lukáš Zaoral <lzaoral@redhat.com> - 8.32-38
|
||||
- fix affinity mask handling in nproc for large CPU counts (RHEL-54139)
|
||||
|
||||
* Tue Oct 22 2024 Lukáš Zaoral <lzaoral@redhat.com> - 8.32-37
|
||||
- fix extended upstream test suite failures (RHEL-60290)
|
||||
|
||||
* Fri Aug 16 2024 Lukáš Zaoral <lzaoral@redhat.com> - 8.32-36
|
||||
|
Loading…
Reference in New Issue
Block a user