/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
#ifndef __TASK_LOCAL_DATA_BPF_H
#define __TASK_LOCAL_DATA_BPF_H

/*
 * Task local data is a library that facilitates sharing per-task data
 * between user space and bpf programs.
 *
 *
 * USAGE
 *
 * A TLD, an entry of data in task local data, first needs to be created by the
 * user space. This is done by calling user space API, TLD_DEFINE_KEY() or
 * tld_create_key(), with the name of the TLD and the size.
 *
 * TLD_DEFINE_KEY(prio, "priority", sizeof(int));
 *
 * or
 *
 * void func_call(...) {
 *     tld_key_t prio, in_cs;
 *
 *     prio = tld_create_key("priority", sizeof(int));
 *     in_cs = tld_create_key("in_critical_section", sizeof(bool));
 *     ...
 *
 * A key associated with the TLD, which has an opaque type tld_key_t, will be
 * initialized or returned. It can be used to get a pointer to the TLD in the
 * user space by calling tld_get_data().
 *
 * In a bpf program, tld_object_init() first needs to be called to initialized a
 * tld_object on the stack. Then, TLDs can be accessed by calling tld_get_data().
 * The API will try to fetch the key by the name and use it to locate the data.
 * A pointer to the TLD will be returned. It also caches the key in a task local
 * storage map, tld_key_map, whose value type, struct tld_keys, must be defined
 * by the developer.
 *
 * struct tld_keys {
 *     tld_key_t prio;
 *     tld_key_t in_cs;
 * };
 *
 * SEC("struct_ops")
 * void prog(struct task_struct task, ...)
 * {
 *     struct tld_object tld_obj;
 *     int err, *p;
 *
 *     err = tld_object_init(task, &tld_obj);
 *     if (err)
 *         return;
 *
 *     p = tld_get_data(&tld_obj, prio, "priority", sizeof(int));
 *     if (p)
 *         // do something depending on *p
 */
#include <errno.h>
#include <bpf/bpf_helpers.h>

#define TLD_ROUND_MASK(x, y) ((__typeof__(x))((y) - 1))
#define TLD_ROUND_UP(x, y) ((((x) - 1) | TLD_ROUND_MASK(x, y)) + 1)

#define TLD_MAX_DATA_CNT (__PAGE_SIZE / sizeof(struct tld_metadata) - 1)
#define TLD_DATA_SIZE (__PAGE_SIZE - sizeof(__u64))

#ifndef TLD_NAME_LEN
#define TLD_NAME_LEN 62
#endif

#ifndef TLD_KEY_MAP_CREATE_RETRY
#define TLD_KEY_MAP_CREATE_RETRY 10
#endif

typedef struct {
	__s16 off;
} tld_key_t;

struct tld_metadata {
	char name[TLD_NAME_LEN];
	__u16 size;
};

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

struct tld_data_u {
	__u64 unused;
	char data[__PAGE_SIZE - sizeof(__u64)] __attribute__((aligned(8)));
};

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

typedef struct tld_uptr_dummy {
	struct tld_data_u data[0];
	struct tld_meta_u meta[0];
} *tld_uptr_dummy_t;

struct tld_object {
	struct tld_map_value *data_map;
	struct tld_keys *key_map;
	/*
	 * Force the compiler to generate the actual definition of tld_meta_u
	 * and tld_data_u in BTF. Without it, tld_meta_u and u_tld_data will
	 * be BTF_KIND_FWD.
	 */
	tld_uptr_dummy_t dummy[0];
};

/*
 * Map value of tld_key_map for caching keys. Must be defined by the developer.
 * Members should be tld_key_t and passed to the 3rd argument of tld_fetch_key().
 */
struct tld_keys;

struct {
	__uint(type, BPF_MAP_TYPE_TASK_STORAGE);
	__uint(map_flags, BPF_F_NO_PREALLOC);
	__type(key, int);
	__type(value, struct tld_map_value);
} tld_data_map SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_TASK_STORAGE);
	__uint(map_flags, BPF_F_NO_PREALLOC);
	__type(key, int);
	__type(value, struct tld_keys);
} tld_key_map SEC(".maps");

