]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/exec-invoke: use sched_setattr instead of sched_setscheduler
authorFlorian Schmaus <flo@geekplace.eu>
Wed, 26 Jun 2024 12:37:52 +0000 (14:37 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 26 Jun 2024 18:54:53 +0000 (20:54 +0200)
The kernel's sched_setattr interface allows for more control over a processes
scheduling attributes as the previously used sched_setscheduler interface.

Using sched_setattr is also the prerequisite for support of utilization
clamping (UCLAMP [1], see #26705) and allows to set sched_runtime. The latter,
sched_runtime, will probably become a relevant scheduling parameter of the
EEVDF scheduler [2, 3], and therefore will not only apply to processes
scheduled via SCHED_DEADLINE, but also for processes scheduled via
SCHED_OTHER/SCHED_BATCH (i.e., most processes).

1: https://docs.kernel.org/next/scheduler/sched-util-clamp.html
2: https://lwn.net/Articles/969062/
3: https://lwn.net/ml/linux-kernel/20240405110010.934104715@infradead.org/

meson.build
src/basic/missing_sched.h
src/basic/missing_syscall.h
src/core/exec-invoke.c

index aa36e72b024fc31e9d58e5cbe02d4943fa6ab1bc..ddad82ddc9260947ba42c6ecec087131263d528b 100644 (file)
@@ -547,6 +547,7 @@ decl_headers = '''
 #include <uchar.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
+#include <sched.h>
 '''
 
 foreach decl : ['char16_t',
@@ -554,6 +555,7 @@ foreach decl : ['char16_t',
                 'struct mount_attr',
                 'struct statx',
                 'struct dirent64',
+                'struct sched_attr',
                ]
 
         # We get -1 if the size cannot be determined
@@ -601,6 +603,7 @@ foreach ident : [
                                  #include <unistd.h>'''],     # no known header declares pivot_root
         ['ioprio_get',        '''#include <sched.h>'''],      # no known header declares ioprio_get
         ['ioprio_set',        '''#include <sched.h>'''],      # no known header declares ioprio_set
+        ['sched_setattr',     '''#include <sched.h>'''],      # no known header declares sched_setattr
         ['name_to_handle_at', '''#include <sys/types.h>
                                  #include <sys/stat.h>
                                  #include <fcntl.h>'''],
index b8109d30ac60fd8e38a3a628c6a0739d3a3cb649..bd83b41a71995c83a9569d74db5e386e3225c348 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include <linux/types.h>
 #include <sched.h>
 
 #include "macro.h"
@@ -35,3 +36,20 @@ assert_cc(PF_KTHREAD == 0x00200000);
 #else
 assert_cc(TASK_COMM_LEN == 16);
 #endif
+
+#if !HAVE_STRUCT_SCHED_ATTR
+struct sched_attr {
+        __u32 size;             /* Size of this structure */
+        __u32 sched_policy;     /* Policy (SCHED_*) */
+        __u64 sched_flags;      /* Flags */
+        __s32  sched_nice;      /* Nice value (SCHED_OTHER,
+                                         SCHED_BATCH) */
+        __u32 sched_priority;   /* Static priority (SCHED_FIFO,
+                                       SCHED_RR) */
+        /* Remaining fields are for SCHED_DEADLINE
+           and potentially soon for SCHED_OTHER/SCHED_BATCH */
+        __u64 sched_runtime;
+        __u64 sched_deadline;
+        __u64 sched_period;
+};
+#endif
index 86280771c49fd278a8789739ec39e8231e62d741..e2cd8b4e35602e9c049776d63c1430c425ca3fae 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "macro.h"
 #include "missing_keyctl.h"
+#include "missing_sched.h"
 #include "missing_stat.h"
 #include "missing_syscall_def.h"
 
@@ -667,6 +668,22 @@ static inline ssize_t missing_getdents64(int fd, void *buffer, size_t length) {
 
 /* ======================================================================= */
 
+#if !HAVE_SCHED_SETATTR
+
+static inline ssize_t missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned int flags) {
+#  if defined __NR_sched_setattr
+        return syscall(__NR_sched_setattr, pid, attr, flags);
+#  else
+        errno = ENOSYS;
+        return -1;
+#  endif
+}
+
+#  define sched_setattr missing_sched_setattr
+#endif
+
+/* ======================================================================= */
+
 /* glibc does not provide clone() on ia64, only clone2(). Not only that, but it also doesn't provide a
  * prototype, only the symbol in the shared library (it provides a prototype for clone(), but not the
  * symbol in the shared library). */
index 3f713e731fd1343f34d737343aef542ff7b87516..94c908afd781361508e3b19a1a200b0982b65f4a 100644 (file)
@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
+#include <linux/sched.h>
 #include <sys/eventfd.h>
 #include <sys/ioctl.h>
 #include <sys/mount.h>
@@ -44,6 +45,7 @@
 #include "journal-send.h"
 #include "missing_ioprio.h"
 #include "missing_prctl.h"
+#include "missing_sched.h"
 #include "missing_securebits.h"
 #include "missing_syscall.h"
 #include "mkdir-label.h"
@@ -4411,15 +4413,14 @@ int exec_invoke(
         }
 
         if (context->cpu_sched_set) {
-                struct sched_param param = {
+                struct sched_attr attr = {
+                        .size = sizeof(attr),
+                        .sched_policy = context->cpu_sched_policy,
                         .sched_priority = context->cpu_sched_priority,
+                        .sched_flags = context->cpu_sched_reset_on_fork ? SCHED_FLAG_RESET_ON_FORK : 0,
                 };
 
-                r = sched_setscheduler(0,
-                                       context->cpu_sched_policy |
-                                       (context->cpu_sched_reset_on_fork ?
-                                        SCHED_RESET_ON_FORK : 0),
-                                       &param);
+                r = sched_setattr(/* pid= */ 0, &attr, /* flags= */ 0);
                 if (r < 0) {
                         *exit_status = EXIT_SETSCHEDULER;
                         return log_exec_error_errno(context, params, errno, "Failed to set up CPU scheduling: %m");