Skip to content

Commit e4329ed

Browse files
committed
netstacklat: Dynamically configure map sizes
Make the userspace agent set the BPF map sizes based on configured options. This allows more suitable map sizes to be used during run time than the static limits set in the BPF programs. This avoids wasting memory by using unnecessary large maps, and might slightly improve hashmap lookup performance by sizing them based on the expected number of entries (small enough that many entries may fit in cache, large enough to avoid excessive hash collisions). Scale the histogram map based on the expected number of histograms, the PID and ifindex filter maps to fit the largest key they need to include and the cgroup filter map to fit all tracked cgroups. This also fixes a bug where the maximum allowed PID (PID_MAX_LIMIT) and ifindex (IFINDEX_MAX) did not fit in their corresponding filter maps (off-by-one error). Signed-off-by: Simon Sundberg <[email protected]>
1 parent 7dc64ad commit e4329ed

File tree

1 file changed

+70
-4
lines changed

1 file changed

+70
-4
lines changed

netstacklat/netstacklat.c

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,9 +1012,15 @@ static int report_stats(const struct netstacklat_bpf *obj,
10121012
return 0;
10131013
}
10141014

1015-
static int init_histogram_buffer(struct histogram_buffer *buf)
1015+
static int init_histogram_buffer(struct histogram_buffer *buf,
1016+
const struct netstacklat_config *conf)
10161017
{
1017-
int max_hists = NETSTACKLAT_N_HOOKS;
1018+
int max_hists = 0, i;
1019+
1020+
for (i = 0; i < NETSTACKLAT_N_HOOKS; i++) {
1021+
if (conf->enabled_hooks[i])
1022+
max_hists++;
1023+
}
10181024

10191025
buf->hists = calloc(max_hists, sizeof(*buf->hists));
10201026
if (!buf->hists)
@@ -1077,6 +1083,59 @@ static void set_programs_to_load(const struct netstacklat_config *conf,
10771083
}
10781084
}
10791085

1086+
static int set_map_sizes(const struct netstacklat_config *conf,
1087+
struct netstacklat_bpf *obj, int max_hists)
1088+
{
1089+
__u32 size;
1090+
int err, i;
1091+
1092+
size = max_hists * HIST_NBUCKETS;
1093+
err = bpf_map__set_max_entries(obj->maps.netstack_latency_seconds,
1094+
size);
1095+
if (err) {
1096+
fprintf(stderr, "Failed setting size of histogram map to %u\n",
1097+
size);
1098+
return err;
1099+
}
1100+
1101+
// PID filter - arraymap, needs max PID + 1 entries
1102+
for (i = 0, size = 1; i < conf->npids; i++) {
1103+
if (conf->pids[i] >= size)
1104+
size = conf->pids[i] + 1;
1105+
}
1106+
err = bpf_map__set_max_entries(obj->maps.netstack_pidfilter, size);
1107+
if (err) {
1108+
fprintf(stderr, "Failed setting size of PID filter map to %u\n",
1109+
size);
1110+
return err;
1111+
}
1112+
1113+
// ifindex filter - arraymap, needs max ifindex + 1 entries
1114+
for (i = 0, size = 1; i < conf->nifindices; i++) {
1115+
if (conf->ifindices[i] >= size)
1116+
size = conf->ifindices[i] + 1;
1117+
}
1118+
err = bpf_map__set_max_entries(obj->maps.netstack_ifindexfilter, size);
1119+
if (err) {
1120+
fprintf(stderr,
1121+
"Failed setting size of ifindex filter map to %u\n",
1122+
size);
1123+
return err;
1124+
}
1125+
1126+
// cgroup filter - hashmap, should be ~2x expected number of entries
1127+
size = conf->bpf_conf.filter_cgroup ? conf->ncgroups * 2 : 1;
1128+
err = bpf_map__set_max_entries(obj->maps.netstack_cgroupfilter, size);
1129+
if (err) {
1130+
fprintf(stderr,
1131+
"Failed setting size of cgroup filter map to %u\n",
1132+
size);
1133+
return err;
1134+
}
1135+
1136+
return 0;
1137+
}
1138+
10801139
static int init_filtermap(int map_fd, void *keys, size_t nelem,
10811140
size_t elem_size)
10821141
{
@@ -1272,7 +1331,7 @@ int main(int argc, char *argv[])
12721331
return EXIT_FAILURE;
12731332
}
12741333

1275-
err = init_histogram_buffer(&hist_buf);
1334+
err = init_histogram_buffer(&hist_buf, &config);
12761335
if (err) {
12771336
fprintf(stderr, "Failed allocating buffer for histograms: %s\n",
12781337
strerror(-err));
@@ -1290,7 +1349,7 @@ int main(int argc, char *argv[])
12901349

12911350
obj = netstacklat_bpf__open();
12921351
if (!obj) {
1293-
err = libbpf_get_error(obj);
1352+
err = -errno;
12941353
libbpf_strerror(err, errmsg, sizeof(errmsg));
12951354
fprintf(stderr, "Failed opening eBPF object file: %s\n", errmsg);
12961355
goto exit_sockfd;
@@ -1301,6 +1360,13 @@ int main(int argc, char *argv[])
13011360

13021361
set_programs_to_load(&config, obj);
13031362

1363+
err = set_map_sizes(&config, obj, hist_buf.max_size);
1364+
if (err) {
1365+
libbpf_strerror(err, errmsg, sizeof(errmsg));
1366+
fprintf(stderr, "Failed configuring map sizes: %s\n", errmsg);
1367+
goto exit_destroy_bpf;
1368+
}
1369+
13041370
err = netstacklat_bpf__load(obj);
13051371
if (err) {
13061372
libbpf_strerror(err, errmsg, sizeof(errmsg));

0 commit comments

Comments
 (0)