aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWill Deacon <will@kernel.org>2023-06-07 22:40:26 +0100
committerWill Deacon <will@kernel.org>2023-06-08 11:52:50 +0100
commit088ba823231ebf8f2c309128a06e1ad5a4716be4 (patch)
treee8d1cf99b352b7c1fc36b17491ca57fbf65c2fe5
parenta0cef1063f808d7ac0679631e8744684ff390dd7 (diff)
downloadlinux-kvm/bpf.tar.gz
bpf: Add uclamp helperkvm/bpf
Introduce a new bpf helper function, bpf_set_current_uclamp(), which wraps sched_setattr() and allows a bpf program to specify the minimum and maximum utilisation values for its task context. Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--include/uapi/linux/bpf.h10
-rw-r--r--kernel/bpf/helpers.c26
2 files changed, 36 insertions, 0 deletions
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index fe8aab4eb79f5a..7aac488d6cc4de 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -5528,6 +5528,15 @@ union bpf_attr {
* Return
* The capacity of *cpu* or 0 if *cpu* does not correspond to a
* valid CPU.
+ *
+ * int bpf_set_current_uclamp(u32 sched_util_min, u32 sched_util_max)
+ * Description
+ * Set the uclamp utilization constaints for the current task.
+ * Note that this differs slightly from the sched_setattr(2)
+ * interface in that a util value of -1 is ignored rather
+ * than resetting to the system default.
+ * Return
+ * 0 on success, negative error code otherwise.
*/
#define ___BPF_FUNC_MAPPER(FN, ctx...) \
FN(unspec, 0, ##ctx) \
@@ -5745,6 +5754,7 @@ union bpf_attr {
FN(get_cpu_freq, 212, ##ctx) \
FN(get_cpu_hw_max_freq, 213, ##ctx) \
FN(get_cpu_scale, 214, ##ctx) \
+ FN(set_current_uclamp, 215, ##ctx) \
/* */
/* backwards-compatibility macros for users of __BPF_FUNC_MAPPER that don't
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 1e4e4a38de9902..d346cb11e3507a 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -24,6 +24,8 @@
#include <linux/btf_ids.h>
#include <linux/bpf_mem_alloc.h>
+#include <uapi/linux/sched/types.h>
+
#include "../../lib/kstrtox.h"
/* If kernel subsystem is allowing eBPF programs to call this function,
@@ -481,6 +483,28 @@ const struct bpf_func_proto bpf_get_cpu_scale_proto = {
.ret_type = RET_INTEGER,
.arg1_type = ARG_ANYTHING,
};
+
+BPF_CALL_2(bpf_set_current_uclamp, u32, sched_util_min, u32, sched_util_max)
+{
+ u32 uc_flags = (sched_util_min != -1 ? SCHED_FLAG_UTIL_CLAMP_MIN : 0) |
+ (sched_util_max != -1 ? SCHED_FLAG_UTIL_CLAMP_MAX : 0) ;
+ struct sched_attr attr = {
+ .sched_policy = -1 /* SETPARAM_POLICY */,
+ .sched_flags = uc_flags | SCHED_FLAG_KEEP_ALL,
+ .sched_util_min = sched_util_min,
+ .sched_util_max = sched_util_max,
+ };
+
+ return sched_setattr(current, &attr);
+}
+
+const struct bpf_func_proto bpf_set_current_uclamp_proto = {
+ .func = bpf_set_current_uclamp,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_ANYTHING,
+ .arg2_type = ARG_ANYTHING,
+};
#endif /* CONFIG_CPU_FREQ */
#define BPF_STRTOX_BASE_MASK 0x1F
@@ -1750,6 +1774,8 @@ bpf_base_func_proto(enum bpf_func_id func_id)
return &bpf_get_cpu_hw_max_freq_proto;
case BPF_FUNC_get_cpu_scale:
return &bpf_get_cpu_scale_proto;
+ case BPF_FUNC_set_current_uclamp:
+ return &bpf_set_current_uclamp_proto;
#endif
default:
break;