static int map_collect_percpu_devmap()

in bpf/xdp_sample_user.c [381:447]


static int map_collect_percpu_devmap(int map_fd, struct stats_record *rec)
{
	unsigned int nr_cpus = bpf_num_possible_cpus();
	__u32 batch, count = 32;
	struct datarec *values;
	bool init = false;
	__u64 *keys;
	int i, ret;

	keys = calloc(count, sizeof(__u64));
	if (!keys)
		return -ENOMEM;
	values = calloc(count * nr_cpus, sizeof(struct datarec));
	if (!values) {
		free(keys);
		return -ENOMEM;
	}

	for (;;) {
		bool exit = false;

		ret = bpf_map_lookup_batch(map_fd, init ? &batch : NULL, &batch,
					   keys, values, &count, NULL);
		if (ret < 0 && errno != ENOENT)
			break;
		if (errno == ENOENT)
			exit = true;

		init = true;
		for (i = 0; i < count; i++) {
			struct map_entry *e, *x = NULL;
			__u64 pair = keys[i];
			struct datarec *arr;

			arr = &values[i * nr_cpus];
			hash_for_each_possible(rec->xmit_map, e, node, pair) {
				if (e->pair == pair) {
					x = e;
					break;
				}
			}
			if (!x) {
				x = calloc(1, sizeof(*x));
				if (!x)
					goto cleanup;
				if (map_entry_init(x, pair) < 0) {
					free(x);
					goto cleanup;
				}
				hash_add(rec->xmit_map, &x->node, pair);
			}
			map_collect_percpu(arr, &x->val);
		}

		if (exit)
			break;
		count = 32;
	}

	free(values);
	free(keys);
	return 0;
cleanup:
	free(values);
	free(keys);
	return -ENOMEM;
}