Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (C) 2022. Huawei Technologies Co., Ltd */
  3#define _GNU_SOURCE
  4#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}
v6.8
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (C) 2022. Huawei Technologies Co., Ltd */
  3#define _GNU_SOURCE
  4#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}