forked from bottlerocket-os/bottlerocket
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0006-linux-fix-accuracy-of-get_nprocs-and-get_nprocs_conf.patch
212 lines (189 loc) · 5.73 KB
/
0006-linux-fix-accuracy-of-get_nprocs-and-get_nprocs_conf.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
From 491f2ef1f0ff849490f374917957018d07ee0586 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 06/28] 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 6b8db4e947..04df0f4e8a 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,8 @@ The following bugs are resolved with this release:
(breaks test isolation)
[28860] build: --enable-kernel=5.1.0 build fails because of missing
__convert_scm_timestamps
+ [28865] linux: _SC_NPROCESSORS_CONF and _SC_NPROCESSORS_ONLN are inaccurate
+ without /sys and /proc
Version 2.35
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index c98c8ce3d4..d1ea074f0d 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -50,9 +50,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 *
@@ -108,22 +107,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
@@ -139,8 +135,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];
@@ -179,7 +175,8 @@ __get_nprocs (void)
}
}
- result += m - n + 1;
+ if (m >= n)
+ result += m - n + 1;
l = endp;
if (l < re && *l == ',')
@@ -188,28 +185,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)
@@ -224,12 +211,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.33.1