提交 462eaba1 编写于 作者: R Ren Zhijie 提交者: Zheng Zengkai

samples: bpf: Add bpf sched preempt sample program

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I5KUFB
CVE: NA

--------------------------------

This program can choose program by args [-W|-T|-E]
to attach BPF_SCHED hooks which in preempt process and then
matches task or task group which has tag TASK_TYPE_ONLINE and
TASK_TYPE_OFFLINE.

This will return different value to hook function which use to
indicate whether to preempt the current sched entity.

To run,

  # sched_preempt [-W|-T|-E|-h]
  # USAGE: sched_preempt [...]
  #        -W    # Test sched preempt wakeup
  #        -T    # Test sched preempt tick
  #        -E    # Test wakeup preempt entity
Signed-off-by: NChen Hui <judy.chenhui@huawei.com>
Signed-off-by: NRen Zhijie <renzhijie2@huawei.com>
上级 2e51838a
...@@ -54,6 +54,7 @@ tprogs-y += task_fd_query ...@@ -54,6 +54,7 @@ tprogs-y += task_fd_query
tprogs-y += xdp_sample_pkts tprogs-y += xdp_sample_pkts
tprogs-y += ibumad tprogs-y += ibumad
tprogs-y += hbm tprogs-y += hbm
tprogs-y += sched_preempt
# Libbpf dependencies # Libbpf dependencies
LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a
...@@ -111,6 +112,7 @@ task_fd_query-objs := bpf_load.o task_fd_query_user.o $(TRACE_HELPERS) ...@@ -111,6 +112,7 @@ task_fd_query-objs := bpf_load.o task_fd_query_user.o $(TRACE_HELPERS)
xdp_sample_pkts-objs := xdp_sample_pkts_user.o $(TRACE_HELPERS) xdp_sample_pkts-objs := xdp_sample_pkts_user.o $(TRACE_HELPERS)
ibumad-objs := bpf_load.o ibumad_user.o $(TRACE_HELPERS) ibumad-objs := bpf_load.o ibumad_user.o $(TRACE_HELPERS)
hbm-objs := bpf_load.o hbm.o $(CGROUP_HELPERS) hbm-objs := bpf_load.o hbm.o $(CGROUP_HELPERS)
sched_preempt-objs := sched_preempt_user.o
# Tell kbuild to always build the programs # Tell kbuild to always build the programs
always-y := $(tprogs-y) always-y := $(tprogs-y)
...@@ -172,6 +174,7 @@ always-y += ibumad_kern.o ...@@ -172,6 +174,7 @@ always-y += ibumad_kern.o
always-y += hbm_out_kern.o always-y += hbm_out_kern.o
always-y += hbm_edt_kern.o always-y += hbm_edt_kern.o
always-y += xdpsock_kern.o always-y += xdpsock_kern.o
always-y += sched_preempt_kern.o
ifeq ($(ARCH), arm) ifeq ($(ARCH), arm)
# Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux # Strip all except -D__LINUX_ARM_ARCH__ option needed to handle linux
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/version.h>
#include <linux/sched.h>
#include <uapi/linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
unsigned long idea_runtime = 1000000UL;
enum task_type {
TASK_TYPE_OFFLINE = -1,
TASK_TYPE_NORMAL,
TASK_TYPE_ONLINE,
};
#define getVal(P) \
({ \
typeof(P) val = 0; \
bpf_probe_read_kernel(&val, sizeof(val), &(P)); \
val; \
})
#define bprintk(fmt, ...) \
({ \
char ____fmt[] = fmt; \
bpf_trace_printk(____fmt, sizeof(____fmt), \
##__VA_ARGS__); \
})
SEC("sched/cfs_check_preempt_wakeup")
int BPF_PROG(sched_cfs_check_preempt_wakeup, struct task_struct *curr, struct task_struct *p)
{
long curr_type, p_type;
int ret = 0;
curr_type = bpf_sched_task_tag_of(curr);
p_type = bpf_sched_task_tag_of(p);
if (curr_type == TASK_TYPE_ONLINE && p_type == TASK_TYPE_OFFLINE)
ret = -1;
if (curr_type == TASK_TYPE_OFFLINE && p_type == TASK_TYPE_ONLINE)
ret = 1;
bprintk("check_preempt_wakeup: curr id = %d, p id = %d, preempt result is %d\n",
getVal(curr->pid), getVal(p->pid), ret);
return ret;
}
SEC("sched/cfs_check_preempt_tick")
int BPF_PROG(sched_cfs_check_preempt_tick, struct sched_entity *curr, unsigned long delta_exec)
{
long curr_type = TASK_TYPE_NORMAL;
int ret = 0, id = 0;
int entity_is_task = bpf_sched_entity_is_task(curr);
if (entity_is_task) {
struct task_struct *tsk = bpf_sched_entity_to_task(curr);
if (tsk) {
curr_type = bpf_sched_task_tag_of(tsk);
id = getVal(tsk->pid);
}
} else {
struct task_group *tg = bpf_sched_entity_to_tg(curr);
if (tg) {
curr_type = bpf_sched_tg_tag_of(tg);
id = bpf_sched_entity_to_cgrpid(curr);
}
}
if (curr_type == TASK_TYPE_ONLINE)
ret = delta_exec >= idea_runtime ? 1 : -1;
bprintk("check_preempt_tick: delta = %lu, entity id = %d, preempt result = %d\n",
delta_exec, id, ret);
return ret;
}
SEC("sched/cfs_wakeup_preempt_entity")
int BPF_PROG(sched_cfs_wakeup_preempt_entity, struct sched_entity *curr, struct sched_entity *se)
{
long curr_type = TASK_TYPE_NORMAL;
long p_type = TASK_TYPE_NORMAL;
int curr_id = 0, p_id = 0;
int curr_is_task = bpf_sched_entity_is_task(curr);
int p_is_task = bpf_sched_entity_is_task(se);
int ret = 0;
if (curr_is_task) {
struct task_struct *tsk = bpf_sched_entity_to_task(curr);
if (tsk) {
curr_type = bpf_sched_task_tag_of(tsk);
curr_id = getVal(tsk->pid);
}
} else {
struct task_group *tg = bpf_sched_entity_to_tg(curr);
if (tg) {
curr_type = bpf_sched_tg_tag_of(tg);
curr_id = bpf_sched_entity_to_cgrpid(curr);
}
}
if (p_is_task) {
struct task_struct *p = bpf_sched_entity_to_task(se);
if (p) {
p_type = bpf_sched_task_tag_of(p);
p_id = getVal(p->pid);
}
} else {
struct task_group *tg1 = bpf_sched_entity_to_tg(se);
if (tg1) {
p_type = bpf_sched_tg_tag_of(tg1);
p_id = bpf_sched_entity_to_cgrpid(se);
}
}
if (curr_type == TASK_TYPE_ONLINE && p_type == TASK_TYPE_OFFLINE)
ret = -1;
if (curr_type == TASK_TYPE_OFFLINE && p_type == TASK_TYPE_ONLINE)
ret = 1;
bprintk("wakeup_preempt_entity: curr entity id = %d, se entity id = %d, result = %d\n",
curr_id, p_id, ret);
return ret;
}
char _license[] SEC("license") = "GPL";
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2022. Huawei Technologies Co., Ltd. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/resource.h>
#include <bpf/libbpf.h>
#define MAX_PROGS (3)
#define TRACE_DIR "/sys/kernel/debug/tracing/"
#define BUF_SIZE (4096)
int progindex[MAX_PROGS];
static void usage(void)
{
printf("USAGE: sched_preempt [...]\n");
printf(" -W # Test sched preempt wakeup\n");
printf(" -T # Test sched preempt tick\n");
printf(" -E # Test wakeup preempt entity\n");
printf(" -h # Display this help\n");
}
/* read trace logs from debug fs */
static void read_trace_pipe(void)
{
int trace_fd;
trace_fd = open(TRACE_DIR "trace_pipe", O_RDONLY, 0);
if (trace_fd < 0)
return;
while (1) {
static char buf[BUF_SIZE];
ssize_t sz;
sz = read(trace_fd, buf, sizeof(buf) - 1);
if (sz > 0) {
buf[sz] = 0;
puts(buf);
}
}
}
static inline bool check_attach_prog(int index)
{
return progindex[index] ? true : false;
}
int main(int argc, char **argv)
{
int opt;
int index;
char filename[256];
struct bpf_object *obj;
struct bpf_program *prog;
struct bpf_link *link[3] = {NULL};
char prognames[MAX_PROGS][256] = {
"sched_cfs_check_preempt_wakeup",
"sched_cfs_check_preempt_tick",
"sched_cfs_wakeup_preempt_entity",
};
while ((opt = getopt(argc, argv, "WTEh")) != -1) {
switch (opt) {
case 'W':
progindex[0] = 1;
break;
case 'T':
progindex[1] = 1;
break;
case 'E':
progindex[2] = 1;
break;
case 'h':
default:
usage();
goto out;
}
}
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
obj = bpf_object__open_file(filename, NULL);
if (libbpf_get_error(obj)) {
fprintf(stderr, "ERROR: opening BPF object file failed\n");
goto out;
}
/* load BPF program */
if (bpf_object__load(obj)) {
fprintf(stderr, "ERROR: loading BPF object file failed\n");
goto cleanup;
}
for (index = 0; index < MAX_PROGS; ++index) {
if (check_attach_prog(index)) {
prog = bpf_object__find_program_by_name(obj, prognames[index]);
if (libbpf_get_error(prog)) {
fprintf(stderr, "ERROR: finding a prog:%s in obj file failed\n",
prognames[index]);
goto cleanup;
}
link[index] = bpf_program__attach(prog);
if (libbpf_get_error(link[index])) {
fprintf(stderr, "ERROR: bpf_program__attach failed\n");
link[index] = NULL;
goto cleanup;
}
}
}
printf("preempt BPF started, hit Ctrl+C to stop!\n");
read_trace_pipe();
cleanup:
for (index = MAX_PROGS - 1; index >= 0; index--)
bpf_link__destroy(link[index]);
bpf_object__close(obj);
out:
return 0;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册