Bug Summary

File:build-scan/../src/basic/cpu-set-util.c
Warning:line 442, column 32
Potential leak of memory pointed to by 's.set'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name cpu-set-util.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/basic/libbasic.a.p -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -I /usr/include/blkid -I /usr/include/libmount -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility default -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/basic/cpu-set-util.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2/***
3 Copyright © 2015 Filipe Brandenburger
4***/
5
6#include <errno(*__errno_location ()).h>
7#include <stddef.h>
8#include <stdio.h>
9#include <syslog.h>
10
11#include "alloc-util.h"
12#include "cpu-set-util.h"
13#include "dirent-util.h"
14#include "extract-word.h"
15#include "fileio.h"
16#include "fd-util.h"
17#include "log.h"
18#include "macro.h"
19#include "missing.h"
20#include "parse-util.h"
21#include "stat-util.h"
22#include "stdio-util.h"
23#include "string-util.h"
24#include "string-table.h"
25#include "strv.h"
26#include "util.h"
27
28char* cpu_set_to_string(const CPUSet *a) {
29 _cleanup_free___attribute__((cleanup(freep))) char *str = NULL((void*)0);
30 size_t allocated = 0, len = 0;
31 int i, r;
32
33 for (i = 0; (size_t) i < a->allocated * 8; i++) {
34 if (!CPU_ISSET_S(i, a->allocated, a->set)(__extension__ ({ size_t __cpu = (i); __cpu / 8 < (a->allocated
) ? ((((const __cpu_mask *) ((a->set)->__bits))[((__cpu
) / (8 * sizeof (__cpu_mask)))] & ((__cpu_mask) 1 <<
((__cpu) % (8 * sizeof (__cpu_mask)))))) != 0 : 0; }))
)
35 continue;
36
37 if (!GREEDY_REALLOC(str, allocated, len + 1 + DECIMAL_STR_MAX(int))greedy_realloc((void**) &(str), &(allocated), (len + 1
+ (2+(sizeof(int) <= 1 ? 3 : sizeof(int) <= 2 ? 5 : sizeof
(int) <= 4 ? 10 : sizeof(int) <= 8 ? 20 : sizeof(int[-2
*(sizeof(int) > 8)])))), sizeof((str)[0]))
)
38 return NULL((void*)0);
39
40 r = sprintf(str + len, len > 0 ? " %d" : "%d", i);
41 assert_se(r > 0)do { if ((__builtin_expect(!!(!(r > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("r > 0"), "../src/basic/cpu-set-util.c"
, 41, __PRETTY_FUNCTION__); } while (0)
;
42 len += r;
43 }
44
45 return TAKE_PTR(str)({ typeof(str) _ptr_ = (str); (str) = ((void*)0); _ptr_; }) ?: strdup("");
46}
47
48char *cpu_set_to_range_string(const CPUSet *set) {
49 unsigned range_start = 0, range_end;
50 _cleanup_free___attribute__((cleanup(freep))) char *str = NULL((void*)0);
51 size_t allocated = 0, len = 0;
52 bool_Bool in_range = false0;
53 int r;
54
55 for (unsigned i = 0; i < set->allocated * 8; i++)
56 if (CPU_ISSET_S(i, set->allocated, set->set)(__extension__ ({ size_t __cpu = (i); __cpu / 8 < (set->
allocated) ? ((((const __cpu_mask *) ((set->set)->__bits
))[((__cpu) / (8 * sizeof (__cpu_mask)))] & ((__cpu_mask)
1 << ((__cpu) % (8 * sizeof (__cpu_mask)))))) != 0 : 0
; }))
) {
57 if (in_range)
58 range_end++;
59 else {
60 range_start = range_end = i;
61 in_range = true1;
62 }
63 } else if (in_range) {
64 in_range = false0;
65
66 if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned))greedy_realloc((void**) &(str), &(allocated), (len + 2
+ 2 * (2+(sizeof(unsigned) <= 1 ? 3 : sizeof(unsigned) <=
2 ? 5 : sizeof(unsigned) <= 4 ? 10 : sizeof(unsigned) <=
8 ? 20 : sizeof(int[-2*(sizeof(unsigned) > 8)])))), sizeof
((str)[0]))
)
67 return NULL((void*)0);
68
69 if (range_end > range_start)
70 r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
71 else
72 r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
73 assert_se(r > 0)do { if ((__builtin_expect(!!(!(r > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("r > 0"), "../src/basic/cpu-set-util.c"
, 73, __PRETTY_FUNCTION__); } while (0)
;
74 len += r;
75 }
76
77 if (in_range) {
78 if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int))greedy_realloc((void**) &(str), &(allocated), (len + 2
+ 2 * (2+(sizeof(int) <= 1 ? 3 : sizeof(int) <= 2 ? 5 :
sizeof(int) <= 4 ? 10 : sizeof(int) <= 8 ? 20 : sizeof
(int[-2*(sizeof(int) > 8)])))), sizeof((str)[0]))
)
79 return NULL((void*)0);
80
81 if (range_end > range_start)
82 r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
83 else
84 r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
85 assert_se(r > 0)do { if ((__builtin_expect(!!(!(r > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("r > 0"), "../src/basic/cpu-set-util.c"
, 85, __PRETTY_FUNCTION__); } while (0)
;
86 }
87
88 return TAKE_PTR(str)({ typeof(str) _ptr_ = (str); (str) = ((void*)0); _ptr_; }) ?: strdup("");
89}
90
91/* XXX(msekleta): this is the workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1819152, remove in 8.3 */
92char *cpu_set_to_range_string_kernel(const CPUSet *set) {
93 unsigned range_start = 0, range_end;
94 _cleanup_free___attribute__((cleanup(freep))) char *str = NULL((void*)0);
95 size_t allocated = 0, len = 0;
96 bool_Bool in_range = false0;
97 int r;
98
99 for (unsigned i = 0; i < set->allocated * 8; i++)
100 if (CPU_ISSET_S(i, set->allocated, set->set)(__extension__ ({ size_t __cpu = (i); __cpu / 8 < (set->
allocated) ? ((((const __cpu_mask *) ((set->set)->__bits
))[((__cpu) / (8 * sizeof (__cpu_mask)))] & ((__cpu_mask)
1 << ((__cpu) % (8 * sizeof (__cpu_mask)))))) != 0 : 0
; }))
) {
101 if (in_range)
102 range_end++;
103 else {
104 range_start = range_end = i;
105 in_range = true1;
106 }
107 } else if (in_range) {
108 in_range = false0;
109
110 if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned))greedy_realloc((void**) &(str), &(allocated), (len + 2
+ 2 * (2+(sizeof(unsigned) <= 1 ? 3 : sizeof(unsigned) <=
2 ? 5 : sizeof(unsigned) <= 4 ? 10 : sizeof(unsigned) <=
8 ? 20 : sizeof(int[-2*(sizeof(unsigned) > 8)])))), sizeof
((str)[0]))
)
111 return NULL((void*)0);
112
113 if (range_end > range_start)
114 r = sprintf(str + len, len > 0 ? ",%d-%d" : "%d-%d", range_start, range_end);
115 else
116 r = sprintf(str + len, len > 0 ? ",%d" : "%d", range_start);
117 assert_se(r > 0)do { if ((__builtin_expect(!!(!(r > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("r > 0"), "../src/basic/cpu-set-util.c"
, 117, __PRETTY_FUNCTION__); } while (0)
;
118 len += r;
119 }
120
121 if (in_range) {
122 if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int))greedy_realloc((void**) &(str), &(allocated), (len + 2
+ 2 * (2+(sizeof(int) <= 1 ? 3 : sizeof(int) <= 2 ? 5 :
sizeof(int) <= 4 ? 10 : sizeof(int) <= 8 ? 20 : sizeof
(int[-2*(sizeof(int) > 8)])))), sizeof((str)[0]))
)
123 return NULL((void*)0);
124
125 if (range_end > range_start)
126 r = sprintf(str + len, len > 0 ? ",%d-%d" : "%d-%d", range_start, range_end);
127 else
128 r = sprintf(str + len, len > 0 ? ",%d" : "%d", range_start);
129 assert_se(r > 0)do { if ((__builtin_expect(!!(!(r > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("r > 0"), "../src/basic/cpu-set-util.c"
, 129, __PRETTY_FUNCTION__); } while (0)
;
130 }
131
132 return TAKE_PTR(str)({ typeof(str) _ptr_ = (str); (str) = ((void*)0); _ptr_; }) ?: strdup("");
133}
134
135
136int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
137 size_t need;
138
139 assert(cpu_set)do { if ((__builtin_expect(!!(!(cpu_set)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("cpu_set"), "../src/basic/cpu-set-util.c"
, 139, __PRETTY_FUNCTION__); } while (0)
;
30
Taking false branch
31
Loop condition is false. Exiting loop
140
141 need = CPU_ALLOC_SIZE(ncpus)((((ncpus) + (8 * sizeof (__cpu_mask)) - 1) / (8 * sizeof (__cpu_mask
))) * sizeof (__cpu_mask))
;
142 if (need > cpu_set->allocated) {
32
Assuming 'need' is > field 'allocated'
33
Taking true branch
143 cpu_set_t *t;
144
145 t = realloc(cpu_set->set, need);
34
Memory is allocated
146 if (!t)
35
Assuming 't' is non-null
36
Taking false branch
147 return -ENOMEM12;
148
149 memzero((uint8_t*) t + cpu_set->allocated, need - cpu_set->allocated)({ size_t _l_ = (need - cpu_set->allocated); void *_x_ = (
(uint8_t*) t + cpu_set->allocated); _l_ == 0 ? _x_ : memset
(_x_, 0, _l_); })
;
37
'?' condition is false
150
151 cpu_set->set = t;
152 cpu_set->allocated = need;
153 }
154
155 return 0;
156}
157
158static int cpu_set_add(CPUSet *cpu_set, unsigned cpu) {
159 int r;
160
161 if (cpu >= 8192)
27
Assuming 'cpu' is < 8192
28
Taking false branch
162 /* As of kernel 5.1, CONFIG_NR_CPUS can be set to 8192 on PowerPC */
163 return -ERANGE34;
164
165 r = cpu_set_realloc(cpu_set, cpu + 1);
29
Calling 'cpu_set_realloc'
38
Returned allocated memory
166 if (r
38.1
'r' is >= 0
< 0)
39
Taking false branch
167 return r;
168
169 CPU_SET_S(cpu, cpu_set->allocated, cpu_set->set)(__extension__ ({ size_t __cpu = (cpu); __cpu / 8 < (cpu_set
->allocated) ? (((__cpu_mask *) ((cpu_set->set)->__bits
))[((__cpu) / (8 * sizeof (__cpu_mask)))] |= ((__cpu_mask) 1 <<
((__cpu) % (8 * sizeof (__cpu_mask))))) : 0; }))
;
40
Assuming the condition is false
41
'?' condition is false
170 return 0;
171}
172
173int cpu_set_add_all(CPUSet *a, const CPUSet *b) {
174 int r;
175
176 /* Do this backwards, so if we fail, we fail before changing anything. */
177 for (unsigned cpu_p1 = b->allocated * 8; cpu_p1 > 0; cpu_p1--)
20
Assuming 'cpu_p1' is > 0
21
Loop condition is true. Entering loop body
44
Assuming 'cpu_p1' is <= 0
45
Loop condition is false. Execution continues on line 184
178 if (CPU_ISSET_S(cpu_p1 - 1, b->allocated, b->set)(__extension__ ({ size_t __cpu = (cpu_p1 - 1); __cpu / 8 <
(b->allocated) ? ((((const __cpu_mask *) ((b->set)->
__bits))[((__cpu) / (8 * sizeof (__cpu_mask)))] & ((__cpu_mask
) 1 << ((__cpu) % (8 * sizeof (__cpu_mask)))))) != 0 : 0
; }))
) {
22
Assuming the condition is true
23
'?' condition is true
24
Assuming the condition is true
25
Taking true branch
179 r = cpu_set_add(a, cpu_p1 - 1);
26
Calling 'cpu_set_add'
42
Returned allocated memory
180 if (r
42.1
'r' is >= 0
< 0)
43
Taking false branch
181 return r;
182 }
183
184 return 1;
185}
186
187int parse_cpu_set_full(
188 const char *rvalue,
189 CPUSet *cpu_set,
190 bool_Bool warn,
191 const char *unit,
192 const char *filename,
193 unsigned line,
194 const char *lvalue) {
195
196 _cleanup_(cpu_set_reset)__attribute__((cleanup(cpu_set_reset))) CPUSet c = {};
197 const char *p = rvalue;
198
199 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/basic/cpu-set-util.c", 199
, __PRETTY_FUNCTION__); } while (0)
;
200
201 for (;;) {
202 _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0);
203 unsigned cpu_lower, cpu_upper;
204 int r;
205
206 r = extract_first_word(&p, &word, WHITESPACE" \t\n\r" ",", EXTRACT_QUOTES);
207 if (r == -ENOMEM12)
208 return warn ? log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/basic/cpu-set-util.c"
, 208, __func__)
: -ENOMEM12;
209 if (r < 0)
210 return warn ? log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/basic/cpu-set-util.c", 210, __func__
, "Invalid value for %s: %s", lvalue, rvalue) : -abs(_e); })
: r;
211 if (r == 0)
212 break;
213
214 r = parse_range(word, &cpu_lower, &cpu_upper);
215 if (r < 0)
216 return warn ? log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", word)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/basic/cpu-set-util.c", 216, __func__
, "Failed to parse CPU affinity '%s'", word) : -abs(_e); })
: r;
217
218 if (cpu_lower > cpu_upper) {
219 if (warn)
220 log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u, ignoring.",({ int _level = (4), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/basic/cpu-set-util.c", 221, __func__
, "Range '%s' is invalid, %u > %u, ignoring.", word, cpu_lower
, cpu_upper) : -abs(_e); })
221 word, cpu_lower, cpu_upper)({ int _level = (4), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/basic/cpu-set-util.c", 221, __func__
, "Range '%s' is invalid, %u > %u, ignoring.", word, cpu_lower
, cpu_upper) : -abs(_e); })
;
222
223 /* Make sure something is allocated, to distinguish this from the empty case */
224 r = cpu_set_realloc(&c, 1);
225 if (r < 0)
226 return r;
227 }
228
229 for (unsigned cpu_p1 = MIN(cpu_upper, UINT_MAX-1)__extension__ ({ const typeof((cpu_upper)) __unique_prefix_A24
= ((cpu_upper)); const typeof(((2147483647 *2U +1U)-1)) __unique_prefix_B25
= (((2147483647 *2U +1U)-1)); __unique_prefix_A24 < __unique_prefix_B25
? __unique_prefix_A24 : __unique_prefix_B25; })
+ 1; cpu_p1 > cpu_lower; cpu_p1--) {
230 r = cpu_set_add(&c, cpu_p1 - 1);
231 if (r < 0)
232 return warn ? log_syntax(unit, LOG_ERR, filename, line, r,({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/basic/cpu-set-util.c", 233, __func__
, "Cannot add CPU %u to set: %m", cpu_p1 - 1) : -abs(_e); })
233 "Cannot add CPU %u to set: %m", cpu_p1 - 1)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/basic/cpu-set-util.c", 233, __func__
, "Cannot add CPU %u to set: %m", cpu_p1 - 1) : -abs(_e); })
: r;
234 }
235 }
236
237 /* On success, transfer ownership to the output variable */
238 *cpu_set = c;
239 c = (CPUSet) {};
240
241 return 0;
242}
243
244int parse_cpu_set_extend(
245 const char *rvalue,
246 CPUSet *old,
247 bool_Bool warn,
248 const char *unit,
249 const char *filename,
250 unsigned line,
251 const char *lvalue) {
252
253 _cleanup_(cpu_set_reset)__attribute__((cleanup(cpu_set_reset))) CPUSet cpuset = {};
254 int r;
255
256 r = parse_cpu_set_full(rvalue, &cpuset, true1, unit, filename, line, lvalue);
257 if (r < 0)
258 return r;
259
260 if (!cpuset.set) {
261 /* An empty assignment resets the CPU list */
262 cpu_set_reset(old);
263 return 0;
264 }
265
266 if (!old->set) {
267 *old = cpuset;
268 cpuset = (CPUSet) {};
269 return 1;
270 }
271
272 return cpu_set_add_all(old, &cpuset);
273}
274
275int cpus_in_affinity_mask(void) {
276 size_t n = 16;
277 int r;
278
279 for (;;) {
280 cpu_set_t *c;
281
282 c = CPU_ALLOC(n)__sched_cpualloc (n);
283 if (!c)
284 return -ENOMEM12;
285
286 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n)((((n) + (8 * sizeof (__cpu_mask)) - 1) / (8 * sizeof (__cpu_mask
))) * sizeof (__cpu_mask))
, c) >= 0) {
287 int k;
288
289 k = CPU_COUNT_S(CPU_ALLOC_SIZE(n), c)__sched_cpucount (((((n) + (8 * sizeof (__cpu_mask)) - 1) / (
8 * sizeof (__cpu_mask))) * sizeof (__cpu_mask)), c)
;
290 CPU_FREE(c)__sched_cpufree (c);
291
292 if (k <= 0)
293 return -EINVAL22;
294
295 return k;
296 }
297
298 r = -errno(*__errno_location ());
299 CPU_FREE(c)__sched_cpufree (c);
300
301 if (r != -EINVAL22)
302 return r;
303 if (n > SIZE_MAX(18446744073709551615UL)/2)
304 return -ENOMEM12;
305 n *= 2;
306 }
307}
308
309int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated) {
310 uint8_t *out;
311
312 assert(set)do { if ((__builtin_expect(!!(!(set)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("set"), "../src/basic/cpu-set-util.c", 312
, __PRETTY_FUNCTION__); } while (0)
;
313 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/basic/cpu-set-util.c", 313
, __PRETTY_FUNCTION__); } while (0)
;
314
315 out = new0(uint8_t, set->allocated)((uint8_t*) calloc((set->allocated), sizeof(uint8_t)));
316 if (!out)
317 return -ENOMEM12;
318
319 for (unsigned cpu = 0; cpu < set->allocated * 8; cpu++)
320 if (CPU_ISSET_S(cpu, set->allocated, set->set)(__extension__ ({ size_t __cpu = (cpu); __cpu / 8 < (set->
allocated) ? ((((const __cpu_mask *) ((set->set)->__bits
))[((__cpu) / (8 * sizeof (__cpu_mask)))] & ((__cpu_mask)
1 << ((__cpu) % (8 * sizeof (__cpu_mask)))))) != 0 : 0
; }))
)
321 out[cpu / 8] |= 1u << (cpu % 8);
322
323 *ret = out;
324 *allocated = set->allocated;
325 return 0;
326}
327
328int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) {
329 _cleanup_(cpu_set_reset)__attribute__((cleanup(cpu_set_reset))) CPUSet s = {};
330 int r;
331
332 assert(bits)do { if ((__builtin_expect(!!(!(bits)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("bits"), "../src/basic/cpu-set-util.c", 332
, __PRETTY_FUNCTION__); } while (0)
;
333 assert(set)do { if ((__builtin_expect(!!(!(set)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("set"), "../src/basic/cpu-set-util.c", 333
, __PRETTY_FUNCTION__); } while (0)
;
334
335 for (unsigned cpu = size * 8; cpu > 0; cpu--)
336 if (bits[(cpu - 1) / 8] & (1u << ((cpu - 1) % 8))) {
337 r = cpu_set_add(&s, cpu - 1);
338 if (r < 0)
339 return r;
340 }
341
342 *set = s;
343 s = (CPUSet) {};
344 return 0;
345}
346
347bool_Bool numa_policy_is_valid(const NUMAPolicy *policy) {
348 assert(policy)do { if ((__builtin_expect(!!(!(policy)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("policy"), "../src/basic/cpu-set-util.c"
, 348, __PRETTY_FUNCTION__); } while (0)
;
349
350 if (!mpol_is_valid(numa_policy_get_type(policy)))
351 return false0;
352
353 if (!policy->nodes.set &&
354 !IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL, MPOL_PREFERRED)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){MPOL_DEFAULT, MPOL_LOCAL, MPOL_PREFERRED
})/sizeof(int)]; switch(numa_policy_get_type(policy)) { case MPOL_DEFAULT
: case MPOL_LOCAL: case MPOL_PREFERRED: _found = 1; break; default
: break; } _found; })
)
355 return false0;
356
357 if (policy->nodes.set &&
358 numa_policy_get_type(policy) == MPOL_PREFERRED &&
359 CPU_COUNT_S(policy->nodes.allocated, policy->nodes.set)__sched_cpucount (policy->nodes.allocated, policy->nodes
.set)
!= 1)
360 return false0;
361
362 return true1;
363}
364
365static int numa_policy_to_mempolicy(const NUMAPolicy *policy, unsigned long *ret_maxnode, unsigned long **ret_nodes) {
366 unsigned node, bits = 0, ulong_bits;
367 _cleanup_free___attribute__((cleanup(freep))) unsigned long *out = NULL((void*)0);
368
369 assert(policy)do { if ((__builtin_expect(!!(!(policy)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("policy"), "../src/basic/cpu-set-util.c"
, 369, __PRETTY_FUNCTION__); } while (0)
;
370 assert(ret_maxnode)do { if ((__builtin_expect(!!(!(ret_maxnode)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret_maxnode"), "../src/basic/cpu-set-util.c"
, 370, __PRETTY_FUNCTION__); } while (0)
;
371 assert(ret_nodes)do { if ((__builtin_expect(!!(!(ret_nodes)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret_nodes"), "../src/basic/cpu-set-util.c"
, 371, __PRETTY_FUNCTION__); } while (0)
;
372
373 if (IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){MPOL_DEFAULT, MPOL_LOCAL})/sizeof(int)];
switch(numa_policy_get_type(policy)) { case MPOL_DEFAULT: case
MPOL_LOCAL: _found = 1; break; default: break; } _found; })
||
374 (numa_policy_get_type(policy) == MPOL_PREFERRED && !policy->nodes.set)) {
375 *ret_nodes = NULL((void*)0);
376 *ret_maxnode = 0;
377 return 0;
378 }
379
380 bits = policy->nodes.allocated * 8;
381 ulong_bits = sizeof(unsigned long) * 8;
382
383 out = new0(unsigned long, DIV_ROUND_UP(policy->nodes.allocated, sizeof(unsigned long)))((unsigned long*) calloc((({ const typeof((policy->nodes.allocated
)) __unique_prefix_X26 = ((policy->nodes.allocated)); const
typeof((sizeof(unsigned long))) __unique_prefix_Y27 = ((sizeof
(unsigned long))); (__unique_prefix_X26 / __unique_prefix_Y27
+ !!(__unique_prefix_X26 % __unique_prefix_Y27)); })), sizeof
(unsigned long)))
;
384 if (!out)
385 return -ENOMEM12;
386
387 /* We don't make any assumptions about internal type libc is using to store NUMA node mask.
388 Hence we need to convert the node mask to the representation expected by set_mempolicy() */
389 for (node = 0; node < bits; node++)
390 if (CPU_ISSET_S(node, policy->nodes.allocated, policy->nodes.set)(__extension__ ({ size_t __cpu = (node); __cpu / 8 < (policy
->nodes.allocated) ? ((((const __cpu_mask *) ((policy->
nodes.set)->__bits))[((__cpu) / (8 * sizeof (__cpu_mask)))
] & ((__cpu_mask) 1 << ((__cpu) % (8 * sizeof (__cpu_mask
)))))) != 0 : 0; }))
)
391 out[node / ulong_bits] |= 1ul << (node % ulong_bits);
392
393 *ret_nodes = TAKE_PTR(out)({ typeof(out) _ptr_ = (out); (out) = ((void*)0); _ptr_; });
394 *ret_maxnode = bits + 1;
395 return 0;
396}
397
398int apply_numa_policy(const NUMAPolicy *policy) {
399 int r;
400 _cleanup_free___attribute__((cleanup(freep))) unsigned long *nodes = NULL((void*)0);
401 unsigned long maxnode;
402
403 assert(policy)do { if ((__builtin_expect(!!(!(policy)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("policy"), "../src/basic/cpu-set-util.c"
, 403, __PRETTY_FUNCTION__); } while (0)
;
404
405 if (get_mempolicymissing_get_mempolicy(NULL((void*)0), NULL((void*)0), 0, 0, 0) < 0 && errno(*__errno_location ()) == ENOSYS38)
406 return -EOPNOTSUPP95;
407
408 if (!numa_policy_is_valid(policy))
409 return -EINVAL22;
410
411 r = numa_policy_to_mempolicy(policy, &maxnode, &nodes);
412 if (r < 0)
413 return r;
414
415 r = set_mempolicymissing_set_mempolicy(numa_policy_get_type(policy), nodes, maxnode);
416 if (r < 0)
417 return -errno(*__errno_location ());
418
419 return 0;
420}
421
422int numa_to_cpu_set(const NUMAPolicy *policy, CPUSet *ret) {
423 int r;
424 size_t i;
425 _cleanup_(cpu_set_reset)__attribute__((cleanup(cpu_set_reset))) CPUSet s = {};
426
427 assert(policy)do { if ((__builtin_expect(!!(!(policy)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("policy"), "../src/basic/cpu-set-util.c"
, 427, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'policy' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
428 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/basic/cpu-set-util.c", 428
, __PRETTY_FUNCTION__); } while (0)
;
4
Assuming 'ret' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
429
430 for (i = 0; i < policy->nodes.allocated * 8; i++) {
7
Assuming the condition is true
8
Loop condition is true. Entering loop body
48
Assuming the condition is true
49
Loop condition is true. Entering loop body
431 _cleanup_free___attribute__((cleanup(freep))) char *l = NULL((void*)0);
432 char p[STRLEN("/sys/devices/system/node/node//cpulist")(sizeof("""/sys/devices/system/node/node//cpulist""") - 1) + DECIMAL_STR_MAX(size_t)(2+(sizeof(size_t) <= 1 ? 3 : sizeof(size_t) <= 2 ? 5 :
sizeof(size_t) <= 4 ? 10 : sizeof(size_t) <= 8 ? 20 : sizeof
(int[-2*(sizeof(size_t) > 8)])))
+ 1];
433 _cleanup_(cpu_set_reset)__attribute__((cleanup(cpu_set_reset))) CPUSet part = {};
434
435 if (!CPU_ISSET_S(i, policy->nodes.allocated, policy->nodes.set)(__extension__ ({ size_t __cpu = (i); __cpu / 8 < (policy->
nodes.allocated) ? ((((const __cpu_mask *) ((policy->nodes
.set)->__bits))[((__cpu) / (8 * sizeof (__cpu_mask)))] &
((__cpu_mask) 1 << ((__cpu) % (8 * sizeof (__cpu_mask)
))))) != 0 : 0; }))
)
9
Assuming the condition is true
10
'?' condition is true
11
Assuming the condition is true
12
Taking false branch
50
'?' condition is true
51
Assuming the condition is true
52
Taking false branch
436 continue;
437
438 xsprintf(p, "/sys/devices/system/node/node%zu/cpulist", i)do { if ((__builtin_expect(!!(!(((size_t) snprintf(p, __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(p), typeof(&*(p))), sizeof(p)/sizeof((p)[0]), ((void)0))
), "/sys/devices/system/node/node%zu/cpulist", i) < (__extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(p), typeof(&*(p))), sizeof(p)/sizeof((p)[0]), ((void)0))
))))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("xsprintf: "
"p" "[] must be big enough"), "../src/basic/cpu-set-util.c",
438, __PRETTY_FUNCTION__); } while (0)
;
13
Assuming the condition is true
14
Taking false branch
15
Loop condition is false. Exiting loop
53
Assuming the condition is true
54
Taking false branch
55
Loop condition is false. Exiting loop
439
440 r = read_one_line_file(p, &l);
441 if (r < 0)
16
Assuming 'r' is >= 0
17
Taking false branch
56
Assuming 'r' is < 0
57
Taking true branch
442 return r;
58
Potential leak of memory pointed to by 's.set'
443
444 r = parse_cpu_set(l, &part);
445 if (r
17.1
'r' is >= 0
< 0)
18
Taking false branch
446 return r;
447
448 r = cpu_set_add_all(&s, &part);
19
Calling 'cpu_set_add_all'
46
Returned allocated memory
449 if (r
46.1
'r' is >= 0
< 0)
47
Taking false branch
450 return r;
451 }
452
453 *ret = s;
454 s = (CPUSet) {};
455
456 return 0;
457}
458
459static const char* const mpol_table[] = {
460 [MPOL_DEFAULT] = "default",
461 [MPOL_PREFERRED] = "preferred",
462 [MPOL_BIND] = "bind",
463 [MPOL_INTERLEAVE] = "interleave",
464 [MPOL_LOCAL] = "local",
465};
466
467DEFINE_STRING_TABLE_LOOKUP(mpol, int)const char *mpol_to_string(int i) { if (i < 0 || i >= (
int) __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(mpol_table), typeof(&*(mpol_table))), sizeof(mpol_table
)/sizeof((mpol_table)[0]), ((void)0)))) return ((void*)0); return
mpol_table[i]; } int mpol_from_string(const char *s) { return
(int) string_table_lookup(mpol_table, __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(mpol_table), typeof(&
*(mpol_table))), sizeof(mpol_table)/sizeof((mpol_table)[0]), (
(void)0))), s); }
;