From: Furkan Caliskan Date: Mon, 11 May 2026 14:10:30 +0000 (+0300) Subject: chrt: Add support for (GRUB) bandwidth reclaim X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=81c2eb29486281367b81baaa8ddf0f27f60877d3;p=thirdparty%2Futil-linux.git chrt: Add support for (GRUB) bandwidth reclaim The SCHED_DEADLINE policy supports the (GRUB) Greedy Reclamation of Unused Bandwidth algorithm. This allows tasks to reclaim bandwidth that are left over by other deadline tasks that finish their work early, or voluntarily yield the cpu. Currently, chrt has no way to set the SCHED_FLAG_RECLAIM bit in the sched_flags field of the sched_attr structure. Add -G/--reclaim-grub option to allow users to toggle this feature using the deadline scheduling class. [kzak@redhat.com: - add missing #ifdef SCHED_FLAG_RECLAIM guards - add comments to #else/#endif for SCHED_DEADLINE block] Signed-off-by: Furkan Caliskan --- diff --git a/bash-completion/chrt b/bash-completion/chrt index 3ca13fc05..363efdfa1 100644 --- a/bash-completion/chrt +++ b/bash-completion/chrt @@ -26,6 +26,7 @@ _chrt_module() --max --other --pid + --reclaim-grub --reset-on-fork --rr --sched-deadline diff --git a/schedutils/chrt.1.adoc b/schedutils/chrt.1.adoc index 4c6dbde1c..7c2ceab86 100644 --- a/schedutils/chrt.1.adoc +++ b/schedutils/chrt.1.adoc @@ -82,6 +82,9 @@ Specifies period parameter for *SCHED_DEADLINE* policy (Linux-specific). Note th *-D*, *--sched-deadline* _nanoseconds_:: Specifies deadline parameter for *SCHED_DEADLINE* policy (Linux-specific). +*-G*, *--reclaim-grub*:: +Enables GRUB (Greedy Reclamation of Unused Bandwidth) algorithm. Linux-specific, supported since 4.13. + *-R*, *--reset-on-fork*:: Use *SCHED_RESET_ON_FORK* or *SCHED_FLAG_RESET_ON_FORK* flag. Linux-specific, supported since 2.6.31. + diff --git a/schedutils/chrt.c b/schedutils/chrt.c index c5bef5478..c1895d117 100644 --- a/schedutils/chrt.c +++ b/schedutils/chrt.c @@ -49,6 +49,7 @@ struct chrt_ctl { uint64_t runtime; /* --sched-* options */ uint64_t deadline; uint64_t period; + uint64_t sched_flags; /* For sched_attr->sched_flags member */ unsigned int all_tasks : 1, /* all threads of the PID */ reset_on_fork : 1, /* SCHED_RESET_ON_FORK or SCHED_FLAG_RESET_ON_FORK */ @@ -91,6 +92,7 @@ static void __attribute__((__noreturn__)) usage(void) fputs(USAGE_SEPARATOR, out); fputs(_("Scheduling options:\n"), out); fputs(_(" -R, --reset-on-fork set reset-on-fork flag\n"), out); + fputs(_(" -G, --reclaim-grub set SCHED_FLAG_RECLAIM\n"), out); fputs(_(" -T, --sched-runtime runtime parameter for DEADLINE\n"), out); fputs(_(" -P, --sched-period period parameter for DEADLINE\n"), out); fputs(_(" -D, --sched-deadline deadline parameter for DEADLINE\n"), out); @@ -386,6 +388,7 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid) sa.sched_runtime = ctl->runtime; sa.sched_period = ctl->period; sa.sched_deadline = ctl->deadline; + sa.sched_flags = ctl->sched_flags; # ifdef SCHED_FLAG_RESET_ON_FORK /* Don't use SCHED_RESET_ON_FORK for sched_setattr()! */ @@ -447,6 +450,7 @@ int main(int argc, char **argv) { "sched-period", required_argument, NULL, 'P' }, { "sched-deadline", required_argument, NULL, 'D' }, { "reset-on-fork", no_argument, NULL, 'R' }, + { "reclaim-grub", no_argument, NULL, 'G' }, { "verbose", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, { NULL, no_argument, NULL, 0 } @@ -457,7 +461,7 @@ int main(int argc, char **argv) textdomain(PACKAGE); close_stdout_atexit(); - while((c = getopt_long(argc, argv, "+abdD:efiphmoP:T:rRvV", longopts, NULL)) != -1) + while((c = getopt_long(argc, argv, "+abdD:efiphmoP:T:rRGvV", longopts, NULL)) != -1) { switch (c) { case 'a': @@ -490,6 +494,11 @@ int main(int argc, char **argv) case 'R': ctl->reset_on_fork = 1; break; + case 'G': +#ifdef SCHED_FLAG_RECLAIM + ctl->sched_flags |= SCHED_FLAG_RECLAIM; +#endif + break; case 'i': #ifdef SCHED_IDLE ctl->policy = SCHED_IDLE; @@ -578,6 +587,14 @@ int main(int argc, char **argv) if ((ctl->deadline || ctl->period) && ctl->policy != SCHED_DEADLINE) errx(EXIT_FAILURE, _("--sched-{deadline,period} options are " "supported for SCHED_DEADLINE only")); +# ifdef SCHED_FLAG_RECLAIM +# ifndef HAVE_SCHED_SETATTR + if (ctl->sched_flags & SCHED_FLAG_RECLAIM) + errx(EXIT_FAILURE, _("SCHED_FLAG_RECLAIM is unsupported")); +# endif + if ((ctl->sched_flags & SCHED_FLAG_RECLAIM) && ctl->policy != SCHED_DEADLINE) + errx(EXIT_FAILURE, _("--reclaim-grub is only supported for SCHED_DEADLINE")); +# endif 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 @@ -589,10 +606,10 @@ int main(int argc, char **argv) if (ctl->runtime == 0) ctl->runtime = ctl->deadline; } -#else +#else /* !SCHED_DEADLINE */ if (ctl->deadline || ctl->period) errx(EXIT_FAILURE, _("SCHED_DEADLINE is unsupported")); -#endif +#endif /* SCHED_DEADLINE */ if (ctl->priority < sched_get_priority_min(ctl->policy) || sched_get_priority_max(ctl->policy) < ctl->priority) errx(EXIT_FAILURE,