No standard, but part of util-linux. --- toys/pending/uclampset.c | 119 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 toys/pending/uclampset.c
From 9ddf2d65915fd1a4fe3f602292bbbae71b9bdb5a Mon Sep 17 00:00:00 2001 From: Elliott Hughes <e...@google.com> Date: Thu, 9 Dec 2021 17:29:03 -0800 Subject: [PATCH] Add uclampset(1).
No standard, but part of util-linux. --- toys/pending/uclampset.c | 119 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 toys/pending/uclampset.c diff --git a/toys/pending/uclampset.c b/toys/pending/uclampset.c new file mode 100644 index 00000000..e59f0d33 --- /dev/null +++ b/toys/pending/uclampset.c @@ -0,0 +1,119 @@ +/* uclampset.c - Set/get processes' utilization clamping attributes. + * + * Copyright 2021 The Android Open Source Project + * + * No standard. See https://man7.org/linux/man-pages/man1/uclampset.1.html + +USE_TASKSET(NEWTOY(uclampset, "p#am#M#R", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT)) + +config UCLAMPSET + bool "uclampset" + default y + help + usage: uclampset [-p PID] [-m MIN] [-M MAX] [CMD [ARG...]] + + Set/get utilization clamping attributes for new or existing processes. + + -a Apply to all the tasks/threads for the given PID + -m MIN Set the minimum + -M MAX Set the maximum + -p PID Apply to PID rather than launching a command + -R Set SCHED_FLAG_RESET_ON_FORK +*/ + +#define FOR_uclampset +#include "toys.h" + +GLOBALS( + long M, m, p; + + int set; +) + +#include <sys/syscall.h> +// The uclamp flags and fields in struct sched_attr were added to the kernel +// in 2019, so we can't rely on the headers yet. +#define SCHED_FLAG_RESET_ON_FORK 0x01 +#define SCHED_FLAG_KEEP_POLICY 0x08 +#define SCHED_FLAG_KEEP_PARAMS 0x10 +#define SCHED_FLAG_UTIL_CLAMP_MIN 0x20 +#define SCHED_FLAG_UTIL_CLAMP_MAX 0x40 +#define sched_getattr(pid, attr) \ + syscall(__NR_sched_getattr, pid, attr, sizeof(struct sched_attr_v2), 0) +#define sched_setattr(pid, attr, flags) \ + syscall(__NR_sched_setattr, pid, attr, flags) +struct sched_attr_v2 { + unsigned size; + unsigned sched_policy; + unsigned long long sched_flags; + int sched_nice; + unsigned sched_priority; + unsigned long long sched_runtime; + unsigned long long sched_deadline; + unsigned long long sched_period; + // These fields aren't in v1 of the struct. + unsigned sched_util_min; + unsigned sched_util_max; +}; + +static void do_uclampset(pid_t pid) +{ + struct sched_attr_v2 *sa = (struct sched_attr_v2 *)toybuf; + + if (TT.set) { + if (sched_setattr(pid, sa, 0)) perror_exit("sched_setattr for pid %d", pid); + } else { + char path[33], *comm; + size_t len; + + if (sched_getattr(pid, sa)) perror_exit("sched_getattr for pid %d", pid); + sprintf(path, "/proc/%u/comm", pid); + comm = xreadfile(path, 0, 0); + len = strlen(comm); + if (comm[len-1] == '\n') comm[len-1] = 0; + printf("%s (%d) util_clamp: min: %u max: %u\n", comm, pid, + sa->sched_util_min, sa->sched_util_max); + free(comm); + } +} + +static int task_callback(struct dirtree *new) +{ + if (!new->parent) return DIRTREE_RECURSE; + if (isdigit(*new->name)) do_uclampset(atoi(new->name)); + + return 0; +} + +void uclampset_main(void) +{ + struct sched_attr_v2* sa = (struct sched_attr_v2 *)toybuf; + + memset(sa, 0, sizeof(*sa)); + sa->size = sizeof(*sa); + sa->sched_flags = SCHED_FLAG_KEEP_POLICY | SCHED_FLAG_KEEP_PARAMS; + if (FLAG(R)) { + sa->sched_flags |= SCHED_FLAG_RESET_ON_FORK; + TT.set = 1; + } + if (FLAG(m)) { + sa->sched_flags |= SCHED_FLAG_UTIL_CLAMP_MIN; + sa->sched_util_min = TT.m; + TT.set = 1; + } + if (FLAG(M)) { + sa->sched_flags |= SCHED_FLAG_UTIL_CLAMP_MAX; + sa->sched_util_max = TT.M; + TT.set = 1; + } + + if (!FLAG(p)) { + if (toys.optc < 1) error_exit("Need -p PID or CMD [ARG...]"); + do_uclampset(getpid()); + xexec(toys.optargs); + } else if (FLAG(a)) { + char buf[33]; + sprintf(buf, "/proc/%ld/task/", TT.p); + dirtree_read(buf, task_callback); + } else do_uclampset(TT.p); +} -- 2.34.1.173.g76aa8bc2d0-goog
_______________________________________________ Toybox mailing list Toybox@lists.landley.net http://lists.landley.net/listinfo.cgi/toybox-landley.net