tools/testing/selftests/bpf/benchs/bench_trigger.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/benchs/bench_trigger.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/benchs/bench_trigger.c
Extension
.c
Size
16652 bytes
Lines
675
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret < 1 || ret > MAX_TRIG_BATCH_ITERS) {
			fprintf(stderr, "invalid --trig-batch-iters value (should be between %d and %d)\n",
				1, MAX_TRIG_BATCH_ITERS);
			argp_usage(state);
		}
		args.batch_iters = ret;
		break;
	default:
		return ARGP_ERR_UNKNOWN;
	}

	return 0;
}

const struct argp bench_trigger_batch_argp = {
	.options = opts,
	.parser = parse_arg,
};

/* adjust slot shift in inc_hits() if changing */
#define MAX_BUCKETS 256

#pragma GCC diagnostic ignored "-Wattributes"

/* BPF triggering benchmarks */
static struct trigger_ctx {
	struct trigger_bench *skel;
	bool usermode_counters;
	int driver_prog_fd;
} ctx;

static struct counter base_hits[MAX_BUCKETS];

static __always_inline void inc_counter(struct counter *counters)
{
	static __thread int tid = 0;
	unsigned slot;

	if (unlikely(tid == 0))
		tid = sys_gettid();

	/* multiplicative hashing, it's fast */
	slot = 2654435769U * tid;
	slot >>= 24;

	atomic_inc(&base_hits[slot].value); /* use highest byte as an index */
}

static long sum_and_reset_counters(struct counter *counters)
{
	int i;
	long sum = 0;

	for (i = 0; i < MAX_BUCKETS; i++)
		sum += atomic_swap(&counters[i].value, 0);
	return sum;
}

static void trigger_validate(void)
{
	if (env.consumer_cnt != 0) {
		fprintf(stderr, "benchmark doesn't support consumer!\n");
		exit(1);
	}
}

static void *trigger_producer(void *input)
{
	if (ctx.usermode_counters) {
		while (true) {
			(void)syscall(__NR_getpgid);
			inc_counter(base_hits);
		}
	} else {
		while (true)
			(void)syscall(__NR_getpgid);
	}
	return NULL;
}

static void *trigger_producer_batch(void *input)
{
	int fd = ctx.driver_prog_fd ?: bpf_program__fd(ctx.skel->progs.trigger_driver);

	while (true)
		bpf_prog_test_run_opts(fd, NULL);

	return NULL;
}

Annotation

Implementation Notes