/**
 * tld_object_init() - Initialize a tld_object.
 *
 * @task: The task_struct of the target task
 * @tld_obj: A pointer to a tld_object to be initialized
 *
 * Return 0 on success; -ENODATA if the user space did not initialize task local data
 * for the current task through tld_get_data(); -ENOMEM if the creation of tld_key_map
 * fails
 */
__attribute__((unused))
static int tld_object_init(struct task_struct *task, struct tld_object *tld_obj)
{
	int i;

	tld_obj->data_map = bpf_task_storage_get(&tld_data_map, task, 0, 0);
	if (!tld_obj->data_map)
		return -ENODATA;

	bpf_for(i, 0, TLD_KEY_MAP_CREATE_RETRY) {
		tld_obj->key_map = bpf_task_storage_get(&tld_key_map, task, 0,
							BPF_LOCAL_STORAGE_GET_F_CREATE);
		if (likely(tld_obj->key_map))
			break;
	}
	if (!tld_obj->key_map)
		return -ENOMEM;

	return 0;
}

/*
 * Return the offset of TLD if @name is found. Otherwise, return the current TLD count
 * using the nonpositive range so that the next tld_get_data() can skip fetching key if
 * no new TLD is added or start comparing name from the first newly added TLD.
 */
__attribute__((unused))
static int __tld_fetch_key(struct tld_object *tld_obj, const char *name, int i_start)
{
	struct tld_metadata *metadata;
	int i, cnt, start, off = 0;

	if (!tld_obj->data_map || !tld_obj->data_map->data || !tld_obj->data_map->meta)
		return 0;

	start = tld_obj->data_map->start;
	cnt = tld_obj->data_map->meta->cnt;
	metadata = tld_obj->data_map->meta->metadata;

	bpf_for(i, 0, cnt) {
		if (i >= TLD_MAX_DATA_CNT)
			break;

		if (i >= i_start && !bpf_strncmp(metadata[i].name, TLD_NAME_LEN, name))
			return start + off;

		off += TLD_ROUND_UP(metadata[i].size, 8);
		if (off > TLD_DATA_SIZE)
			break;
	}

	return -cnt;
}

/**
 * tld_get_data() - Retrieve a pointer to the TLD associated with the name.
 *
 * @tld_obj: A pointer to a valid tld_object initialized by tld_object_init()
 * @key: The cached key of the TLD in tld_key_map
 * @name: The name of the key associated with a TLD
 * @size: The size of the TLD. Must be a known constant value
 *
 * Return a pointer to the TLD associated with @name; NULL if not found or @size is too
 * big. @key is used to cache the key if the TLD is found to speed up subsequent calls.
 * It should be defined as an member of tld_keys of tld_key_t type by the developer.
 */
#define tld_get_data(tld_obj, key, name, size)						\
	({										\
		void *data = NULL, *_data = (tld_obj)->data_map->data;			\
		long off = (tld_obj)->key_map->key.off;					\
		int cnt;								\
											\
		if (likely(_data)) {							\
			if (likely(off > 0)) {						\
				barrier_var(off);					\
				if (likely(off < __PAGE_SIZE - size))			\
					data = _data + off;				\
			} else {							\
				cnt = -(off);						\
				if (likely((tld_obj)->data_map->meta) &&		\
				    cnt < (tld_obj)->data_map->meta->cnt) {		\
					off = __tld_fetch_key(tld_obj, name, cnt);	\
					(tld_obj)->key_map->key.off = off;		\
											\
					if (likely(off < __PAGE_SIZE - size)) {		\
						barrier_var(off);			\
						if (off > 0)				\
							data = _data + off;		\
					}						\
				}							\
			}								\
		}									\
		data;									\
	})

#endif
