// SPDX-License-Identifier: GPL-2.0/* Copyright (C) 2022. Huawei Technologies Co., Ltd */#define _GNU_SOURCE#include <sched.h>#include <unistd.h>#include <stdlib.h>#include <stdbool.h>#include <errno.h>#include <string.h>#include <pthread.h> #include <bpf/bpf.h>#include <bpf/libbpf.h> #include "bpf_util.h"#include "test_maps.h"#include "task_local_storage_helpers.h"#include "read_bpf_task_storage_busy.skel.h" struct lookup_ctx { bool start; bool stop; int pid_fd; int map_fd; int loop;}; static void *lookup_fn(void *arg){ struct lookup_ctx *ctx = arg; long value; int i = 0; while (!ctx->start) usleep(1); while (!ctx->stop && i++ < ctx->loop) bpf_map_lookup_elem(ctx->map_fd, &ctx->pid_fd, &value); return NULL;} static void abort_lookup(struct lookup_ctx *ctx, pthread_t *tids, unsigned int nr){ unsigned int i; ctx->stop = true; ctx->start = true; for (i = 0; i < nr; i++) pthread_join(tids[i], NULL);} void test_task_storage_map_stress_lookup(void){#define MAX_NR_THREAD 4096 unsigned int i, nr = 256, loop = 8192, cpu = 0; struct read_bpf_task_storage_busy *skel; pthread_t tids[MAX_NR_THREAD]; struct lookup_ctx ctx; cpu_set_t old, new; const char *cfg; int err; cfg = getenv("TASK_STORAGE_MAP_NR_THREAD"); if (cfg) { nr = atoi(cfg); if (nr > MAX_NR_THREAD) nr = MAX_NR_THREAD; } cfg = getenv("TASK_STORAGE_MAP_NR_LOOP"); if (cfg) loop = atoi(cfg); cfg = getenv("TASK_STORAGE_MAP_PIN_CPU"); if (cfg) cpu = atoi(cfg); skel = read_bpf_task_storage_busy__open_and_load(); err = libbpf_get_error(skel); CHECK(err, "open_and_load", "error %d\n", err); /* Only for a fully preemptible kernel */ if (!skel->kconfig->CONFIG_PREEMPTION) { printf("%s SKIP (no CONFIG_PREEMPTION)\n", __func__); read_bpf_task_storage_busy__destroy(skel); skips++; return; } /* Save the old affinity setting */ sched_getaffinity(getpid(), sizeof(old), &old); /* Pinned on a specific CPU */ CPU_ZERO(&new); CPU_SET(cpu, &new); sched_setaffinity(getpid(), sizeof(new), &new); ctx.start = false; ctx.stop = false; ctx.pid_fd = sys_pidfd_open(getpid(), 0); ctx.map_fd = bpf_map__fd(skel->maps.task); ctx.loop = loop; for (i = 0; i < nr; i++) { err = pthread_create(&tids[i], NULL, lookup_fn, &ctx); if (err) { abort_lookup(&ctx, tids, i); CHECK(err, "pthread_create", "error %d\n", err); goto out; } } ctx.start = true; for (i = 0; i < nr; i++) pthread_join(tids[i], NULL); skel->bss->pid = getpid(); err = read_bpf_task_storage_busy__attach(skel); CHECK(err, "attach", "error %d\n", err); /* Trigger program */ sys_gettid(); skel->bss->pid = 0; CHECK(skel->bss->busy != 0, "bad bpf_task_storage_busy", "got %d\n", skel->bss->busy);out: read_bpf_task_storage_busy__destroy(skel); /* Restore affinity setting */ sched_setaffinity(getpid(), sizeof(old), &old); printf("%s:PASS\n", __func__);}
// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2022. Huawei Technologies Co., Ltd */
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include "bpf_util.h"
#include "test_maps.h"
#include "task_local_storage_helpers.h"
#include "read_bpf_task_storage_busy.skel.h"
struct lookup_ctx {
bool start;
bool stop;
int pid_fd;
int map_fd;
int loop;
};
static void *lookup_fn(void *arg)
{
struct lookup_ctx *ctx = arg;
long value;
int i = 0;
while (!ctx->start)
usleep(1);
while (!ctx->stop && i++ < ctx->loop)
bpf_map_lookup_elem(ctx->map_fd, &ctx->pid_fd, &value);
return NULL;
}
static void abort_lookup(struct lookup_ctx *ctx, pthread_t *tids, unsigned int nr)
{
unsigned int i;
ctx->stop = true;
ctx->start = true;
for (i = 0; i < nr; i++)
pthread_join(tids[i], NULL);
}
void test_task_storage_map_stress_lookup(void)
{
#define MAX_NR_THREAD 4096
unsigned int i, nr = 256, loop = 8192, cpu = 0;
struct read_bpf_task_storage_busy *skel;
pthread_t tids[MAX_NR_THREAD];
struct lookup_ctx ctx;
cpu_set_t old, new;
const char *cfg;
int err;
cfg = getenv("TASK_STORAGE_MAP_NR_THREAD");
if (cfg) {
nr = atoi(cfg);
if (nr > MAX_NR_THREAD)
nr = MAX_NR_THREAD;
}
cfg = getenv("TASK_STORAGE_MAP_NR_LOOP");
if (cfg)
loop = atoi(cfg);
cfg = getenv("TASK_STORAGE_MAP_PIN_CPU");
if (cfg)
cpu = atoi(cfg);
skel = read_bpf_task_storage_busy__open_and_load();
err = libbpf_get_error(skel);
CHECK(err, "open_and_load", "error %d\n", err);
/* Only for a fully preemptible kernel */
if (!skel->kconfig->CONFIG_PREEMPTION) {
printf("%s SKIP (no CONFIG_PREEMPTION)\n", __func__);
read_bpf_task_storage_busy__destroy(skel);
skips++;
return;
}
/* Save the old affinity setting */
sched_getaffinity(getpid(), sizeof(old), &old);
/* Pinned on a specific CPU */
CPU_ZERO(&new);
CPU_SET(cpu, &new);
sched_setaffinity(getpid(), sizeof(new), &new);
ctx.start = false;
ctx.stop = false;
ctx.pid_fd = sys_pidfd_open(getpid(), 0);
ctx.map_fd = bpf_map__fd(skel->maps.task);
ctx.loop = loop;
for (i = 0; i < nr; i++) {
err = pthread_create(&tids[i], NULL, lookup_fn, &ctx);
if (err) {
abort_lookup(&ctx, tids, i);
CHECK(err, "pthread_create", "error %d\n", err);
goto out;
}
}
ctx.start = true;
for (i = 0; i < nr; i++)
pthread_join(tids[i], NULL);
skel->bss->pid = getpid();
err = read_bpf_task_storage_busy__attach(skel);
CHECK(err, "attach", "error %d\n", err);
/* Trigger program */
sys_gettid();
skel->bss->pid = 0;
CHECK(skel->bss->busy != 0, "bad bpf_task_storage_busy", "got %d\n", skel->bss->busy);
out:
read_bpf_task_storage_busy__destroy(skel);
/* Restore affinity setting */
sched_setaffinity(getpid(), sizeof(old), &old);
printf("%s:PASS\n", __func__);
}