Skip to content

Commit a7182a6

Browse files
committed
netstacklat: Make HOL-blocking filtering configurable
To make netstacklat only report latency based on the local network and application stack, it by default excludes TCP reads that may be head-of-line (HOL) blocked by a missing segment. However, in some scenarios, it may be desirable to still include these HOL-blocked measurements. For example, in a data center where the full network is under your control, high latency caused by drops in the data center network could still be an issue you wish netstacklat to detect. Therefore, add the -y/--include-tcp-hol-delay option, which disables the mechanism used to filter out potentially HOL-blocked reads. An alternative design to simply disabling the filtering mechanism, would be to separate the potentially HOL-blocked measurements into their own histogram (e.g. "tcp-socket-read-hol-blocked"). However, that would further increase the data cardinality (which may be a concern when using it together ebpf-exporter). Furthermore, by simply disabling the filtering instead we can reduce the overhead a bit and also allow it as an option on systems were the tcp_data_queue_ofo() function cannot be probed. Signed-off-by: Simon Sundberg <simon.sundberg@kau.se>
1 parent 64c7d05 commit a7182a6

File tree

3 files changed

+33
-13
lines changed

3 files changed

+33
-13
lines changed

netstacklat/netstacklat.bpf.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ volatile const struct netstacklat_bpf_config user_config = {
2727
.filter_cgroup = false,
2828
.groupby_ifindex = false,
2929
.groupby_cgroup = false,
30+
.include_hol_blocked = false,
3031
};
3132

3233
/*
@@ -484,7 +485,7 @@ int BPF_PROG(netstacklat_tcp_recv_timestamp, void *msg, struct sock *sk,
484485
struct timespec64 *ts = &tss->ts[0];
485486

486487
/* skip if preceeding sock read ended in ooo-range */
487-
if (tcp_read_in_ooo_range(sk))
488+
if (!user_config.include_hol_blocked && tcp_read_in_ooo_range(sk))
488489
return 0;
489490

490491
record_socket_latency(sk, NULL,
@@ -507,6 +508,15 @@ SEC("fentry/tcp_data_queue_ofo")
507508
int BPF_PROG(netstacklat_tcp_data_queue_ofo, struct sock *sk,
508509
struct sk_buff *skb)
509510
{
511+
if (!user_config.include_hol_blocked)
512+
/*
513+
* It's better to not load this program at all if the ooo-range
514+
* tracking isn't needed (like done by netstacklat.c).
515+
* But if an external loader (like ebpf-exporter) is used,
516+
* this should at least minimze the unncecessary overhead.
517+
*/
518+
tcp_update_ooo_range(sk, skb);
519+
510520
if (!filter_network(skb, sk))
511521
return 0;
512522

netstacklat/netstacklat.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,19 @@ struct netstacklat_config {
8383
};
8484

8585
static const struct option long_options[] = {
86-
{ "help", no_argument, NULL, 'h' },
87-
{ "report-interval", required_argument, NULL, 'r' },
88-
{ "list-probes", no_argument, NULL, 'l' },
89-
{ "enable-probes", required_argument, NULL, 'e' },
90-
{ "disable-probes", required_argument, NULL, 'd' },
91-
{ "pids", required_argument, NULL, 'p' },
92-
{ "interfaces", required_argument, NULL, 'i' },
93-
{ "network-namespace", required_argument, NULL, 'n' },
94-
{ "cgroups", required_argument, NULL, 'c' },
95-
{ "min-queuelength", required_argument, NULL, 'q' },
96-
{ "groupby-interface", no_argument, NULL, 'I' },
97-
{ "groupby-cgroup", no_argument, NULL, 'C' },
86+
{ "help", no_argument, NULL, 'h' },
87+
{ "report-interval", required_argument, NULL, 'r' },
88+
{ "list-probes", no_argument, NULL, 'l' },
89+
{ "enable-probes", required_argument, NULL, 'e' },
90+
{ "disable-probes", required_argument, NULL, 'd' },
91+
{ "pids", required_argument, NULL, 'p' },
92+
{ "interfaces", required_argument, NULL, 'i' },
93+
{ "network-namespace", required_argument, NULL, 'n' },
94+
{ "cgroups", required_argument, NULL, 'c' },
95+
{ "min-queuelength", required_argument, NULL, 'q' },
96+
{ "groupby-interface", no_argument, NULL, 'I' },
97+
{ "groupby-cgroup", no_argument, NULL, 'C' },
98+
{ "include-tcp-hol-delay", no_argument, NULL, 'y' },
9899
{ 0, 0, 0, 0 }
99100
};
100101

@@ -565,6 +566,7 @@ static int parse_arguments(int argc, char *argv[],
565566
conf->bpf_conf.filter_cgroup = false;
566567
conf->bpf_conf.groupby_ifindex = false;
567568
conf->bpf_conf.groupby_cgroup = false;
569+
conf->bpf_conf.include_hol_blocked = false;
568570

569571
for (i = 0; i < NETSTACKLAT_N_HOOKS; i++)
570572
// All probes enabled by default
@@ -659,6 +661,9 @@ static int parse_arguments(int argc, char *argv[],
659661
case 'C': // groupby-cgroup
660662
conf->bpf_conf.groupby_cgroup = true;
661663
break;
664+
case 'y': // include-tcp-hol-delay
665+
conf->bpf_conf.include_hol_blocked = true;
666+
break;
662667
case 'h': // help
663668
print_usage(stdout, argv[0]);
664669
exit(EXIT_SUCCESS);
@@ -1113,6 +1118,10 @@ static void set_programs_to_load(const struct netstacklat_config *conf,
11131118
bpf_program__set_autoload(progs.progs[i],
11141119
conf->enabled_hooks[hook]);
11151120
}
1121+
1122+
if (conf->bpf_conf.include_hol_blocked)
1123+
bpf_program__set_autoload(
1124+
obj->progs.netstacklat_tcp_data_queue_ofo, false);
11161125
}
11171126

11181127
static int set_map_sizes(const struct netstacklat_config *conf,

netstacklat/netstacklat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ struct netstacklat_bpf_config {
7777
bool filter_cgroup;
7878
bool groupby_ifindex;
7979
bool groupby_cgroup;
80+
bool include_hol_blocked;
8081
};
8182

8283
#endif

0 commit comments

Comments
 (0)