tools/testing/selftests/bpf/libarena/src/spmc.bpf.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/libarena/src/spmc.bpf.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/libarena/src/spmc.bpf.c
Extension
.c
Size
4307 bytes
Lines
235
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

// SPDX-License-Identifier: LGPL-2.1 OR BSD-2-Clause
/*
 * Copyright (c) 2025-2026 Meta Platforms, Inc. and affiliates.
 * Copyright (c) 2025-2026 Emil Tsalapatis <etsal@meta.com>
 */

#include <bpf_atomic.h>

#include <libarena/common.h>

#include <libarena/asan.h>
#include <libarena/spmc.h>

static inline
u64 spmc_arr_size(volatile struct spmc_arr __arena *spmc_arr)
{
	return SPMC_ARR_BASESZ << spmc_arr->order;
}

static inline
u64 spmc_arr_get(volatile struct spmc_arr __arena *spmc_arr, u64 ind)
{
	u64 ret = READ_ONCE(spmc_arr->data[ind % spmc_arr_size(spmc_arr)]);

	return ret;
}

static inline
void spmc_arr_put(volatile struct spmc_arr __arena *spmc_arr, u64 ind, u64 value)
{
	WRITE_ONCE(spmc_arr->data[ind % spmc_arr_size(spmc_arr)], value);
}

static inline
void spmc_arr_copy(volatile struct spmc_arr __arena *dst,
		   volatile struct spmc_arr __arena *src, u64 b, u64 t)
{
	u64 i;

	for (i = t; i < b && can_loop; i++)
		spmc_arr_put(dst, i, spmc_arr_get(src, i));
}

static inline
int spmc_order_init(struct spmc __arena *spmc, int order)
{
	volatile struct spmc_arr __arena *arr = &spmc->arr[order];

	if (unlikely(!spmc))
		return -EINVAL;

	if (order >= SPMC_ARR_ORDERS)
		return -E2BIG;

	/* Already allocated? */
	if (arr->data)
		return 0;

	arr->data = arena_malloc((SPMC_ARR_BASESZ << order) * sizeof(*arr->data));
	if (!arr->data)
		return -ENOMEM;

	return 0;
}

__weak
int spmc_owned_add(struct spmc __arena *spmc, u64 val)
{
	volatile struct spmc_arr __arena *newarr;
	volatile struct spmc_arr __arena *arr;
	ssize_t sz;
	u64 b, t;
	int ret;

	if (unlikely(!spmc))
		return -EINVAL;

	/* 
	 * Bottom must always be read first, also
	 * see spmc_steal().
	 */
	b = smp_load_acquire(&spmc->bottom);
	t = READ_ONCE(spmc->top);
	arr = READ_ONCE(spmc->cur);

	sz = b - t;
	if (sz >= spmc_arr_size(arr) - 1) {
		ret = spmc_order_init(spmc, arr->order + 1);
		if (ret)
			return ret;

Annotation

Implementation Notes