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