diff options
Diffstat (limited to 'samples')
| -rw-r--r-- | samples/bpf/bpf_helpers.h | 6 | ||||
| -rw-r--r-- | samples/bpf/tracex2_kern.c | 24 | ||||
| -rw-r--r-- | samples/bpf/tracex2_user.c | 67 |
3 files changed, 83 insertions, 14 deletions
diff --git a/samples/bpf/bpf_helpers.h b/samples/bpf/bpf_helpers.h index f531a0b3282d..bdf1c1607b80 100644 --- a/samples/bpf/bpf_helpers.h +++ b/samples/bpf/bpf_helpers.h | |||
| @@ -25,6 +25,12 @@ static void (*bpf_tail_call)(void *ctx, void *map, int index) = | |||
| 25 | (void *) BPF_FUNC_tail_call; | 25 | (void *) BPF_FUNC_tail_call; |
| 26 | static unsigned long long (*bpf_get_smp_processor_id)(void) = | 26 | static unsigned long long (*bpf_get_smp_processor_id)(void) = |
| 27 | (void *) BPF_FUNC_get_smp_processor_id; | 27 | (void *) BPF_FUNC_get_smp_processor_id; |
| 28 | static unsigned long long (*bpf_get_current_pid_tgid)(void) = | ||
| 29 | (void *) BPF_FUNC_get_current_pid_tgid; | ||
| 30 | static unsigned long long (*bpf_get_current_uid_gid)(void) = | ||
| 31 | (void *) BPF_FUNC_get_current_uid_gid; | ||
| 32 | static int (*bpf_get_current_comm)(void *buf, int buf_size) = | ||
| 33 | (void *) BPF_FUNC_get_current_comm; | ||
| 28 | 34 | ||
| 29 | /* llvm builtin functions that eBPF C program may use to | 35 | /* llvm builtin functions that eBPF C program may use to |
| 30 | * emit BPF_LD_ABS and BPF_LD_IND instructions | 36 | * emit BPF_LD_ABS and BPF_LD_IND instructions |
diff --git a/samples/bpf/tracex2_kern.c b/samples/bpf/tracex2_kern.c index 19ec1cfc45db..dc50f4f2943f 100644 --- a/samples/bpf/tracex2_kern.c +++ b/samples/bpf/tracex2_kern.c | |||
| @@ -62,11 +62,18 @@ static unsigned int log2l(unsigned long v) | |||
| 62 | return log2(v); | 62 | return log2(v); |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | struct hist_key { | ||
| 66 | char comm[16]; | ||
| 67 | u64 pid_tgid; | ||
| 68 | u64 uid_gid; | ||
| 69 | u32 index; | ||
| 70 | }; | ||
| 71 | |||
| 65 | struct bpf_map_def SEC("maps") my_hist_map = { | 72 | struct bpf_map_def SEC("maps") my_hist_map = { |
| 66 | .type = BPF_MAP_TYPE_ARRAY, | 73 | .type = BPF_MAP_TYPE_HASH, |
| 67 | .key_size = sizeof(u32), | 74 | .key_size = sizeof(struct hist_key), |
| 68 | .value_size = sizeof(long), | 75 | .value_size = sizeof(long), |
| 69 | .max_entries = 64, | 76 | .max_entries = 1024, |
| 70 | }; | 77 | }; |
| 71 | 78 | ||
| 72 | SEC("kprobe/sys_write") | 79 | SEC("kprobe/sys_write") |
| @@ -75,11 +82,18 @@ int bpf_prog3(struct pt_regs *ctx) | |||
| 75 | long write_size = ctx->dx; /* arg3 */ | 82 | long write_size = ctx->dx; /* arg3 */ |
| 76 | long init_val = 1; | 83 | long init_val = 1; |
| 77 | long *value; | 84 | long *value; |
| 78 | u32 index = log2l(write_size); | 85 | struct hist_key key = {}; |
| 86 | |||
| 87 | key.index = log2l(write_size); | ||
| 88 | key.pid_tgid = bpf_get_current_pid_tgid(); | ||
| 89 | key.uid_gid = bpf_get_current_uid_gid(); | ||
| 90 | bpf_get_current_comm(&key.comm, sizeof(key.comm)); | ||
| 79 | 91 | ||
| 80 | value = bpf_map_lookup_elem(&my_hist_map, &index); | 92 | value = bpf_map_lookup_elem(&my_hist_map, &key); |
| 81 | if (value) | 93 | if (value) |
| 82 | __sync_fetch_and_add(value, 1); | 94 | __sync_fetch_and_add(value, 1); |
| 95 | else | ||
| 96 | bpf_map_update_elem(&my_hist_map, &key, &init_val, BPF_ANY); | ||
| 83 | return 0; | 97 | return 0; |
| 84 | } | 98 | } |
| 85 | char _license[] SEC("license") = "GPL"; | 99 | char _license[] SEC("license") = "GPL"; |
diff --git a/samples/bpf/tracex2_user.c b/samples/bpf/tracex2_user.c index 91b8d0896fbb..cd0241c1447a 100644 --- a/samples/bpf/tracex2_user.c +++ b/samples/bpf/tracex2_user.c | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
| 4 | #include <signal.h> | 4 | #include <signal.h> |
| 5 | #include <linux/bpf.h> | 5 | #include <linux/bpf.h> |
| 6 | #include <string.h> | ||
| 6 | #include "libbpf.h" | 7 | #include "libbpf.h" |
| 7 | #include "bpf_load.h" | 8 | #include "bpf_load.h" |
| 8 | 9 | ||
| @@ -20,23 +21,42 @@ static void stars(char *str, long val, long max, int width) | |||
| 20 | str[i] = '\0'; | 21 | str[i] = '\0'; |
| 21 | } | 22 | } |
| 22 | 23 | ||
| 23 | static void print_hist(int fd) | 24 | struct task { |
| 25 | char comm[16]; | ||
| 26 | __u64 pid_tgid; | ||
| 27 | __u64 uid_gid; | ||
| 28 | }; | ||
| 29 | |||
| 30 | struct hist_key { | ||
| 31 | struct task t; | ||
| 32 | __u32 index; | ||
| 33 | }; | ||
| 34 | |||
| 35 | #define SIZE sizeof(struct task) | ||
| 36 | |||
| 37 | static void print_hist_for_pid(int fd, void *task) | ||
| 24 | { | 38 | { |
| 25 | int key; | 39 | struct hist_key key = {}, next_key; |
| 40 | char starstr[MAX_STARS]; | ||
| 26 | long value; | 41 | long value; |
| 27 | long data[MAX_INDEX] = {}; | 42 | long data[MAX_INDEX] = {}; |
| 28 | char starstr[MAX_STARS]; | ||
| 29 | int i; | ||
| 30 | int max_ind = -1; | 43 | int max_ind = -1; |
| 31 | long max_value = 0; | 44 | long max_value = 0; |
| 45 | int i, ind; | ||
| 32 | 46 | ||
| 33 | for (key = 0; key < MAX_INDEX; key++) { | 47 | while (bpf_get_next_key(fd, &key, &next_key) == 0) { |
| 34 | bpf_lookup_elem(fd, &key, &value); | 48 | if (memcmp(&next_key, task, SIZE)) { |
| 35 | data[key] = value; | 49 | key = next_key; |
| 36 | if (value && key > max_ind) | 50 | continue; |
| 37 | max_ind = key; | 51 | } |
| 52 | bpf_lookup_elem(fd, &next_key, &value); | ||
| 53 | ind = next_key.index; | ||
| 54 | data[ind] = value; | ||
| 55 | if (value && ind > max_ind) | ||
| 56 | max_ind = ind; | ||
| 38 | if (value > max_value) | 57 | if (value > max_value) |
| 39 | max_value = value; | 58 | max_value = value; |
| 59 | key = next_key; | ||
| 40 | } | 60 | } |
| 41 | 61 | ||
| 42 | printf(" syscall write() stats\n"); | 62 | printf(" syscall write() stats\n"); |
| @@ -48,6 +68,35 @@ static void print_hist(int fd) | |||
| 48 | MAX_STARS, starstr); | 68 | MAX_STARS, starstr); |
| 49 | } | 69 | } |
| 50 | } | 70 | } |
| 71 | |||
| 72 | static void print_hist(int fd) | ||
| 73 | { | ||
| 74 | struct hist_key key = {}, next_key; | ||
| 75 | static struct task tasks[1024]; | ||
| 76 | int task_cnt = 0; | ||
| 77 | int i; | ||
| 78 | |||
| 79 | while (bpf_get_next_key(fd, &key, &next_key) == 0) { | ||
| 80 | int found = 0; | ||
| 81 | |||
| 82 | for (i = 0; i < task_cnt; i++) | ||
| 83 | if (memcmp(&tasks[i], &next_key, SIZE) == 0) | ||
| 84 | found = 1; | ||
| 85 | if (!found) | ||
| 86 | memcpy(&tasks[task_cnt++], &next_key, SIZE); | ||
| 87 | key = next_key; | ||
| 88 | } | ||
| 89 | |||
| 90 | for (i = 0; i < task_cnt; i++) { | ||
| 91 | printf("\npid %d cmd %s uid %d\n", | ||
| 92 | (__u32) tasks[i].pid_tgid, | ||
| 93 | tasks[i].comm, | ||
| 94 | (__u32) tasks[i].uid_gid); | ||
| 95 | print_hist_for_pid(fd, &tasks[i]); | ||
| 96 | } | ||
| 97 | |||
| 98 | } | ||
| 99 | |||
| 51 | static void int_exit(int sig) | 100 | static void int_exit(int sig) |
| 52 | { | 101 | { |
| 53 | print_hist(map_fd[1]); | 102 | print_hist(map_fd[1]); |
