brintos

brintos / linux-shallow public Read only

0
0
Text · 2.6 KiB · 2bc85f4 Raw
127 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (C) 2022. Huawei Technologies Co., Ltd */3#define _GNU_SOURCE4#include <sched.h>5#include <stdbool.h>6#include <test_progs.h>7#include "htab_update.skel.h"8 9struct htab_update_ctx {10	int fd;11	int loop;12	bool stop;13};14 15static void test_reenter_update(void)16{17	struct htab_update *skel;18	unsigned int key, value;19	int err;20 21	skel = htab_update__open();22	if (!ASSERT_OK_PTR(skel, "htab_update__open"))23		return;24 25	/* lookup_elem_raw() may be inlined and find_kernel_btf_id() will return -ESRCH */26	bpf_program__set_autoload(skel->progs.lookup_elem_raw, true);27	err = htab_update__load(skel);28	if (!ASSERT_TRUE(!err || err == -ESRCH, "htab_update__load") || err)29		goto out;30 31	skel->bss->pid = getpid();32	err = htab_update__attach(skel);33	if (!ASSERT_OK(err, "htab_update__attach"))34		goto out;35 36	/* Will trigger the reentrancy of bpf_map_update_elem() */37	key = 0;38	value = 0;39	err = bpf_map_update_elem(bpf_map__fd(skel->maps.htab), &key, &value, 0);40	if (!ASSERT_OK(err, "add element"))41		goto out;42 43	ASSERT_EQ(skel->bss->update_err, -EBUSY, "no reentrancy");44out:45	htab_update__destroy(skel);46}47 48static void *htab_update_thread(void *arg)49{50	struct htab_update_ctx *ctx = arg;51	cpu_set_t cpus;52	int i;53 54	/* Pinned on CPU 0 */55	CPU_ZERO(&cpus);56	CPU_SET(0, &cpus);57	pthread_setaffinity_np(pthread_self(), sizeof(cpus), &cpus);58 59	i = 0;60	while (i++ < ctx->loop && !ctx->stop) {61		unsigned int key = 0, value = 0;62		int err;63 64		err = bpf_map_update_elem(ctx->fd, &key, &value, 0);65		if (err) {66			ctx->stop = true;67			return (void *)(long)err;68		}69	}70 71	return NULL;72}73 74static void test_concurrent_update(void)75{76	struct htab_update_ctx ctx;77	struct htab_update *skel;78	unsigned int i, nr;79	pthread_t *tids;80	int err;81 82	skel = htab_update__open_and_load();83	if (!ASSERT_OK_PTR(skel, "htab_update__open_and_load"))84		return;85 86	ctx.fd = bpf_map__fd(skel->maps.htab);87	ctx.loop = 1000;88	ctx.stop = false;89 90	nr = 4;91	tids = calloc(nr, sizeof(*tids));92	if (!ASSERT_NEQ(tids, NULL, "no mem"))93		goto out;94 95	for (i = 0; i < nr; i++) {96		err = pthread_create(&tids[i], NULL, htab_update_thread, &ctx);97		if (!ASSERT_OK(err, "pthread_create")) {98			unsigned int j;99 100			ctx.stop = true;101			for (j = 0; j < i; j++)102				pthread_join(tids[j], NULL);103			goto out;104		}105	}106 107	for (i = 0; i < nr; i++) {108		void *thread_err = NULL;109 110		pthread_join(tids[i], &thread_err);111		ASSERT_EQ(thread_err, NULL, "update error");112	}113 114out:115	if (tids)116		free(tids);117	htab_update__destroy(skel);118}119 120void test_htab_update(void)121{122	if (test__start_subtest("reenter_update"))123		test_reenter_update();124	if (test__start_subtest("concurrent_update"))125		test_concurrent_update();126}127