Skip to content

Commit 99528d1

Browse files
authored
Merge pull request #32 from prakashsurya/metaslab-alloc
Add new tool for observing metaslab allocations
2 parents 3f6c4b1 + e8558cf commit 99528d1

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed

bpf/estat/metaslab-alloc.c

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Copyright 2020 Delphix. All rights reserved.
3+
*
4+
* SPDX-License-Identifier: GPL-2.0-or-later
5+
*/
6+
7+
#include <sys/metaslab.h>
8+
#include <sys/metaslab_impl.h>
9+
#include <sys/vdev_impl.h>
10+
#include <sys/spa_impl.h>
11+
12+
#define VD_NAME_SIZE 32
13+
typedef struct {
14+
u64 ts;
15+
u64 size;
16+
u64 asize;
17+
u64 alloc_time;
18+
char vd_name[VD_NAME_SIZE];
19+
} data_t;
20+
21+
BPF_HASH(data_map, u32, data_t);
22+
23+
#ifndef OPTARG
24+
#define POOL "domain0"
25+
#else
26+
#define POOL (OPTARG)
27+
#endif
28+
29+
static inline bool
30+
equal_to_pool(char *str)
31+
{
32+
char comparand[sizeof (POOL)];
33+
bpf_probe_read(&comparand, sizeof (comparand), str);
34+
char compare[] = POOL;
35+
36+
for (int i = 0; i < sizeof (comparand); ++i)
37+
if (compare[i] != comparand[i])
38+
return (false);
39+
40+
return (true);
41+
}
42+
43+
// @@ kprobe|metaslab_alloc_dva|metaslab_alloc_dva_entry
44+
int
45+
metaslab_alloc_dva_entry(struct pt_regs *ctx,
46+
spa_t *spa, metaslab_class_t *mc, uint64_t psize)
47+
{
48+
u32 tid = bpf_get_current_pid_tgid();
49+
data_t data = {};
50+
51+
if (!equal_to_pool(spa->spa_name))
52+
return (0);
53+
54+
data.ts = bpf_ktime_get_ns();
55+
data.size = psize;
56+
57+
data_map.update(&tid, &data);
58+
59+
return (0);
60+
}
61+
62+
// @@ kprobe|metaslab_group_alloc|metaslab_group_alloc_entry
63+
int
64+
metaslab_group_alloc_entry(struct pt_regs *ctx,
65+
metaslab_group_t *mg, zio_alloc_list_t *zal, uint64_t asize)
66+
{
67+
u32 tid = bpf_get_current_pid_tgid();
68+
data_t *data = data_map.lookup(&tid);
69+
70+
if (data == NULL || data->ts == 0)
71+
return (0);
72+
73+
data->asize = asize;
74+
data->alloc_time = bpf_ktime_get_ns();
75+
76+
if (mg->mg_vd->vdev_path != NULL) {
77+
bpf_probe_read_str(data->vd_name,
78+
sizeof(data->vd_name), mg->mg_vd->vdev_path);
79+
} else {
80+
bpf_probe_read_str(data->vd_name,
81+
sizeof(data->vd_name), mg->mg_vd->vdev_ops->vdev_op_type);
82+
}
83+
84+
return (0);
85+
}
86+
87+
// @@ kretprobe|metaslab_group_alloc|metaslab_group_alloc_exit
88+
int
89+
metaslab_group_alloc_exit(struct pt_regs *ctx)
90+
{
91+
u32 tid = bpf_get_current_pid_tgid();
92+
data_t *data = data_map.lookup(&tid);
93+
char failure[] = "failure";
94+
char success[] = "success";
95+
char *axis;
96+
97+
if (data == NULL || data->ts == 0)
98+
return (0);
99+
100+
if (PT_REGS_RC(ctx) == -1ULL) {
101+
axis = failure;
102+
} else {
103+
axis = success;
104+
}
105+
106+
AGGREGATE_DATA(data->vd_name, axis,
107+
bpf_ktime_get_ns() - data->ts, data->asize);
108+
109+
data->asize = 0;
110+
data->alloc_time = 0;
111+
data->vd_name[0] = '\0';
112+
113+
return (0);
114+
}
115+
116+
// @@ kretprobe|metaslab_alloc_dva|metaslab_alloc_dva_exit
117+
int
118+
metaslab_alloc_dva_exit(struct pt_regs *ctx,
119+
spa_t *spa, metaslab_class_t *mc, uint64_t psize)
120+
{
121+
u32 tid = bpf_get_current_pid_tgid();
122+
data_t *data = data_map.lookup(&tid);
123+
124+
if (data == NULL || data->ts == 0)
125+
return (0);
126+
127+
if (PT_REGS_RC(ctx) == 0)
128+
return (0);
129+
130+
char name[] = "allocation failures";
131+
char axis = 0;
132+
AGGREGATE_DATA(name, &axis,
133+
bpf_ktime_get_ns() - data->ts, data->size);
134+
135+
data->ts = 0;
136+
data->size = 0;
137+
138+
data_map.delete(&tid);
139+
140+
return (0);
141+
}

0 commit comments

Comments
 (0)