linux/samples/bpf/lathist_user.c
<<
>>
Prefs
   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 <bpf/libbpf.h>
  10#include <bpf/bpf.h>
  11
  12#define MAX_ENTRIES     20
  13#define MAX_CPU         4
  14#define MAX_STARS       40
  15
  16struct cpu_hist {
  17        long data[MAX_ENTRIES];
  18        long max;
  19};
  20
  21static struct cpu_hist cpu_hist[MAX_CPU];
  22
  23static void stars(char *str, long val, long max, int width)
  24{
  25        int i;
  26
  27        for (i = 0; i < (width * val / max) - 1 && i < width - 1; i++)
  28                str[i] = '*';
  29        if (val > max)
  30                str[i - 1] = '+';
  31        str[i] = '\0';
  32}
  33
  34static void print_hist(void)
  35{
  36        char starstr[MAX_STARS];
  37        struct cpu_hist *hist;
  38        int i, j;
  39
  40        /* clear screen */
  41        printf("\033[2J");
  42
  43        for (j = 0; j < MAX_CPU; j++) {
  44                hist = &cpu_hist[j];
  45
  46                /* ignore CPUs without data (maybe offline?) */
  47                if (hist->max == 0)
  48                        continue;
  49
  50                printf("CPU %d\n", j);
  51                printf("      latency        : count     distribution\n");
  52                for (i = 1; i <= MAX_ENTRIES; i++) {
  53                        stars(starstr, hist->data[i - 1], hist->max, MAX_STARS);
  54                        printf("%8ld -> %-8ld : %-8ld |%-*s|\n",
  55                                (1l << i) >> 1, (1l << i) - 1,
  56                                hist->data[i - 1], MAX_STARS, starstr);
  57                }
  58        }
  59}
  60
  61static void get_data(int fd)
  62{
  63        long key, value;
  64        int c, i;
  65
  66        for (i = 0; i < MAX_CPU; i++)
  67                cpu_hist[i].max = 0;
  68
  69        for (c = 0; c < MAX_CPU; c++) {
  70                for (i = 0; i < MAX_ENTRIES; i++) {
  71                        key = c * MAX_ENTRIES + i;
  72                        bpf_map_lookup_elem(fd, &key, &value);
  73
  74                        cpu_hist[c].data[i] = value;
  75                        if (value > cpu_hist[c].max)
  76                                cpu_hist[c].max = value;
  77                }
  78        }
  79}
  80
  81int main(int argc, char **argv)
  82{
  83        struct bpf_link *links[2];
  84        struct bpf_program *prog;
  85        struct bpf_object *obj;
  86        char filename[256];
  87        int map_fd, i = 0;
  88
  89        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
  90        obj = bpf_object__open_file(filename, NULL);
  91        if (libbpf_get_error(obj)) {
  92                fprintf(stderr, "ERROR: opening BPF object file failed\n");
  93                return 0;
  94        }
  95
  96        /* load BPF program */
  97        if (bpf_object__load(obj)) {
  98                fprintf(stderr, "ERROR: loading BPF object file failed\n");
  99                goto cleanup;
 100        }
 101
 102        map_fd = bpf_object__find_map_fd_by_name(obj, "my_lat");
 103        if (map_fd < 0) {
 104                fprintf(stderr, "ERROR: finding a map in obj file failed\n");
 105                goto cleanup;
 106        }
 107
 108        bpf_object__for_each_program(prog, obj) {
 109                links[i] = bpf_program__attach(prog);
 110                if (libbpf_get_error(links[i])) {
 111                        fprintf(stderr, "ERROR: bpf_program__attach failed\n");
 112                        links[i] = NULL;
 113                        goto cleanup;
 114                }
 115                i++;
 116        }
 117
 118        while (1) {
 119                get_data(map_fd);
 120                print_hist();
 121                sleep(5);
 122        }
 123
 124cleanup:
 125        for (i--; i >= 0; i--)
 126                bpf_link__destroy(links[i]);
 127
 128        bpf_object__close(obj);
 129        return 0;
 130}
 131