Skip to content

Commit 3026b28

Browse files
committed
netstacklat: Add option to groupby cgroup
Add the -C/--groupby-cgroup option to collect and report data on a per-cgroup basis. Just like the -c/--cgroups option, this will only apply to probes in the process context, which is currently only tcp-socket-read and udp-socket-read. When reporting the data, print out the cgroup ID (inode number) directly instead of the cgroup path. As far as I can tell, the only way to resolve the ID into a path is the walk the entire cgroup mount (e.g. /sys/fs/cgroup) and stat each path to find the matching inode. Doing this every time the cgroup needs to be printed seems highly inefficient, and to create an efficient cache the most suitable data structure seems like a hashmap, which C lacks. Adding support for printing out the cgroup path would thus be a significant implementation effort for something we in the end primarily will rely on ebpf-exporter for anyways. Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
1 parent a76550c commit 3026b28

File tree

4 files changed

+34
-7
lines changed

4 files changed

+34
-7
lines changed

netstacklat/netstacklat.bpf.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ volatile const struct netstacklat_bpf_config user_config = {
2020
.filter_cgroup = false,
2121
.filter_nonempty_sockqueue = false,
2222
.groupby_ifindex = false,
23+
.groupby_cgroup = false,
2324
};
2425

2526
/*
@@ -37,7 +38,7 @@ struct sk_buff___old {
3738

3839
struct {
3940
__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
40-
__uint(max_entries, HIST_NBUCKETS * NETSTACKLAT_N_HOOKS * 16);
41+
__uint(max_entries, HIST_NBUCKETS * NETSTACKLAT_N_HOOKS * 64);
4142
__type(key, struct hist_key);
4243
__type(value, u64);
4344
} netstack_latency_seconds SEC(".maps");
@@ -250,21 +251,18 @@ static bool filter_cgroup(u64 cgroup_id)
250251
return bpf_map_lookup_elem(&netstack_cgroupfilter, &cgroup_id) != NULL;
251252
}
252253

253-
static bool filter_current_task(void)
254+
static bool filter_current_task(u64 cgroup)
254255
{
255256
bool ok = true;
256-
__u64 cgroup;
257257
__u32 tgid;
258258

259259
if (user_config.filter_pid) {
260260
tgid = bpf_get_current_pid_tgid() >> 32;
261261
ok = ok && filter_pid(tgid);
262262
}
263263

264-
if (user_config.filter_cgroup) {
265-
cgroup = bpf_get_current_cgroup_id();
264+
if (user_config.filter_cgroup)
266265
ok = ok && filter_cgroup(cgroup);
267-
}
268266

269267
return ok;
270268
}
@@ -294,12 +292,16 @@ static void record_socket_latency(struct sock *sk, struct sk_buff *skb,
294292
ktime_t tstamp, enum netstacklat_hook hook)
295293
{
296294
struct hist_key key = { .hook = hook };
295+
u64 cgroup = 0;
297296
u32 ifindex;
298297

299298
if (!filter_nonempty_sockqueue(sk))
300299
return;
301300

302-
if (!filter_current_task())
301+
if (user_config.filter_cgroup || user_config.groupby_cgroup)
302+
cgroup = bpf_get_current_cgroup_id();
303+
304+
if (!filter_current_task(cgroup))
303305
return;
304306

305307
ifindex = skb ? skb->skb_iif : sk->sk_rx_dst_ifindex;
@@ -311,6 +313,8 @@ static void record_socket_latency(struct sock *sk, struct sk_buff *skb,
311313

312314
if (user_config.groupby_ifindex)
313315
key.ifindex = ifindex;
316+
if (user_config.groupby_cgroup)
317+
key.cgroup = cgroup;
314318

315319
record_latency_since(tstamp, &key);
316320
}

netstacklat/netstacklat.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ static const struct option long_options[] = {
9898
{ "cgroups", required_argument, NULL, 'c' },
9999
{ "nonempty-queue", no_argument, NULL, 'q' },
100100
{ "groupby-interface", no_argument, NULL, 'I' },
101+
{ "groupby-cgroup", no_argument, NULL, 'C' },
101102
{ 0, 0, 0, 0 }
102103
};
103104

@@ -564,6 +565,7 @@ static int parse_arguments(int argc, char *argv[],
564565
conf->bpf_conf.filter_ifindex = false;
565566
conf->bpf_conf.filter_nonempty_sockqueue = false;
566567
conf->bpf_conf.groupby_ifindex = false;
568+
conf->bpf_conf.groupby_cgroup = false;
567569

568570
conf->pids = calloc(MAX_PARSED_PIDS, sizeof(*conf->pids));
569571
conf->ifindices = calloc(MAX_PARSED_IFACES, sizeof(*conf->ifindices));
@@ -658,6 +660,9 @@ static int parse_arguments(int argc, char *argv[],
658660
case 'I': // groupby-interface
659661
conf->bpf_conf.groupby_ifindex = true;
660662
break;
663+
case 'C': // groupby-cgroup
664+
conf->bpf_conf.groupby_cgroup = true;
665+
break;
661666
case 'h': // help
662667
print_usage(stdout, argv[0]);
663668
exit(EXIT_SUCCESS);
@@ -831,6 +836,9 @@ static void print_histkey(FILE *stream, const struct hist_key *key)
831836

832837
if (key->ifindex)
833838
fprintf(stream, ", interface=%u", key->ifindex);
839+
840+
if (key->cgroup)
841+
fprintf(stream, ", cgroup=%llu", key->cgroup);
834842
}
835843

836844
static int cmp_histkey(const void *val1, const void *val2)
@@ -843,6 +851,9 @@ static int cmp_histkey(const void *val1, const void *val2)
843851
if (key1->ifindex != key2->ifindex)
844852
return key1->ifindex > key2->ifindex ? 1 : -1;
845853

854+
if (key1->cgroup != key2->cgroup)
855+
return key1->cgroup > key2->cgroup ? 1 : -1;
856+
846857
return 0;
847858
}
848859

@@ -1042,6 +1053,11 @@ static int init_histogram_buffer(struct histogram_buffer *buf,
10421053
min(conf->nifindices, 64) :
10431054
32;
10441055

1056+
if (conf->bpf_conf.groupby_cgroup)
1057+
max_hists *= conf->bpf_conf.filter_cgroup ?
1058+
min(conf->ncgroups, 128) :
1059+
64;
1060+
10451061
buf->hists = calloc(max_hists, sizeof(*buf->hists));
10461062
if (!buf->hists)
10471063
return -errno;

netstacklat/netstacklat.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ enum netstacklat_hook {
6060
* member is named "bucket" and is the histogram bucket index.
6161
*/
6262
struct hist_key {
63+
__u64 cgroup;
6364
__u32 ifindex;
6465
__u16 hook; // need well defined size for ebpf-exporter to decode
6566
__u16 bucket; // needs to be last to be compatible with ebpf-exporter
@@ -72,6 +73,7 @@ struct netstacklat_bpf_config {
7273
bool filter_cgroup;
7374
bool filter_nonempty_sockqueue;
7475
bool groupby_ifindex;
76+
bool groupby_cgroup;
7577
};
7678

7779
#endif

netstacklat/netstacklat.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ metrics:
77
bucket_max: 34
88
bucket_multiplier: 0.000000001 # nanoseconds to seconds
99
labels:
10+
- name: cgroup
11+
size: 8
12+
decoders:
13+
- name: uint
14+
- name: cgroup
1015
- name: iface
1116
size: 4
1217
decoders:

0 commit comments

Comments
 (0)