From: Chen Hui judy.chenhui@huawei.com
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I7X7WW
--------------------------------
Add three helper functions: 1) bpf_sched_entity_is_task is to check whether the sched entity is a task struct. 2) bpf_sched_entity_to_task is to change the sched entity to a task struct. 3) bpf_sched_entity_to_tg is to change the sched entity to a task group.
Signed-off-by: Chen Hui judy.chenhui@huawei.com Signed-off-by: Ren Zhijie renzhijie2@huawei.com Signed-off-by: Hui Tang tanghui20@huawei.com Signed-off-by: Guan Jing guanjing6@huawei.com --- include/uapi/linux/bpf.h | 21 +++++++++++ kernel/sched/bpf_sched.c | 69 ++++++++++++++++++++++++++++++++-- scripts/bpf_doc.py | 2 + tools/include/uapi/linux/bpf.h | 21 +++++++++++ 4 files changed, 109 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index cb37b50acccd..b224509c795b 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -5619,6 +5619,24 @@ union bpf_attr { * Get system cpus returned in *cpus*. * Return * 0 on success, or a negative error in case of failure. + * + * long bpf_sched_entity_is_task(struct sched_entity *se) + * Description + * Checks whether the sched entity is a task. + * Return + * 1 if true, 0 otherwise. + * + * struct task_struct *bpf_sched_entity_to_task(struct sched_entity *se) + * Description + * Return task struct of *se* if se is a task. + * Return + * Task struct if se is a task, NULL otherwise. + * + * struct task_group *bpf_sched_entity_to_tg(struct sched_entity *se) + * Description + * Return task group of *se* if se is a task group. + * Return + * Task struct if se is a task group, NULL otherwise. */ #define ___BPF_FUNC_MAPPER(FN, ctx...) \ FN(unspec, 0, ##ctx) \ @@ -5842,6 +5860,9 @@ union bpf_attr { FN(sched_cpu_stats_of, 218, ##ctx) \ FN(init_cpu_topology, 219, ##ctx) \ FN(get_cpumask_info, 220, ##ctx) \ + FN(sched_entity_is_task, 221, ##ctx) \ + FN(sched_entity_to_task, 222, ##ctx) \ + FN(sched_entity_to_tg, 223, ##ctx) \ /* */
/* backwards-compatibility macros for users of __BPF_FUNC_MAPPER that don't diff --git a/kernel/sched/bpf_sched.c b/kernel/sched/bpf_sched.c index e768b465d684..f0ec3462ff17 100644 --- a/kernel/sched/bpf_sched.c +++ b/kernel/sched/bpf_sched.c @@ -119,6 +119,65 @@ static const struct bpf_func_proto bpf_sched_cpu_stats_of_proto = { .arg3_type = ARG_CONST_SIZE, };
+BTF_ID_LIST_SINGLE(btf_sched_entity_ids, struct, sched_entity) +BTF_ID_LIST_SINGLE(btf_sched_task_ids, struct, task_struct) +BTF_ID_LIST_SINGLE(btf_sched_tg_ids, struct, task_group) + +BPF_CALL_1(bpf_sched_entity_is_task, struct sched_entity *, se) +{ + return entity_is_task(se) ? 1 : 0; +} + +static const struct bpf_func_proto bpf_sched_entity_is_task_proto = { + .func = bpf_sched_entity_is_task, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_BTF_ID, + .arg1_btf_id = &btf_sched_entity_ids[0], +}; + +BPF_CALL_1(bpf_sched_entity_to_task, struct sched_entity *, se) +{ + if (entity_is_task(se)) { + struct task_struct *tsk = task_of(se); + + return (unsigned long)tsk; + } + + return (unsigned long)NULL; +} + +static const struct bpf_func_proto bpf_sched_entity_to_task_proto = { + .func = bpf_sched_entity_to_task, + .gpl_only = false, + .ret_type = RET_PTR_TO_BTF_ID_OR_NULL, + .ret_btf_id = &btf_sched_task_ids[0], + .arg1_type = ARG_PTR_TO_BTF_ID, + .arg1_btf_id = &btf_sched_entity_ids[0], +}; + +BPF_CALL_1(bpf_sched_entity_to_tg, struct sched_entity *, se) +{ +#if CONFIG_FAIR_GROUP_SCHED + if (!entity_is_task(se)) { + struct task_group *tg = group_cfs_rq(se)->tg; + + return (unsigned long)tg; + } +#endif + + return (unsigned long)NULL; +} + +static const struct bpf_func_proto bpf_sched_entity_to_tg_proto = { + .func = bpf_sched_entity_to_tg, + .gpl_only = false, + .ret_type = RET_PTR_TO_BTF_ID_OR_NULL, + .ret_btf_id = &btf_sched_tg_ids[0], + .arg1_type = ARG_PTR_TO_BTF_ID, + .arg1_btf_id = &btf_sched_entity_ids[0], +}; + static const struct bpf_func_proto * bpf_sched_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) { @@ -131,6 +190,12 @@ bpf_sched_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_init_cpu_topology_proto; case BPF_FUNC_get_cpumask_info: return &bpf_get_cpumask_info_proto; + case BPF_FUNC_sched_entity_is_task: + return &bpf_sched_entity_is_task_proto; + case BPF_FUNC_sched_entity_to_task: + return &bpf_sched_entity_to_task_proto; + case BPF_FUNC_sched_entity_to_tg: + return &bpf_sched_entity_to_tg_proto; default: return bpf_base_func_proto(func_id); } @@ -157,8 +222,6 @@ BPF_CALL_1(bpf_sched_tg_tag_of, struct task_group *, tg) return ret; }
-BTF_ID_LIST_SINGLE(btf_sched_tg_ids, struct, task_group) - const struct bpf_func_proto bpf_sched_tg_tag_of_proto = { .func = bpf_sched_tg_tag_of, .gpl_only = false, @@ -174,8 +237,6 @@ BPF_CALL_1(bpf_sched_task_tag_of, struct task_struct *, tsk) return tsk->tag; }
-BTF_ID_LIST_SINGLE(btf_sched_task_ids, struct, task_struct) - const struct bpf_func_proto bpf_sched_task_tag_of_proto = { .func = bpf_sched_task_tag_of, .gpl_only = false, diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py index b23f07438978..11cf353ad57f 100755 --- a/scripts/bpf_doc.py +++ b/scripts/bpf_doc.py @@ -704,6 +704,7 @@ class PrinterHelpers(Printer): 'struct bpf_sched_cpu_stats', 'struct bpf_cpu_topology', 'struct bpf_cpumask_info', + 'struct sched_entity', ] known_types = { '...', @@ -763,6 +764,7 @@ class PrinterHelpers(Printer): 'struct bpf_sched_cpu_stats', 'struct bpf_cpu_topology', 'struct bpf_cpumask_info', + 'struct sched_entity', } mapped_types = { 'u8': '__u8', diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index cb37b50acccd..b224509c795b 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -5619,6 +5619,24 @@ union bpf_attr { * Get system cpus returned in *cpus*. * Return * 0 on success, or a negative error in case of failure. + * + * long bpf_sched_entity_is_task(struct sched_entity *se) + * Description + * Checks whether the sched entity is a task. + * Return + * 1 if true, 0 otherwise. + * + * struct task_struct *bpf_sched_entity_to_task(struct sched_entity *se) + * Description + * Return task struct of *se* if se is a task. + * Return + * Task struct if se is a task, NULL otherwise. + * + * struct task_group *bpf_sched_entity_to_tg(struct sched_entity *se) + * Description + * Return task group of *se* if se is a task group. + * Return + * Task struct if se is a task group, NULL otherwise. */ #define ___BPF_FUNC_MAPPER(FN, ctx...) \ FN(unspec, 0, ##ctx) \ @@ -5842,6 +5860,9 @@ union bpf_attr { FN(sched_cpu_stats_of, 218, ##ctx) \ FN(init_cpu_topology, 219, ##ctx) \ FN(get_cpumask_info, 220, ##ctx) \ + FN(sched_entity_is_task, 221, ##ctx) \ + FN(sched_entity_to_task, 222, ##ctx) \ + FN(sched_entity_to_tg, 223, ##ctx) \ /* */
/* backwards-compatibility macros for users of __BPF_FUNC_MAPPER that don't