linux/samples/bpf/tracex3_user.c
<<
>>
Prefs
   1/* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com
   2 *
   3 * This program is free software; you can redistribute it and/or
   4 * modify it under the terms of version 2 of the GNU General Public
   5 * License as published by the Free Software Foundation.
   6 */
   7#include <stdio.h>
   8#include <stdlib.h>
   9#include <signal.h>
  10#include <unistd.h>
  11#include <stdbool.h>
  12#include <string.h>
  13#include <linux/bpf.h>
  14#include <sys/resource.h>
  15
  16#include "libbpf.h"
  17#include "bpf_load.h"
  18#include "bpf_util.h"
  19
  20#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
  21
  22#define SLOTS 100
  23
  24static void clear_stats(int fd)
  25{
  26        unsigned int nr_cpus = bpf_num_possible_cpus();
  27        __u64 values[nr_cpus];
  28        __u32 key;
  29
  30        memset(values, 0, sizeof(values));
  31        for (key = 0; key < SLOTS; key++)
  32                bpf_map_update_elem(fd, &key, values, BPF_ANY);
  33}
  34
  35const char *color[] = {
  36        "\033[48;5;255m",
  37        "\033[48;5;252m",
  38        "\033[48;5;250m",
  39        "\033[48;5;248m",
  40        "\033[48;5;246m",
  41        "\033[48;5;244m",
  42        "\033[48;5;242m",
  43        "\033[48;5;240m",
  44        "\033[48;5;238m",
  45        "\033[48;5;236m",
  46        "\033[48;5;234m",
  47        "\033[48;5;232m",
  48};
  49const int num_colors = ARRAY_SIZE(color);
  50
  51const char nocolor[] = "\033[00m";
  52
  53const char *sym[] = {
  54        " ",
  55        " ",
  56        ".",
  57        ".",
  58        "*",
  59        "*",
  60        "o",
  61        "o",
  62        "O",
  63        "O",
  64        "#",
  65        "#",
  66};
  67
  68bool full_range = false;
  69bool text_only = false;
  70
  71static void print_banner(void)
  72{
  73        if (full_range)
  74                printf("|1ns     |10ns     |100ns    |1us      |10us     |100us"
  75                       "    |1ms      |10ms     |100ms    |1s       |10s\n");
  76        else
  77                printf("|1us      |10us     |100us    |1ms      |10ms     "
  78                       "|100ms    |1s       |10s\n");
  79}
  80
  81static void print_hist(int fd)
  82{
  83        unsigned int nr_cpus = bpf_num_possible_cpus();
  84        __u64 total_events = 0;
  85        long values[nr_cpus];
  86        __u64 max_cnt = 0;
  87        __u64 cnt[SLOTS];
  88        __u64 value;
  89        __u32 key;
  90        int i;
  91
  92        for (key = 0; key < SLOTS; key++) {
  93                bpf_map_lookup_elem(fd, &key, values);
  94                value = 0;
  95                for (i = 0; i < nr_cpus; i++)
  96                        value += values[i];
  97                cnt[key] = value;
  98                total_events += value;
  99                if (value > max_cnt)
 100                        max_cnt = value;
 101        }
 102        clear_stats(fd);
 103        for (key = full_range ? 0 : 29; key < SLOTS; key++) {
 104                int c = num_colors * cnt[key] / (max_cnt + 1);
 105
 106                if (text_only)
 107                        printf("%s", sym[c]);
 108                else
 109                        printf("%s %s", color[c], nocolor);
 110        }
 111        printf(" # %lld\n", total_events);
 112}
 113
 114int main(int ac, char **argv)
 115{
 116        struct rlimit r = {1024*1024, RLIM_INFINITY};
 117        char filename[256];
 118        int i;
 119
 120        snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
 121
 122        if (setrlimit(RLIMIT_MEMLOCK, &r)) {
 123                perror("setrlimit(RLIMIT_MEMLOCK)");
 124                return 1;
 125        }
 126
 127        if (load_bpf_file(filename)) {
 128                printf("%s", bpf_log_buf);
 129                return 1;
 130        }
 131
 132        for (i = 1; i < ac; i++) {
 133                if (strcmp(argv[i], "-a") == 0) {
 134                        full_range = true;
 135                } else if (strcmp(argv[i], "-t") == 0) {
 136                        text_only = true;
 137                } else if (strcmp(argv[i], "-h") == 0) {
 138                        printf("Usage:\n"
 139                               "  -a display wider latency range\n"
 140                               "  -t text only\n");
 141                        return 1;
 142                }
 143        }
 144
 145        printf("  heatmap of IO latency\n");
 146        if (text_only)
 147                printf("  %s", sym[num_colors - 1]);
 148        else
 149                printf("  %s %s", color[num_colors - 1], nocolor);
 150        printf(" - many events with this latency\n");
 151
 152        if (text_only)
 153                printf("  %s", sym[0]);
 154        else
 155                printf("  %s %s", color[0], nocolor);
 156        printf(" - few events\n");
 157
 158        for (i = 0; ; i++) {
 159                if (i % 20 == 0)
 160                        print_banner();
 161                print_hist(map_fd[1]);
 162                sleep(2);
 163        }
 164
 165        return 0;
 166}
 167