1 // SPDX-License-Identifier: GPL-2.0
8 #include <sys/resource.h>
17 static void stars(char *str
, long val
, long max
, int width
)
21 for (i
= 0; i
< (width
* val
/ max
) - 1 && i
< width
- 1; i
++)
39 #define SIZE sizeof(struct task)
41 static void print_hist_for_pid(int fd
, void *task
)
43 unsigned int nr_cpus
= bpf_num_possible_cpus();
44 struct hist_key key
= {}, next_key
;
46 char starstr
[MAX_STARS
];
48 long data
[MAX_INDEX
] = {};
53 while (bpf_map_get_next_key(fd
, &key
, &next_key
) == 0) {
54 if (memcmp(&next_key
, task
, SIZE
)) {
58 bpf_map_lookup_elem(fd
, &next_key
, values
);
60 for (i
= 0; i
< nr_cpus
; i
++)
64 if (value
&& ind
> max_ind
)
66 if (value
> max_value
)
71 printf(" syscall write() stats\n");
72 printf(" byte_size : count distribution\n");
73 for (i
= 1; i
<= max_ind
+ 1; i
++) {
74 stars(starstr
, data
[i
- 1], max_value
, MAX_STARS
);
75 printf("%8ld -> %-8ld : %-8ld |%-*s|\n",
76 (1l << i
) >> 1, (1l << i
) - 1, data
[i
- 1],
81 static void print_hist(int fd
)
83 struct hist_key key
= {}, next_key
;
84 static struct task tasks
[1024];
88 while (bpf_map_get_next_key(fd
, &key
, &next_key
) == 0) {
91 for (i
= 0; i
< task_cnt
; i
++)
92 if (memcmp(&tasks
[i
], &next_key
, SIZE
) == 0)
95 memcpy(&tasks
[task_cnt
++], &next_key
, SIZE
);
99 for (i
= 0; i
< task_cnt
; i
++) {
100 printf("\npid %d cmd %s uid %d\n",
101 (__u32
) tasks
[i
].pid_tgid
,
103 (__u32
) tasks
[i
].uid_gid
);
104 print_hist_for_pid(fd
, &tasks
[i
]);
109 static void int_exit(int sig
)
111 print_hist(map_fd
[1]);
115 int main(int ac
, char **argv
)
117 struct rlimit r
= {1024*1024, RLIM_INFINITY
};
119 long key
, next_key
, value
;
123 snprintf(filename
, sizeof(filename
), "%s_kern.o", argv
[0]);
125 if (setrlimit(RLIMIT_MEMLOCK
, &r
)) {
126 perror("setrlimit(RLIMIT_MEMLOCK)");
130 signal(SIGINT
, int_exit
);
131 signal(SIGTERM
, int_exit
);
133 /* start 'ping' in the background to have some kfree_skb events */
134 f
= popen("ping -c5 localhost", "r");
137 /* start 'dd' in the background to have plenty of 'write' syscalls */
138 f
= popen("dd if=/dev/zero of=/dev/null count=5000000", "r");
141 if (load_bpf_file(filename
)) {
142 printf("%s", bpf_log_buf
);
146 for (i
= 0; i
< 5; i
++) {
148 while (bpf_map_get_next_key(map_fd
[0], &key
, &next_key
) == 0) {
149 bpf_map_lookup_elem(map_fd
[0], &next_key
, &value
);
150 printf("location 0x%lx count %ld\n", next_key
, value
);
157 print_hist(map_fd
[1]);