| File: | build-scan/../src/basic/cpu-set-util.c |
| Warning: | line 442, column 32 Potential leak of memory pointed to by 's.set' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | ||||
| 28 | char* 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 | ||||
| 48 | char *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 */ | |||
| 92 | char *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 | ||||
| 136 | int 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); | |||
| 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) { | |||
| 143 | cpu_set_t *t; | |||
| 144 | ||||
| 145 | t = realloc(cpu_set->set, need); | |||
| 146 | if (!t) | |||
| 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_); }); | |||
| 150 | ||||
| 151 | cpu_set->set = t; | |||
| 152 | cpu_set->allocated = need; | |||
| 153 | } | |||
| 154 | ||||
| 155 | return 0; | |||
| 156 | } | |||
| 157 | ||||
| 158 | static int cpu_set_add(CPUSet *cpu_set, unsigned cpu) { | |||
| 159 | int r; | |||
| 160 | ||||
| 161 | if (cpu >= 8192) | |||
| 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); | |||
| 166 | if (r
| |||
| 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; })); | |||
| 170 | return 0; | |||
| 171 | } | |||
| 172 | ||||
| 173 | int 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--) | |||
| 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 ; }))) { | |||
| 179 | r = cpu_set_add(a, cpu_p1 - 1); | |||
| 180 | if (r
| |||
| 181 | return r; | |||
| 182 | } | |||
| 183 | ||||
| 184 | return 1; | |||
| 185 | } | |||
| 186 | ||||
| 187 | int 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 | ||||
| 244 | int 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 | ||||
| 275 | int 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 | ||||
| 309 | int 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 | ||||
| 328 | int 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 | ||||
| 347 | bool_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 | ||||
| 365 | static 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 | ||||
| 398 | int 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 | ||||
| 422 | int 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); | |||
| ||||
| 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); | |||
| 429 | ||||
| 430 | for (i = 0; i < policy->nodes.allocated * 8; i++) { | |||
| 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; }))) | |||
| 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); | |||
| 439 | ||||
| 440 | r = read_one_line_file(p, &l); | |||
| 441 | if (r < 0) | |||
| 442 | return r; | |||
| ||||
| 443 | ||||
| 444 | r = parse_cpu_set(l, &part); | |||
| 445 | if (r
| |||
| 446 | return r; | |||
| 447 | ||||
| 448 | r = cpu_set_add_all(&s, &part); | |||
| 449 | if (r
| |||
| 450 | return r; | |||
| 451 | } | |||
| 452 | ||||
| 453 | *ret = s; | |||
| 454 | s = (CPUSet) {}; | |||
| 455 | ||||
| 456 | return 0; | |||
| 457 | } | |||
| 458 | ||||
| 459 | static 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 | ||||
| 467 | DEFINE_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); }; |