]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
chrt: Add --sched_runtime support for SCHED_{OTHER,BATCH} policies
authorPetre Tudor <petre-ionut.tudor@arm.com>
Thu, 16 Jan 2025 15:13:22 +0000 (15:13 +0000)
committerPetre Tudor <petre-ionut.tudor@arm.com>
Wed, 12 Feb 2025 15:56:41 +0000 (15:56 +0000)
Apply --sched_runtime to SCHED_{OTHER,BATCH} in addition to
SCHED_DEADLINE, supporting Linux kernel patch:

commit 857b158dc5e8 ("sched/eevdf: Use sched_attr::sched_runtime to set request/slice suggestion")
(2024-08-17 Peter Zijlstra)

This patch is present in kernel versions starting with 6.12 and allows
setting custom slice length on fair tasks via the sched_runtime parameter.

Using this new feature:

/* change policy to SCHED_BATCH and set custom slice to 0.1ms */
chrt -v -b -T 100000 -p 0 $PID

pid $PID's current scheduling policy: SCHED_OTHER
pid $PID's current scheduling priority: 0
pid $PID's current runtime parameter: 2250000
pid $PID's new scheduling policy: SCHED_BATCH
pid $PID's new scheduling priority: 0
pid $PID's new runtime parameter: 100000

Signed-off-by: Petre Tudor <petre-ionut.tudor@arm.com>
schedutils/chrt.c

index 91e05831c402828485cea4e490db7de8208be75d..104ee23a05e73817a831ad79089bf3d68b904e28 100644 (file)
@@ -26,6 +26,7 @@
 #include <unistd.h>
 #include <getopt.h>
 #include <errno.h>
+#include <stdbool.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 
@@ -127,11 +128,45 @@ static const char *get_policy_name(int policy)
        return _("unknown");
 }
 
+static bool supports_custom_slice(int policy)
+{
+#ifdef SCHED_BATCH
+       if (policy == SCHED_BATCH)
+               return true;
+#endif
+       return policy == SCHED_OTHER;
+}
+
+static bool supports_runtime_param(int policy)
+{
+#ifdef SCHED_DEADLINE
+       if (policy == SCHED_DEADLINE)
+               return true;
+#endif
+       return supports_custom_slice(policy);
+}
+
+static const char *get_supported_runtime_param_policies(void)
+{
+#if defined(SCHED_BATCH)
+#if defined(SCHED_DEADLINE)
+       return _("SCHED_OTHER, SCHED_BATCH and SCHED_DEADLINE");
+#else
+       return _("SCHED_OTHER and SCHED_BATCH");
+#endif /* SCHED_DEADLINE */
+#elif defined(SCHED_DEADLINE)
+       return _("SCHED_OTHER and SCHED_DEADLINE");
+#else
+       return _("SCHED_OTHER");
+#endif
+}
+
 static void show_sched_pid_info(struct chrt_ctl *ctl, pid_t pid)
 {
        int policy = -1, reset_on_fork = 0, prio = 0;
+       uint64_t runtime = 0;
 #ifdef SCHED_DEADLINE
-       uint64_t deadline = 0, runtime = 0, period = 0;
+       uint64_t deadline = 0, period = 0;
 #endif
 
        /* don't display "pid 0" as that is confusing */
@@ -156,9 +191,11 @@ static void show_sched_pid_info(struct chrt_ctl *ctl, pid_t pid)
                policy = sa.sched_policy;
                prio = sa.sched_priority;
                reset_on_fork = sa.sched_flags & SCHED_FLAG_RESET_ON_FORK;
-               deadline = sa.sched_deadline;
                runtime = sa.sched_runtime;
+#ifdef SCHED_DEADLINE
+               deadline = sa.sched_deadline;
                period = sa.sched_period;
+#endif
        }
 
        /*
@@ -198,6 +235,13 @@ fallback:
        else
                printf(_("pid %d's current scheduling priority: %d\n"), pid, prio);
 
+       if (runtime && supports_custom_slice(policy)) {
+               if (ctl->altered)
+                       printf(_("pid %d's new runtime parameter: %ju\n"), pid, runtime);
+               else
+                       printf(_("pid %d's current runtime parameter: %ju\n"), pid, runtime);
+       }
+
 #ifdef SCHED_DEADLINE
        if (policy == SCHED_DEADLINE) {
                if (ctl->altered)
@@ -296,7 +340,7 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
        struct sched_attr sa = { .size = sizeof(struct sched_attr) };
 
        /* old API is good enough for non-deadline */
-       if (ctl->policy != SCHED_DEADLINE)
+       if (!supports_runtime_param(ctl->policy))
                return set_sched_one_by_setscheduler(ctl, pid);
 
        /* not changed by chrt, follow the current setting */
@@ -452,10 +496,13 @@ int main(int argc, char **argv)
        errno = 0;
        ctl->priority = strtos32_or_err(argv[optind], _("invalid priority argument"));
 
+       if (ctl->runtime && !supports_runtime_param(ctl->policy))
+               errx(EXIT_FAILURE, _("--sched-runtime option is supported for %s"),
+                                    get_supported_runtime_param_policies());
 #ifdef SCHED_DEADLINE
-       if ((ctl->runtime || ctl->deadline || ctl->period) && ctl->policy != SCHED_DEADLINE)
-               errx(EXIT_FAILURE, _("--sched-{runtime,deadline,period} options "
-                                    "are supported for SCHED_DEADLINE only"));
+       if ((ctl->deadline || ctl->period) && ctl->policy != SCHED_DEADLINE)
+               errx(EXIT_FAILURE, _("--sched-{deadline,period} options are "
+                                    "supported for SCHED_DEADLINE only"));
        if (ctl->policy == SCHED_DEADLINE) {
                /* The basic rule is runtime <= deadline <= period, so we can
                 * make deadline and runtime optional on command line. Note we
@@ -468,7 +515,7 @@ int main(int argc, char **argv)
                        ctl->runtime = ctl->deadline;
        }
 #else
-       if (ctl->runtime || ctl->deadline || ctl->period)
+       if (ctl->deadline || ctl->period)
                errx(EXIT_FAILURE, _("SCHED_DEADLINE is unsupported"));
 #endif
        if (ctl->pid == -1)