Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  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 <unistd.h>
  6#include <stdlib.h>
  7#include <stdbool.h>
  8#include <errno.h>
  9#include <string.h>
 10#include <pthread.h>
 11
 12#include <bpf/bpf.h>
 13#include <bpf/libbpf.h>
 14
 15#include "test_maps.h"
 16#include "task_local_storage_helpers.h"
 17#include "read_bpf_task_storage_busy.skel.h"
 18
 19struct lookup_ctx {
 20	bool start;
 21	bool stop;
 22	int pid_fd;
 23	int map_fd;
 24	int loop;
 25};
 26
 27static void *lookup_fn(void *arg)
 28{
 29	struct lookup_ctx *ctx = arg;
 30	long value;
 31	int i = 0;
 32
 33	while (!ctx->start)
 34		usleep(1);
 35
 36	while (!ctx->stop && i++ < ctx->loop)
 37		bpf_map_lookup_elem(ctx->map_fd, &ctx->pid_fd, &value);
 38	return NULL;
 39}
 40
 41static void abort_lookup(struct lookup_ctx *ctx, pthread_t *tids, unsigned int nr)
 42{
 43	unsigned int i;
 44
 45	ctx->stop = true;
 46	ctx->start = true;
 47	for (i = 0; i < nr; i++)
 48		pthread_join(tids[i], NULL);
 49}
 50
 51void test_task_storage_map_stress_lookup(void)
 52{
 53#define MAX_NR_THREAD 4096
 54	unsigned int i, nr = 256, loop = 8192, cpu = 0;
 55	struct read_bpf_task_storage_busy *skel;
 56	pthread_t tids[MAX_NR_THREAD];
 57	struct lookup_ctx ctx;
 58	cpu_set_t old, new;
 59	const char *cfg;
 60	int err;
 61
 62	cfg = getenv("TASK_STORAGE_MAP_NR_THREAD");
 63	if (cfg) {
 64		nr = atoi(cfg);
 65		if (nr > MAX_NR_THREAD)
 66			nr = MAX_NR_THREAD;
 67	}
 68	cfg = getenv("TASK_STORAGE_MAP_NR_LOOP");
 69	if (cfg)
 70		loop = atoi(cfg);
 71	cfg = getenv("TASK_STORAGE_MAP_PIN_CPU");
 72	if (cfg)
 73		cpu = atoi(cfg);
 74
 75	skel = read_bpf_task_storage_busy__open_and_load();
 76	err = libbpf_get_error(skel);
 77	CHECK(err, "open_and_load", "error %d\n", err);
 78
 79	/* Only for a fully preemptible kernel */
 80	if (!skel->kconfig->CONFIG_PREEMPT) {
 81		printf("%s SKIP (no CONFIG_PREEMPT)\n", __func__);
 82		read_bpf_task_storage_busy__destroy(skel);
 83		skips++;
 84		return;
 85	}
 86
 87	/* Save the old affinity setting */
 88	sched_getaffinity(getpid(), sizeof(old), &old);
 89
 90	/* Pinned on a specific CPU */
 91	CPU_ZERO(&new);
 92	CPU_SET(cpu, &new);
 93	sched_setaffinity(getpid(), sizeof(new), &new);
 94
 95	ctx.start = false;
 96	ctx.stop = false;
 97	ctx.pid_fd = sys_pidfd_open(getpid(), 0);
 98	ctx.map_fd = bpf_map__fd(skel->maps.task);
 99	ctx.loop = loop;
100	for (i = 0; i < nr; i++) {
101		err = pthread_create(&tids[i], NULL, lookup_fn, &ctx);
102		if (err) {
103			abort_lookup(&ctx, tids, i);
104			CHECK(err, "pthread_create", "error %d\n", err);
105			goto out;
106		}
107	}
108
109	ctx.start = true;
110	for (i = 0; i < nr; i++)
111		pthread_join(tids[i], NULL);
112
113	skel->bss->pid = getpid();
114	err = read_bpf_task_storage_busy__attach(skel);
115	CHECK(err, "attach", "error %d\n", err);
116
117	/* Trigger program */
118	syscall(SYS_gettid);
119	skel->bss->pid = 0;
120
121	CHECK(skel->bss->busy != 0, "bad bpf_task_storage_busy", "got %d\n", skel->bss->busy);
122out:
123	read_bpf_task_storage_busy__destroy(skel);
124	/* Restore affinity setting */
125	sched_setaffinity(getpid(), sizeof(old), &old);
126	printf("%s:PASS\n", __func__);
127}