xref: /linux/samples/bpf/lathist_user.c (revision 3bdab16c55f57a24245c97d707241dd9b48d1a91)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com
3  * Copyright (c) 2015 BMW Car IT GmbH
4  */
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <stdlib.h>
8 #include <signal.h>
9 #include <linux/bpf.h>
10 #include <bpf/bpf.h>
11 #include "bpf_load.h"
12 
13 #define MAX_ENTRIES	20
14 #define MAX_CPU		4
15 #define MAX_STARS	40
16 
17 struct cpu_hist {
18 	long data[MAX_ENTRIES];
19 	long max;
20 };
21 
22 static struct cpu_hist cpu_hist[MAX_CPU];
23 
24 static void stars(char *str, long val, long max, int width)
25 {
26 	int i;
27 
28 	for (i = 0; i < (width * val / max) - 1 && i < width - 1; i++)
29 		str[i] = '*';
30 	if (val > max)
31 		str[i - 1] = '+';
32 	str[i] = '\0';
33 }
34 
35 static void print_hist(void)
36 {
37 	char starstr[MAX_STARS];
38 	struct cpu_hist *hist;
39 	int i, j;
40 
41 	/* clear screen */
42 	printf("\033[2J");
43 
44 	for (j = 0; j < MAX_CPU; j++) {
45 		hist = &cpu_hist[j];
46 
47 		/* ignore CPUs without data (maybe offline?) */
48 		if (hist->max == 0)
49 			continue;
50 
51 		printf("CPU %d\n", j);
52 		printf("      latency        : count     distribution\n");
53 		for (i = 1; i <= MAX_ENTRIES; i++) {
54 			stars(starstr, hist->data[i - 1], hist->max, MAX_STARS);
55 			printf("%8ld -> %-8ld : %-8ld |%-*s|\n",
56 				(1l << i) >> 1, (1l << i) - 1,
57 				hist->data[i - 1], MAX_STARS, starstr);
58 		}
59 	}
60 }
61 
62 static void get_data(int fd)
63 {
64 	long key, value;
65 	int c, i;
66 
67 	for (i = 0; i < MAX_CPU; i++)
68 		cpu_hist[i].max = 0;
69 
70 	for (c = 0; c < MAX_CPU; c++) {
71 		for (i = 0; i < MAX_ENTRIES; i++) {
72 			key = c * MAX_ENTRIES + i;
73 			bpf_map_lookup_elem(fd, &key, &value);
74 
75 			cpu_hist[c].data[i] = value;
76 			if (value > cpu_hist[c].max)
77 				cpu_hist[c].max = value;
78 		}
79 	}
80 }
81 
82 int main(int argc, char **argv)
83 {
84 	char filename[256];
85 
86 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
87 
88 	if (load_bpf_file(filename)) {
89 		printf("%s", bpf_log_buf);
90 		return 1;
91 	}
92 
93 	while (1) {
94 		get_data(map_fd[1]);
95 		print_hist();
96 		sleep(5);
97 	}
98 
99 	return 0;
100 }
101