tools/testing/selftests/bpf/prog_tests/task_local_data.h

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/task_local_data.h

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/task_local_data.h
Extension
.h
Size
11420 bytes
Lines
390
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

struct tld_metadata {
	char name[TLD_NAME_LEN];
	_Atomic __u16 size; /* size of tld_data_u->data */
};

struct tld_meta_u {
	_Atomic __u16 cnt;
	__u16 size;
	struct tld_metadata metadata[];
};

/*
 * The unused field ensures map_val.start > 0. On the BPF side, __tld_fetch_key()
 * calculates off by summing map_val.start and tld_key_t.off and treats off == 0
 * as key not cached.
 */
struct tld_data_u {
	__u64 unused;
	char data[] __attribute__((aligned(8)));
};

struct tld_map_value {
	void *data;
	struct tld_meta_u *meta;
	__u16 start; /* offset of tld_data_u->data in a page */
};

struct tld_meta_u * _Atomic tld_meta_p __attribute__((weak));
__thread struct tld_data_u *tld_data_p __attribute__((weak));

#ifdef TLD_FREE_DATA_ON_THREAD_EXIT
bool _Atomic tld_pthread_key_init __attribute__((weak));
pthread_key_t tld_pthread_key __attribute__((weak));

static void tld_free(void);

static void __tld_thread_exit_handler(void *unused)
{
	(void)unused;
	tld_free();
}
#endif

static int __tld_init_meta_p(void)
{
	struct tld_meta_u *meta, *uninit = NULL;
	int err = 0;

	meta = (struct tld_meta_u *)aligned_alloc(TLD_PAGE_SIZE, TLD_PAGE_SIZE);
	if (!meta) {
		err = -ENOMEM;
		goto out;
	}

	memset(meta, 0, TLD_PAGE_SIZE);
	meta->size = TLD_DYN_DATA_SIZE;

	if (!atomic_compare_exchange_strong(&tld_meta_p, &uninit, meta)) {
		free(meta);
		goto out;
	}

out:
	return err;
}

static int __tld_init_data_p(int map_fd)
{
	struct tld_map_value map_val;
	struct tld_data_u *data;
	int err, tid_fd = -1;
	size_t size, size_pot;

	tid_fd = syscall(SYS_pidfd_open, sys_gettid(), O_EXCL);
	if (tid_fd < 0) {
		err = -errno;
		goto out;
	}

	/*
	 * tld_meta_p->size = TLD_DYN_DATA_SIZE +
	 *          total size of TLDs defined via TLD_DEFINE_KEY()
	 */
	size = tld_meta_p->size + sizeof(struct tld_data_u);
	size_pot = TLD_ROUND_UP_POWER_OF_TWO(size);
#ifdef TLD_DONT_ROUND_UP_DATA_SIZE
	data = (struct tld_data_u *)aligned_alloc(size_pot, size);
#else
	data = (struct tld_data_u *)aligned_alloc(size_pot, size_pot);
#endif

Annotation

Implementation Notes