Skip to content

Commit 7e4fb55

Browse files
committed
libbpf-tools/biotop: Use dump_hash for map processing
Replace biotop's two-loop map lookup and deletion with a single dump_hash call, using bpf_map_lookup_and_delete_batch for atomic processing to prevent potential concurrency issues. Simplify code using dump_hash.
1 parent ddf94d3 commit 7e4fb55

File tree

1 file changed

+28
-41
lines changed

1 file changed

+28
-41
lines changed

libbpf-tools/biotop.c

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "biotop.skel.h"
2727
#include "compat.h"
2828
#include "trace_helpers.h"
29+
#include "map_helpers.h"
2930

3031
#define warn(...) fprintf(stderr, __VA_ARGS__)
3132
#define OUTPUT_ROWS_LIMIT 10240
@@ -276,16 +277,36 @@ static char *search_disk_name(int major, int minor)
276277
return "";
277278
}
278279

280+
static int read_stat(struct biotop_bpf *obj, struct data_t *datas, __u32 *count)
281+
{
282+
struct info_t keys[OUTPUT_ROWS_LIMIT];
283+
struct val_t values[OUTPUT_ROWS_LIMIT];
284+
struct info_t invalid_key = {0};
285+
int fd = bpf_map__fd(obj->maps.counts);
286+
int err, i;
287+
288+
err = dump_hash(fd, keys, sizeof(struct info_t), values, sizeof(struct val_t),
289+
count, &invalid_key, true /* lookup_and_delete */);
290+
if (err)
291+
return err;
292+
293+
/* Store data in datas array */
294+
for (i = 0; i < *count; i++) {
295+
datas[i].key = keys[i];
296+
datas[i].value = values[i];
297+
}
298+
299+
return 0;
300+
}
301+
279302
static int print_stat(struct biotop_bpf *obj)
280303
{
281304
FILE *f;
282305
time_t t;
283306
struct tm *tm;
284307
char ts[16], buf[256];
285-
struct info_t *prev_key = NULL;
286308
static struct data_t datas[OUTPUT_ROWS_LIMIT];
287-
int n, i, err = 0, rows = 0;
288-
int fd = bpf_map__fd(obj->maps.counts);
309+
int n, i, err = 0, rows = OUTPUT_ROWS_LIMIT;
289310

290311
f = fopen("/proc/loadavg", "r");
291312
if (f) {
@@ -301,23 +322,10 @@ static int print_stat(struct biotop_bpf *obj)
301322
printf("%-7s %-16s %1s %-3s %-3s %-8s %5s %7s %6s\n",
302323
"PID", "COMM", "D", "MAJ", "MIN", "DISK", "I/O", "Kbytes", "AVGms");
303324

304-
while (1) {
305-
err = bpf_map_get_next_key(fd, prev_key, &datas[rows].key);
306-
if (err) {
307-
if (errno == ENOENT) {
308-
err = 0;
309-
break;
310-
}
311-
warn("bpf_map_get_next_key failed: %s\n", strerror(errno));
312-
return err;
313-
}
314-
err = bpf_map_lookup_elem(fd, &datas[rows].key, &datas[rows].value);
315-
if (err) {
316-
warn("bpf_map_lookup_elem failed: %s\n", strerror(errno));
317-
return err;
318-
}
319-
prev_key = &datas[rows].key;
320-
rows++;
325+
err = read_stat(obj, datas, (__u32*) &rows);
326+
if (err) {
327+
fprintf(stderr, "read stat failed: %s\n", strerror(errno));
328+
return err;
321329
}
322330

323331
qsort(datas, rows, sizeof(struct data_t), sort_column);
@@ -343,27 +351,6 @@ static int print_stat(struct biotop_bpf *obj)
343351
}
344352

345353
printf("\n");
346-
prev_key = NULL;
347-
348-
while (1) {
349-
struct info_t key;
350-
351-
err = bpf_map_get_next_key(fd, prev_key, &key);
352-
if (err) {
353-
if (errno == ENOENT) {
354-
err = 0;
355-
break;
356-
}
357-
warn("bpf_map_get_next_key failed: %s\n", strerror(errno));
358-
return err;
359-
}
360-
err = bpf_map_delete_elem(fd, &key);
361-
if (err) {
362-
warn("bpf_map_delete_elem failed: %s\n", strerror(errno));
363-
return err;
364-
}
365-
prev_key = &key;
366-
}
367354
return err;
368355
}
369356

0 commit comments

Comments
 (0)