mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-18 03:23:53 -04:00
Add a scheduler that uses BPF arenas to manage task context data. Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com> Signed-off-by: Tejun Heo <tj@kernel.org>
114 lines
2.4 KiB
C
114 lines
2.4 KiB
C
/*
|
|
* SPDX-License-Identifier: GPL-2.0
|
|
* Copyright (c) 2025 Meta Platforms, Inc. and affiliates.
|
|
* Copyright (c) 2025 Tejun Heo <tj@kernel.org>
|
|
* Copyright (c) 2025 Emil Tsalapatis <etsal@meta.com>
|
|
*/
|
|
#pragma once
|
|
|
|
#ifndef __BPF__
|
|
#define __arena
|
|
#endif /* __BPF__ */
|
|
|
|
struct scx_alloc_stats {
|
|
__u64 chunk_allocs;
|
|
__u64 data_allocs;
|
|
__u64 alloc_ops;
|
|
__u64 free_ops;
|
|
__u64 active_allocs;
|
|
__u64 arena_pages_used;
|
|
};
|
|
|
|
struct sdt_pool {
|
|
void __arena *slab;
|
|
__u64 elem_size;
|
|
__u64 max_elems;
|
|
__u64 idx;
|
|
};
|
|
|
|
#ifndef div_round_up
|
|
#define div_round_up(a, b) (((a) + (b) - 1) / (b))
|
|
#endif
|
|
|
|
#ifndef round_up
|
|
#define round_up(a, b) (div_round_up((a), (b)) * (b))
|
|
#endif
|
|
|
|
typedef struct sdt_desc __arena sdt_desc_t;
|
|
|
|
enum sdt_consts {
|
|
SDT_TASK_ENTS_PER_PAGE_SHIFT = 9,
|
|
SDT_TASK_LEVELS = 3,
|
|
SDT_TASK_ENTS_PER_CHUNK = 1 << SDT_TASK_ENTS_PER_PAGE_SHIFT,
|
|
SDT_TASK_CHUNK_BITMAP_U64S = div_round_up(SDT_TASK_ENTS_PER_CHUNK, 64),
|
|
SDT_TASK_MIN_ELEM_PER_ALLOC = 8,
|
|
};
|
|
|
|
union sdt_id {
|
|
__s64 val;
|
|
struct {
|
|
__s32 idx; /* index in the radix tree */
|
|
__s32 genn; /* ++'d on recycle so that it forms unique'ish 64bit ID */
|
|
};
|
|
};
|
|
|
|
struct sdt_chunk;
|
|
|
|
/*
|
|
* Each index page is described by the following descriptor which carries the
|
|
* bitmap. This way the actual index can host power-of-two numbers of entries
|
|
* which makes indexing cheaper.
|
|
*/
|
|
struct sdt_desc {
|
|
__u64 allocated[SDT_TASK_CHUNK_BITMAP_U64S];
|
|
__u64 nr_free;
|
|
struct sdt_chunk __arena *chunk;
|
|
};
|
|
|
|
/*
|
|
* Leaf node containing per-task data.
|
|
*/
|
|
struct sdt_data {
|
|
union sdt_id tid;
|
|
__u64 payload[];
|
|
};
|
|
|
|
/*
|
|
* Intermediate node pointing to another intermediate node or leaf node.
|
|
*/
|
|
struct sdt_chunk {
|
|
union {
|
|
sdt_desc_t * descs[SDT_TASK_ENTS_PER_CHUNK];
|
|
struct sdt_data __arena *data[SDT_TASK_ENTS_PER_CHUNK];
|
|
};
|
|
};
|
|
|
|
struct scx_allocator {
|
|
struct sdt_pool pool;
|
|
sdt_desc_t *root;
|
|
};
|
|
|
|
struct scx_stats {
|
|
int seq;
|
|
pid_t pid;
|
|
__u64 enqueue;
|
|
__u64 exit;
|
|
__u64 init;
|
|
__u64 select_busy_cpu;
|
|
__u64 select_idle_cpu;
|
|
};
|
|
|
|
#ifdef __BPF__
|
|
|
|
void __arena *scx_task_data(struct task_struct *p);
|
|
int scx_task_init(__u64 data_size);
|
|
void __arena *scx_task_alloc(struct task_struct *p);
|
|
void scx_task_free(struct task_struct *p);
|
|
void scx_arena_subprog_init(void);
|
|
|
|
int scx_alloc_init(struct scx_allocator *alloc, __u64 data_size);
|
|
u64 scx_alloc_internal(struct scx_allocator *alloc);
|
|
int scx_alloc_free_idx(struct scx_allocator *alloc, __u64 idx);
|
|
|
|
#endif /* __BPF__ */
|