• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) PLUMgrid, Inc.
2 // Licensed under the Apache License, Version 2.0 (the "License")
3 #include <linux/ptrace.h>
4 #include <linux/blkdev.h>
5 struct Request { u64 rq; };
6 struct Time { u64 start; };
7 BPF_HASH(requests, struct Request, struct Time, 1024);
8 #define SLOTS 100
9 BPF_ARRAY(latency, u64, SLOTS);
10 
log2(u32 v)11 static u32 log2(u32 v) {
12   u32 r, shift;
13 
14   r = (v > 0xFFFF) << 4; v >>= r;
15   shift = (v > 0xFF) << 3; v >>= shift; r |= shift;
16   shift = (v > 0xF) << 2; v >>= shift; r |= shift;
17   shift = (v > 0x3) << 1; v >>= shift; r |= shift;
18   r |= (v >> 1);
19   return r;
20 }
21 
log2l(u64 v)22 static u32 log2l(u64 v) {
23   u32 hi = v >> 32;
24   if (hi)
25     return log2(hi) + 32;
26   else
27     return log2(v);
28 }
29 
probe_blk_start_request(struct pt_regs * ctx)30 int probe_blk_start_request(struct pt_regs *ctx) {
31   struct Request rq = {.rq = PT_REGS_PARM1(ctx)};
32   struct Time tm = {.start = bpf_ktime_get_ns()};
33   requests.update(&rq, &tm);
34   return 0;
35 }
36 
probe_blk_update_request(struct pt_regs * ctx)37 int probe_blk_update_request(struct pt_regs *ctx) {
38   struct Request rq = {.rq = PT_REGS_PARM1(ctx)};
39   struct Time *tm = requests.lookup(&rq);
40   if (!tm) return 0;
41   u64 delta = bpf_ktime_get_ns() - tm->start;
42   requests.delete(&rq);
43   u64 lg = log2l(delta);
44   u64 base = 1ull << lg;
45   u32 index = (lg * 64 + (delta - base) * 64 / base) * 3 / 64;
46   if (index >= SLOTS)
47     index = SLOTS - 1;
48 
49   u64 zero = 0;
50   u64 *val = latency.lookup_or_init(&index, &zero);
51   lock_xadd(val, 1);
52   return 0;
53 }
54