root/samples/bpf/lathist_kern.c

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

DEFINITIONS

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

   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 <linux/version.h>
   9 #include <linux/ptrace.h>
  10 #include <uapi/linux/bpf.h>
  11 #include "bpf_helpers.h"
  12 
  13 #define MAX_ENTRIES     20
  14 #define MAX_CPU         4
  15 
  16 /* We need to stick to static allocated memory (an array instead of
  17  * hash table) because managing dynamic memory from the
  18  * trace_preempt_[on|off] tracepoints hooks is not supported.
  19  */
  20 
  21 struct bpf_map_def SEC("maps") my_map = {
  22         .type = BPF_MAP_TYPE_ARRAY,
  23         .key_size = sizeof(int),
  24         .value_size = sizeof(u64),
  25         .max_entries = MAX_CPU,
  26 };
  27 
  28 SEC("kprobe/trace_preempt_off")
  29 int bpf_prog1(struct pt_regs *ctx)
  30 {
  31         int cpu = bpf_get_smp_processor_id();
  32         u64 *ts = bpf_map_lookup_elem(&my_map, &cpu);
  33 
  34         if (ts)
  35                 *ts = bpf_ktime_get_ns();
  36 
  37         return 0;
  38 }
  39 
  40 static unsigned int log2(unsigned int v)
  41 {
  42         unsigned int r;
  43         unsigned int shift;
  44 
  45         r = (v > 0xFFFF) << 4; v >>= r;
  46         shift = (v > 0xFF) << 3; v >>= shift; r |= shift;
  47         shift = (v > 0xF) << 2; v >>= shift; r |= shift;
  48         shift = (v > 0x3) << 1; v >>= shift; r |= shift;
  49         r |= (v >> 1);
  50 
  51         return r;
  52 }
  53 
  54 static unsigned int log2l(unsigned long v)
  55 {
  56         unsigned int hi = v >> 32;
  57 
  58         if (hi)
  59                 return log2(hi) + 32;
  60         else
  61                 return log2(v);
  62 }
  63 
  64 struct bpf_map_def SEC("maps") my_lat = {
  65         .type = BPF_MAP_TYPE_ARRAY,
  66         .key_size = sizeof(int),
  67         .value_size = sizeof(long),
  68         .max_entries = MAX_CPU * MAX_ENTRIES,
  69 };
  70 
  71 SEC("kprobe/trace_preempt_on")
  72 int bpf_prog2(struct pt_regs *ctx)
  73 {
  74         u64 *ts, cur_ts, delta;
  75         int key, cpu;
  76         long *val;
  77 
  78         cpu = bpf_get_smp_processor_id();
  79         ts = bpf_map_lookup_elem(&my_map, &cpu);
  80         if (!ts)
  81                 return 0;
  82 
  83         cur_ts = bpf_ktime_get_ns();
  84         delta = log2l(cur_ts - *ts);
  85 
  86         if (delta > MAX_ENTRIES - 1)
  87                 delta = MAX_ENTRIES - 1;
  88 
  89         key = cpu * MAX_ENTRIES + delta;
  90         val = bpf_map_lookup_elem(&my_lat, &key);
  91         if (val)
  92                 __sync_fetch_and_add((long *)val, 1);
  93 
  94         return 0;
  95 
  96 }
  97 
  98 char _license[] SEC("license") = "GPL";
  99 u32 _version SEC("version") = LINUX_VERSION_CODE;

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