When setting CPU affinity, take into consideration the current CPU
affinity set. Use only CPU numbers, which exist in the current affinity set. Maybe fixes https://github.com/google/nsjail/issues/200
This commit is contained in:
parent
57ed22dfdf
commit
856cb0f2ec
@ -484,7 +484,6 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
nsjconf->forward_signals = false;
|
nsjconf->forward_signals = false;
|
||||||
nsjconf->orig_uid = getuid();
|
nsjconf->orig_uid = getuid();
|
||||||
nsjconf->orig_euid = geteuid();
|
nsjconf->orig_euid = geteuid();
|
||||||
nsjconf->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
|
||||||
nsjconf->seccomp_fprog.filter = NULL;
|
nsjconf->seccomp_fprog.filter = NULL;
|
||||||
nsjconf->seccomp_fprog.len = 0;
|
nsjconf->seccomp_fprog.len = 0;
|
||||||
nsjconf->seccomp_log = false;
|
nsjconf->seccomp_log = false;
|
||||||
|
85
cpu.cc
85
cpu.cc
@ -27,66 +27,83 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
|
|
||||||
static void setRandomCpu(cpu_set_t* mask, size_t mask_size, size_t cpu_num) {
|
static size_t getNthCpu(cpu_set_t* mask, size_t mask_size, size_t n, size_t cpus_left) {
|
||||||
if ((size_t)CPU_COUNT_S(mask_size, mask) >= cpu_num) {
|
for (size_t i = 0, j = 0; i < CPU_SETSIZE; i++) {
|
||||||
LOG_F(
|
if (CPU_ISSET_S(i, mask_size, mask)) {
|
||||||
"Number of CPUs in the mask '%d' is bigger than number of available CPUs '%zu'",
|
if (j == n) {
|
||||||
CPU_COUNT(mask), cpu_num);
|
return i;
|
||||||
|
}
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG_F("No CPU #%zu found, yet there should be %zu left", n,
|
||||||
|
(size_t)CPU_COUNT_S(mask_size, mask));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
static void setRandomCpu(cpu_set_t* original_mask, cpu_set_t* new_mask, size_t mask_size) {
|
||||||
uint64_t n = util::rnd64() % cpu_num;
|
size_t cpus_left = CPU_COUNT_S(mask_size, original_mask);
|
||||||
if (!CPU_ISSET_S(n, mask_size, mask)) {
|
if (cpus_left == 0) {
|
||||||
LOG_D("Setting allowed CPU#:%" PRIu64 " of [0-%zu]", n, cpu_num - 1);
|
LOG_F("There are no more CPUs left to use");
|
||||||
CPU_SET_S(n, mask_size, mask);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t n = getNthCpu(original_mask, mask_size, util::rnd64() % cpus_left, cpus_left);
|
||||||
|
LOG_D("Setting allowed CPU#:%" PRIu64, n);
|
||||||
|
CPU_SET_S(n, mask_size, new_mask);
|
||||||
|
CPU_CLR_S(n, mask_size, original_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool initCpu(nsjconf_t* nsjconf) {
|
bool initCpu(nsjconf_t* nsjconf) {
|
||||||
if (nsjconf->num_cpus < 0) {
|
|
||||||
PLOG_W("sysconf(_SC_NPROCESSORS_ONLN) returned %ld", nsjconf->num_cpus);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (nsjconf->max_cpus > (size_t)nsjconf->num_cpus) {
|
|
||||||
LOG_W("Requested number of CPUs:%zu is bigger than CPUs online:%ld",
|
|
||||||
nsjconf->max_cpus, nsjconf->num_cpus);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (nsjconf->max_cpus == (size_t)nsjconf->num_cpus) {
|
|
||||||
LOG_D("All CPUs requested (%zu of %ld)", nsjconf->max_cpus, nsjconf->num_cpus);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (nsjconf->max_cpus == 0) {
|
if (nsjconf->max_cpus == 0) {
|
||||||
LOG_D("No max_cpus limit set");
|
LOG_D("No max_cpus limit set");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_set_t* mask = CPU_ALLOC(nsjconf->num_cpus);
|
size_t mask_size = CPU_ALLOC_SIZE(CPU_SETSIZE);
|
||||||
if (mask == NULL) {
|
std::unique_ptr<cpu_set_t> original_mask(CPU_ALLOC(CPU_SETSIZE));
|
||||||
PLOG_W("Failure allocating cpu_set_t for %ld CPUs", nsjconf->num_cpus);
|
if (original_mask.get() == NULL) {
|
||||||
|
PLOG_W("Failure allocating cpu_set_t for %d CPUs", CPU_SETSIZE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (sched_getaffinity(0, mask_size, original_mask.get()) == -1) {
|
||||||
|
PLOG_W("sched_getaffinity(0, mask_size=%zu)", mask_size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t available_cpus = CPU_COUNT_S(mask_size, original_mask.get());
|
||||||
|
|
||||||
size_t mask_size = CPU_ALLOC_SIZE(nsjconf->num_cpus);
|
if (nsjconf->max_cpus > available_cpus) {
|
||||||
CPU_ZERO_S(mask_size, mask);
|
LOG_W(
|
||||||
|
"Number of requested CPUs is bigger than number of available CPUs (%zu > %zu)",
|
||||||
|
nsjconf->max_cpus, available_cpus);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (nsjconf->max_cpus == available_cpus) {
|
||||||
|
LOG_D("All CPUs requested (%zu of %zu)", nsjconf->max_cpus, available_cpus);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<cpu_set_t> new_mask(CPU_ALLOC(CPU_SETSIZE));
|
||||||
|
if (new_mask.get() == NULL) {
|
||||||
|
PLOG_W("Failure allocating cpu_set_t for %d CPUs", CPU_SETSIZE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CPU_ZERO_S(mask_size, new_mask.get());
|
||||||
|
|
||||||
for (size_t i = 0; i < nsjconf->max_cpus; i++) {
|
for (size_t i = 0; i < nsjconf->max_cpus; i++) {
|
||||||
setRandomCpu(mask, mask_size, nsjconf->num_cpus);
|
setRandomCpu(original_mask.get(), new_mask.get(), mask_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sched_setaffinity(0, mask_size, mask) == -1) {
|
if (sched_setaffinity(0, mask_size, new_mask.get()) == -1) {
|
||||||
PLOG_W("sched_setaffinity(max_cpus=%zu) failed", nsjconf->max_cpus);
|
PLOG_W("sched_setaffinity(max_cpus=%zu) failed", nsjconf->max_cpus);
|
||||||
CPU_FREE(mask);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
CPU_FREE(mask);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
1
nsjail.h
1
nsjail.h
@ -168,7 +168,6 @@ struct nsjconf_t {
|
|||||||
struct sock_fprog seccomp_fprog;
|
struct sock_fprog seccomp_fprog;
|
||||||
bool seccomp_log;
|
bool seccomp_log;
|
||||||
int nice_level;
|
int nice_level;
|
||||||
long num_cpus;
|
|
||||||
uid_t orig_uid;
|
uid_t orig_uid;
|
||||||
uid_t orig_euid;
|
uid_t orig_euid;
|
||||||
std::vector<mount_t> mountpts;
|
std::vector<mount_t> mountpts;
|
||||||
|
Loading…
Reference in New Issue
Block a user