root/samples/bpf/tracex3_kern.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SEC
  2. log2l
  3. SEC

   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 <linux/skbuff.h>
   8 #include <linux/netdevice.h>
   9 #include <linux/version.h>
  10 #include <uapi/linux/bpf.h>
  11 #include "bpf_helpers.h"
  12 
  13 struct bpf_map_def SEC("maps") my_map = {
  14         .type = BPF_MAP_TYPE_HASH,
  15         .key_size = sizeof(long),
  16         .value_size = sizeof(u64),
  17         .max_entries = 4096,
  18 };
  19 
  20 /* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe
  21  * example will no longer be meaningful
  22  */
  23 SEC("kprobe/blk_mq_start_request")
  24 int bpf_prog1(struct pt_regs *ctx)
  25 {
  26         long rq = PT_REGS_PARM1(ctx);
  27         u64 val = bpf_ktime_get_ns();
  28 
  29         bpf_map_update_elem(&my_map, &rq, &val, BPF_ANY);
  30         return 0;
  31 }
  32 
  33 static unsigned int log2l(unsigned long long n)
  34 {
  35 #define S(k) if (n >= (1ull << k)) { i += k; n >>= k; }
  36         int i = -(n == 0);
  37         S(32); S(16); S(8); S(4); S(2); S(1);
  38         return i;
  39 #undef S
  40 }
  41 
  42 #define SLOTS 100
  43 
  44 struct bpf_map_def SEC("maps") lat_map = {
  45         .type = BPF_MAP_TYPE_PERCPU_ARRAY,
  46         .key_size = sizeof(u32),
  47         .value_size = sizeof(u64),
  48         .max_entries = SLOTS,
  49 };
  50 
  51 SEC("kprobe/blk_account_io_completion")
  52 int bpf_prog2(struct pt_regs *ctx)
  53 {
  54         long rq = PT_REGS_PARM1(ctx);
  55         u64 *value, l, base;
  56         u32 index;
  57 
  58         value = bpf_map_lookup_elem(&my_map, &rq);
  59         if (!value)
  60                 return 0;
  61 
  62         u64 cur_time = bpf_ktime_get_ns();
  63         u64 delta = cur_time - *value;
  64 
  65         bpf_map_delete_elem(&my_map, &rq);
  66 
  67         /* the lines below are computing index = log10(delta)*10
  68          * using integer arithmetic
  69          * index = 29 ~ 1 usec
  70          * index = 59 ~ 1 msec
  71          * index = 89 ~ 1 sec
  72          * index = 99 ~ 10sec or more
  73          * log10(x)*10 = log2(x)*10/log2(10) = log2(x)*3
  74          */
  75         l = log2l(delta);
  76         base = 1ll << l;
  77         index = (l * 64 + (delta - base) * 64 / base) * 3 / 64;
  78 
  79         if (index >= SLOTS)
  80                 index = SLOTS - 1;
  81 
  82         value = bpf_map_lookup_elem(&lat_map, &index);
  83         if (value)
  84                 *value += 1;
  85 
  86         return 0;
  87 }
  88 char _license[] SEC("license") = "GPL";
  89 u32 _version SEC("version") = LINUX_VERSION_CODE;

/* [<][>][^][v][top][bottom][index][help] */