File Index
Files and directories
Sign in
FILE

task_storage_map.c

File preview with syntax highlighting.

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