1 /* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com
2 * Copyright (c) 2015 BMW Car IT GmbH
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.
8 #include <linux/version.h>
9 #include <linux/ptrace.h>
10 #include <uapi/linux/bpf.h>
11 #include "bpf_helpers.h"
13 #define MAX_ENTRIES 20
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.
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
,
28 SEC("kprobe/trace_preempt_off")
29 int bpf_prog1(struct pt_regs
*ctx
)
31 int cpu
= bpf_get_smp_processor_id();
32 u64
*ts
= bpf_map_lookup_elem(&my_map
, &cpu
);
35 *ts
= bpf_ktime_get_ns();
40 static unsigned int log2(unsigned int v
)
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
;
54 static unsigned int log2l(unsigned long v
)
56 unsigned int hi
= v
>> 32;
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
,
71 SEC("kprobe/trace_preempt_on")
72 int bpf_prog2(struct pt_regs
*ctx
)
74 u64
*ts
, cur_ts
, delta
;
78 cpu
= bpf_get_smp_processor_id();
79 ts
= bpf_map_lookup_elem(&my_map
, &cpu
);
83 cur_ts
= bpf_ktime_get_ns();
84 delta
= log2l(cur_ts
- *ts
);
86 if (delta
> MAX_ENTRIES
- 1)
87 delta
= MAX_ENTRIES
- 1;
89 key
= cpu
* MAX_ENTRIES
+ delta
;
90 val
= bpf_map_lookup_elem(&my_lat
, &key
);
92 __sync_fetch_and_add((long *)val
, 1);
98 char _license
[] SEC("license") = "GPL";
99 u32 _version
SEC("version") = LINUX_VERSION_CODE
;