Skip to content

Commit 3a6dc1a

Browse files
committed
libbpf-tools/profile: Batch lookup support for hash map
Use bpf_map_lookup_batch() instead of bpf_map_get_next_key() to read the hash map, if available.
1 parent 77c0591 commit 3a6dc1a

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

libbpf-tools/profile.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ struct ksyms *ksyms;
116116
struct syms_cache *syms_cache;
117117
struct syms *syms;
118118

119+
static bool batch_map_ops = true; /* hope for the best */
120+
119121
static error_t parse_arg(int key, char *arg, struct argp_state *state)
120122
{
121123
static int pos_args;
@@ -268,13 +270,61 @@ static int cmp_counts(const void *a, const void *b)
268270
return y - x;
269271
}
270272

273+
static int read_batch_counts_map(int fd, struct key_ext_t *items, __u32 *count)
274+
{
275+
struct key_t keys[*count];
276+
__u64 vals[*count];
277+
void *in = NULL, *out;
278+
__u32 i, n, n_read = 0;
279+
int err = 0;
280+
281+
while (n_read < *count && !err) {
282+
n = *count - n_read;
283+
err = bpf_map_lookup_batch(fd, &in, &out, keys + n_read,
284+
vals + n_read, &n, NULL);
285+
if (err < 0 && err != -ENOENT) {
286+
/* we want to propagate EINVAL upper, so that
287+
* the batch_map_ops flag is set to false */
288+
if (err != -EINVAL)
289+
fprintf(stderr, "bpf_map_lookup_batch: %s\n",
290+
strerror(-err));
291+
292+
return err;
293+
}
294+
295+
n_read += n;
296+
in = out;
297+
}
298+
299+
for (i = 0; i < n_read; i++) {
300+
items[i].k.pid = keys[i].pid;
301+
items[i].k.user_stack_id = keys[i].user_stack_id;
302+
items[i].k.kern_stack_id = keys[i].kern_stack_id;
303+
strncpy(items[i].k.name, keys[i].name, TASK_COMM_LEN);
304+
items[i].v = vals[i];
305+
}
306+
307+
*count = n_read;
308+
return 0;
309+
}
310+
271311
static int read_counts_map(int fd, struct key_ext_t *items, __u32 *count)
272312
{
273313
struct key_t empty = {};
274314
struct key_t *lookup_key = &empty;
275315
int i = 0;
276316
int err;
277317

318+
if (batch_map_ops) {
319+
err = read_batch_counts_map(fd, items, count);
320+
if (err < 0 && err == -EINVAL) {
321+
/* fall back to a racy variant */
322+
batch_map_ops = false;
323+
} else {
324+
return err;
325+
}
326+
}
327+
278328
while (bpf_map_get_next_key(fd, lookup_key, &items[i].k) == 0) {
279329
err = bpf_map_lookup_elem(fd, &items[i].k, &items[i].v);
280330
if (err < 0) {

0 commit comments

Comments
 (0)