kernel/bpf/local_storage.c

Source file repositories/reference/linux-study-clean/kernel/bpf/local_storage.c

File Facts

System
Linux kernel
Corpus path
kernel/bpf/local_storage.c
Extension
.c
Size
15315 bytes
Lines
619
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct bpf_cgroup_storage_map {
	struct bpf_map map;

	spinlock_t lock;
	struct rb_root root;
	struct list_head list;
};

static struct bpf_cgroup_storage_map *map_to_storage(struct bpf_map *map)
{
	return container_of(map, struct bpf_cgroup_storage_map, map);
}

static bool attach_type_isolated(const struct bpf_map *map)
{
	return map->key_size == sizeof(struct bpf_cgroup_storage_key);
}

static int bpf_cgroup_storage_key_cmp(const struct bpf_cgroup_storage_map *map,
				      const void *_key1, const void *_key2)
{
	if (attach_type_isolated(&map->map)) {
		const struct bpf_cgroup_storage_key *key1 = _key1;
		const struct bpf_cgroup_storage_key *key2 = _key2;

		if (key1->cgroup_inode_id < key2->cgroup_inode_id)
			return -1;
		else if (key1->cgroup_inode_id > key2->cgroup_inode_id)
			return 1;
		else if (key1->attach_type < key2->attach_type)
			return -1;
		else if (key1->attach_type > key2->attach_type)
			return 1;
	} else {
		const __u64 *cgroup_inode_id1 = _key1;
		const __u64 *cgroup_inode_id2 = _key2;

		if (*cgroup_inode_id1 < *cgroup_inode_id2)
			return -1;
		else if (*cgroup_inode_id1 > *cgroup_inode_id2)
			return 1;
	}
	return 0;
}

struct bpf_cgroup_storage *
cgroup_storage_lookup(struct bpf_cgroup_storage_map *map,
		      void *key, bool locked)
{
	struct rb_root *root = &map->root;
	struct rb_node *node;

	if (!locked)
		spin_lock_bh(&map->lock);

	node = root->rb_node;
	while (node) {
		struct bpf_cgroup_storage *storage;

		storage = container_of(node, struct bpf_cgroup_storage, node);

		switch (bpf_cgroup_storage_key_cmp(map, key, &storage->key)) {
		case -1:
			node = node->rb_left;
			break;
		case 1:
			node = node->rb_right;
			break;
		default:
			if (!locked)
				spin_unlock_bh(&map->lock);
			return storage;
		}
	}

	if (!locked)
		spin_unlock_bh(&map->lock);

	return NULL;
}

static int cgroup_storage_insert(struct bpf_cgroup_storage_map *map,
				 struct bpf_cgroup_storage *storage)
{
	struct rb_root *root = &map->root;
	struct rb_node **new = &(root->rb_node), *parent = NULL;

	while (*new) {
		struct bpf_cgroup_storage *this;

Annotation

Implementation Notes