From f3d90fca4a51ba42bd788bd696f2521f05b5ca76 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sat, 23 Oct 2021 19:15:24 +0200 Subject: [PATCH] conf: handle kernels without or not using SMT On kernel not enabling or not using SMT core scheduling will return with ENODEV. Handle such kernels. Link: https://github.com/lxc/lxd/issues/9419 Signed-off-by: Christian Brauner --- src/lxc/attach.c | 10 +++++----- src/lxc/start.c | 9 +++++++-- src/lxc/syscall_wrappers.h | 16 ++++++++++------ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c index cd526ab6bd..77da7bb456 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -409,8 +409,8 @@ static int get_attach_context(struct attach_context *ctx, SYSERROR("Failed to retrieve namespace flags"); ctx->ns_clone_flags = ret; - ctx->core_sched_cookie = core_scheduling_cookie_get(ctx->init_pid); - if (!core_scheduling_cookie_valid(ctx->core_sched_cookie)) + ret = core_scheduling_cookie_get(ctx->init_pid, &ctx->core_sched_cookie); + if (ret || !core_scheduling_cookie_valid(ctx->core_sched_cookie)) INFO("Container does not run in a separate core scheduling domain"); else INFO("Container runs in separate core scheduling domain %llu", @@ -1155,9 +1155,9 @@ __noreturn static void do_attach(struct attach_payload *ap) goto on_error; } - core_sched_cookie = core_scheduling_cookie_get(getpid()); - if (!core_scheduling_cookie_valid(core_sched_cookie) && - ctx->core_sched_cookie != core_sched_cookie) { + ret = core_scheduling_cookie_get(getpid(), &core_sched_cookie); + if (ret || !core_scheduling_cookie_valid(core_sched_cookie) || + (ctx->core_sched_cookie != core_sched_cookie)) { SYSERROR("Invalid core scheduling domain cookie %llu != %llu", (llu)core_sched_cookie, (llu)ctx->core_sched_cookie); diff --git a/src/lxc/start.c b/src/lxc/start.c index 3ed9289858..8f7173ec8c 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -1566,14 +1566,19 @@ static int core_scheduling(struct lxc_handler *handler) ret = core_scheduling_cookie_create_threadgroup(handler->pid); if (ret < 0) { + if (ret == -ENODEV) { + INFO("The kernel doesn't support or doesn't use simultaneous multithreading (SMT)"); + conf->sched_core = false; + return 0; + } if (ret == -EINVAL) return syserror("The kernel does not support core scheduling"); return syserror("Failed to create new core scheduling domain"); } - conf->sched_core_cookie = core_scheduling_cookie_get(handler->pid); - if (!core_scheduling_cookie_valid(conf->sched_core_cookie)) + ret = core_scheduling_cookie_get(handler->pid, &conf->sched_core_cookie); + if (ret || !core_scheduling_cookie_valid(conf->sched_core_cookie)) return syserror("Failed to retrieve core scheduling domain cookie"); TRACE("Created new core scheduling domain with cookie %llu", diff --git a/src/lxc/syscall_wrappers.h b/src/lxc/syscall_wrappers.h index 4a9dda83d1..a5e98b565c 100644 --- a/src/lxc/syscall_wrappers.h +++ b/src/lxc/syscall_wrappers.h @@ -367,17 +367,21 @@ static inline bool core_scheduling_cookie_valid(__u64 cookie) return (cookie > 0) && (cookie != INVALID_SCHED_CORE_COOKIE); } -static inline __u64 core_scheduling_cookie_get(pid_t pid) +static inline int core_scheduling_cookie_get(pid_t pid, __u64 *cookie) { - __u64 cookie; int ret; + if (!cookie) + return ret_errno(EINVAL); + ret = prctl(PR_SCHED_CORE, PR_SCHED_CORE_GET, pid, - PR_SCHED_CORE_SCOPE_THREAD, (unsigned long)&cookie); - if (ret) - return INVALID_SCHED_CORE_COOKIE; + PR_SCHED_CORE_SCOPE_THREAD, (unsigned long)cookie); + if (ret) { + *cookie = INVALID_SCHED_CORE_COOKIE; + return -errno; + } - return cookie; + return 0; } static inline int core_scheduling_cookie_create_threadgroup(pid_t pid)