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/
#include <uchar.h>
#include <sys/mount.h>
#include <sys/stat.h>
+#include <sched.h>
'''
foreach decl : ['char16_t',
'struct mount_attr',
'struct statx',
'struct dirent64',
+ 'struct sched_attr',
]
# We get -1 if the size cannot be determined
#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>'''],
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include <linux/types.h>
#include <sched.h>
#include "macro.h"
#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
#include "macro.h"
#include "missing_keyctl.h"
+#include "missing_sched.h"
#include "missing_stat.h"
#include "missing_syscall_def.h"
/* ======================================================================= */
+#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). */
/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#include <linux/sched.h>
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#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"
}
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),
- ¶m);
+ 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");