#ifndef __CAKE_INTF_H
#define __CAKE_INTF_H
#include <limits.h>
#ifndef __VMLINUX_H__
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long u64;
typedef signed char s8;
typedef signed short s16;
typedef signed int s32;
typedef signed long s64;
#endif
enum cake_tier {
CAKE_TIER_CRITICAL = 0,
CAKE_TIER_INTERACT = 1,
CAKE_TIER_FRAME = 2,
CAKE_TIER_BULK = 3,
CAKE_TIER_MAX = 4,
};
enum cake_class {
CAKE_CLASS_NORMAL = 0,
CAKE_CLASS_GAME = 1,
CAKE_CLASS_HOG = 2,
CAKE_CLASS_BG = 3,
CAKE_CLASS_MAX = 4,
};
struct cake_task_hot {
u64 staged_vtime_bits;
u16 deficit_u16;
u16 wake_counter;
u32 packed_info;
u32 ppid;
u32 last_run_at;
u32 reclass_counter;
u16 warm_cpus[3];
u16 waker_cpu;
u64 nvcsw_snapshot;
u8 task_class;
u8 _pad_hot;
u16 vtime_mult;
u64 dsq_vtime;
};
struct cake_cpu_bss {
u32 run_start;
u8 is_yielder;
u8 idle_hint;
u8 tick_count;
u8 llc_id;
u64 tick_slice;
u64 vtime_local;
u32 last_pid;
u8 sched_state_local;
u8 _reserved[3];
u64 cached_now;
u8 _pad[88];
} __attribute__((aligned(128)));
#define CAKE_MAX_CPUS 256
#define CAKE_TELEM_MAX_CPUS 64
#define CAKE_MAX_LLCS 8
#define CAKE_MAX_AUDIO_TGIDS 8
#define CAKE_MAX_COMPOSITOR_TGIDS 4
#define LLC_DSQ_BASE 200
#define STAGED_BIT_VALID 63
#define STAGED_SHIFT_HOME 55
#define STAGED_BIT_BG_NOISE 53
#define STAGED_BIT_WAKER_BOOST 52
#define STAGED_BIT_GAME_MEMBER 51
#define STAGED_BIT_HOG 50
#define STAGED_BIT_WB_DUP 49
#define STAGED_BIT_NEW_FLOW 48
#define BENCH_ITERATIONS 8
enum kfunc_bench_id {
BENCH_KTIME_GET_NS = 0,
BENCH_SCX_BPF_NOW = 1,
BENCH_GET_SMP_PROC_ID = 2,
BENCH_TASK_FROM_PID = 3,
BENCH_TEST_CLEAR_IDLE = 4,
BENCH_NR_CPU_IDS = 5,
BENCH_GET_TASK_CTX = 6,
BENCH_DSQ_NR_QUEUED = 7,
BENCH_BSS_ARRAY_ACCESS = 8,
BENCH_ARENA_DEREF = 9,
BENCH_NOW_PAIR = 10,
BENCH_MBOX_CPU_READ = 11,
BENCH_TCTX_FROM_MBOX = 12,
BENCH_RINGBUF_CYCLE = 13,
BENCH_TASK_STRUCT_READ = 14,
BENCH_RODATA_LOOKUP = 15,
BENCH_BITFLAG_OPS = 16,
BENCH_RESERVED_17 = 17,
BENCH_PSYCHIC_HIT_SIM = 18,
BENCH_IDLE_REMOTE = 19,
BENCH_IDLE_SMTMASK = 20,
BENCH_DISRUPTOR_READ = 21,
BENCH_TCTX_COLD_SIM = 22,
BENCH_ARENA_STRIDE = 23,
BENCH_KTIME_BOOT_NS = 24,
BENCH_KTIME_COARSE_NS = 25,
BENCH_JIFFIES64 = 26,
BENCH_KTIME_TAI_NS = 27,
BENCH_CURRENT_PID_TGID = 28,
BENCH_CURRENT_TASK_BTF = 29,
BENCH_CURRENT_COMM = 30,
BENCH_NUMA_NODE_ID = 31,
BENCH_SCX_TASK_RUNNING = 32,
BENCH_SCX_TASK_CPU = 33,
BENCH_SCX_NR_NODE_IDS = 34,
BENCH_SCX_CPUPERF_CUR = 35,
BENCH_TASK_STORAGE_GET = 36,
BENCH_SCX_PICK_IDLE_CPU = 37,
BENCH_SCX_IDLE_CPUMASK = 38,
BENCH_SCX_KICK_CPU = 39,
BENCH_PRANDOM_U32 = 40,
BENCH_SPIN_LOCK = 41,
BENCH_SCX_CPUPERF_CAP = 42,
BENCH_RODATA_NR_CPUS = 43,
BENCH_RODATA_NR_NODES = 44,
BENCH_RODATA_CPUPERF_CAP = 45,
BENCH_ARENA_PID_TGID = 46,
BENCH_MBOX_TASK_CPU = 47,
BENCH_CL0_LOCKFREE = 48,
BENCH_BSS_XORSHIFT = 49,
BENCH_PELT_UTIL_AVG = 50,
BENCH_PELT_RUNNABLE_AVG = 51,
BENCH_SCHEDSTATS_WAKEUPS = 52,
BENCH_TASK_POLICY_FLAGS = 53,
BENCH_PELT_VS_EWMA = 54,
BENCH_STORAGE_ROUNDTRIP = 55,
BENCH_ARENA_ROUNDTRIP = 56,
BENCH_CASCADE_VS_PICK = 57,
BENCH_PICK_IDLE_FULL = 58,
BENCH_CLASSIFY_WEIGHT = 59,
BENCH_CLASSIFY_LATCRI = 60,
BENCH_SMT_CAKE_PROBE = 61,
BENCH_SMT_CPUMASK_PROBE = 62,
BENCH_STORAGE_GET_COLD = 63,
BENCH_PELT_COLD = 64,
BENCH_EWMA_COLD = 65,
BENCH_KICK_REMOTE = 66,
BENCH_MAX_ENTRIES = 67,
};
struct kfunc_bench_entry {
u64 min_ns;
u64 max_ns;
u64 total_ns;
u64 last_value;
u64 samples[BENCH_ITERATIONS];
};
struct kfunc_bench_results {
struct kfunc_bench_entry entries[BENCH_MAX_ENTRIES];
u32 cpu;
u32 iterations;
u64 bench_timestamp;
};
enum cake_flow_flags {
CAKE_FLOW_NEW = 1 << 0,
CAKE_FLOW_YIELDER = 1 << 1,
CAKE_FLOW_WAKER_BOOST = 1 << 2,
CAKE_FLOW_HOG = 1 << 3,
};
struct cake_iter_record {
u32 pid;
u32 ppid;
u32 packed_info;
u16 pelt_util;
u16 deficit_us;
u16 vtime_mult;
u16 _pad_iter;
struct {
u64 run_start_ns;
u64 run_duration_ns;
u64 enqueue_start_ns;
u64 wait_duration_ns;
u32 select_cpu_duration_ns;
u32 enqueue_duration_ns;
u32 dsq_insert_ns;
u32 gate_1_hits;
u32 gate_2_hits;
u32 gate_1w_hits;
u32 gate_3_hits;
u32 gate_1p_hits;
u32 gate_1c_hits;
u32 gate_1cp_hits;
u32 gate_1d_hits;
u32 gate_1wc_hits;
u32 gate_tun_hits;
u32 _pad2;
u64 jitter_accum_ns;
u32 total_runs;
u16 core_placement;
u16 migration_count;
u16 preempt_count;
u16 yield_count;
u16 direct_dispatch_count;
u16 enqueue_count;
u16 cpumask_change_count;
u16 _pad3;
u32 stopping_duration_ns;
u32 running_duration_ns;
u32 max_runtime_us;
u32 _pad4;
u64 dispatch_gap_ns;
u64 max_dispatch_gap_ns;
u32 wait_hist_lt10us;
u32 wait_hist_lt100us;
u32 wait_hist_lt1ms;
u32 wait_hist_ge1ms;
u16 slice_util_pct;
u16 llc_id;
u16 same_cpu_streak;
u16 _pad_recomp;
u32 wakeup_source_pid;
u64 nivcsw_snapshot;
u32 nvcsw_delta;
u32 nivcsw_delta;
u32 pid_inner;
u32 tgid;
char comm[16];
u32 gate_cascade_ns;
u32 idle_probe_ns;
u32 vtime_compute_ns;
u32 mbox_staging_ns;
u32 _pad_ewma;
u32 classify_ns;
u32 vtime_staging_ns;
u32 warm_history_ns;
u16 quantum_full_count;
u16 quantum_yield_count;
u16 quantum_preempt_count;
u16 _pad_quantum;
u16 waker_cpu;
u16 _pad_waker;
u32 waker_tgid;
u16 cpu_run_count[CAKE_TELEM_MAX_CPUS];
} telemetry;
};
#ifdef CAKE_RELEASE
#define CAKE_MBOX_SIZE 64
#define CAKE_MBOX_ALIGN 64
#define CAKE_TCTX_SIZE 64
#define CAKE_TCTX_ALIGN 64
#else
#define CAKE_MBOX_SIZE 128
#define CAKE_MBOX_ALIGN 128
#define CAKE_TCTX_SIZE 512
#define CAKE_TCTX_ALIGN 512
#endif
struct cake_task_ctx {
u64 staged_vtime_bits;
u16 deficit_u16;
u16 _ctx_pad;
u32 packed_info;
u32 ppid;
u32 last_run_at;
u32 reclass_counter;
u16 warm_cpus[3];
u16 waker_cpu;
u64 nvcsw_snapshot;
u8 task_class;
u8 _pad_ctx;
u16 vtime_mult;
u8 _pad_cl0[12];
#ifndef CAKE_RELEASE
struct {
u64 run_start_ns;
u64 run_duration_ns;
u64 enqueue_start_ns;
u64 wait_duration_ns;
u32 select_cpu_duration_ns;
u32 enqueue_duration_ns;
u32 dsq_insert_ns;
u32 gate_1_hits;
u32 gate_2_hits;
u32 gate_1w_hits;
u32 gate_3_hits;
u32 gate_1p_hits;
u32 gate_1c_hits;
u32 gate_1cp_hits;
u32 gate_1d_hits;
u32 gate_1wc_hits;
u32 gate_tun_hits;
u64 jitter_accum_ns;
u32 total_runs;
u16 core_placement;
u16 migration_count;
u16 preempt_count;
u16 yield_count;
u16 direct_dispatch_count;
u16 enqueue_count;
u16 cpumask_change_count;
u32 stopping_duration_ns;
u32 running_duration_ns;
u32 max_runtime_us;
u64 dispatch_gap_ns;
u64 max_dispatch_gap_ns;
u32 wait_hist_lt10us;
u32 wait_hist_lt100us;
u32 wait_hist_lt1ms;
u32 wait_hist_ge1ms;
u16 slice_util_pct;
u16 llc_id;
u16 same_cpu_streak;
u16 _pad_recomp;
u32 wakeup_source_pid;
u64 nivcsw_snapshot;
u32 nvcsw_delta;
u32 nivcsw_delta;
u32 pid;
u32 tgid;
char comm[16];
u32 gate_cascade_ns;
u32 idle_probe_ns;
u32 vtime_compute_ns;
u32 mbox_staging_ns;
u32 _pad_ewma;
u32 classify_ns;
u32 vtime_staging_ns;
u32 warm_history_ns;
u16 quantum_full_count;
u16 quantum_yield_count;
u16 quantum_preempt_count;
u16 _pad_quantum;
u16 waker_cpu;
u16 _pad_waker;
u32 waker_tgid;
u16 cpu_run_count[CAKE_TELEM_MAX_CPUS];
} telemetry;
#endif
} __attribute__((aligned(CAKE_TCTX_ALIGN)));
_Static_assert(
sizeof(struct cake_task_ctx) == CAKE_TCTX_SIZE,
"cake_task_ctx size mismatch (64B release, 512B debug)");
#define SHIFT_FLAGS 24
#define SHIFT_TIER 28
#define SHIFT_STABLE 30
#define BIT_KTHREAD 23
#define BIT_BG_NOISE 22
#define MASK_TIER 0x03
#define MASK_FLAGS 0x0F
struct mega_mailbox_entry {
u32 last_stopped_pid;
u32 idle_hint;
u32 last_tgid;
u8 _pad_cl0[52];
#ifndef CAKE_RELEASE
u8 is_yielder;
u8 tick_tier;
u16 cached_cpu;
u32 tick_last_run_at;
u64 tick_slice;
u64 cached_tctx_ptr;
u32 cached_deficit;
u32 cached_packed;
u64 cached_nvcsw;
u8 _pad_cl1[24];
#endif
} __attribute__((aligned(CAKE_MBOX_ALIGN)));
_Static_assert(
sizeof(struct mega_mailbox_entry) == CAKE_MBOX_SIZE,
"mega_mailbox_entry size mismatch (64B release, 128B debug)");
struct cake_stats {
u64 nr_new_flow_dispatches;
u64 nr_old_flow_dispatches;
u64 nr_tier_dispatches[CAKE_TIER_MAX];
u64 nr_starvation_preempts_tier
[CAKE_TIER_MAX];
u64 total_gate1_latency_ns;
u64 total_gate2_latency_ns;
u64 total_enqueue_latency_ns;
u64 nr_dropped_allocations;
u64 nr_local_dispatches;
u64 nr_stolen_dispatches;
u64 nr_dispatch_misses;
u64 nr_dispatch_hint_skip;
u64 nr_dsq_queued;
u64 nr_dsq_consumed;
u64 total_select_cpu_ns;
u64 total_stopping_ns;
u64 total_running_ns;
u64 max_select_cpu_ns;
u64 max_stopping_ns;
u64 max_running_ns;
u64 nr_stop_confidence_skip;
u64 nr_stop_classify;
u64 nr_stop_ramp;
u64 nr_stop_miss;
u64 total_dispatch_ns;
u64 max_dispatch_ns;
u64 nr_vprot_suppressed;
u64 nr_lag_applied;
u64 nr_capacity_scaled;
} __attribute__((aligned(64)));
#define CAKE_DEFAULT_QUANTUM_NS (2 * 1000 * 1000)
#define CAKE_DEFAULT_NEW_FLOW_BONUS_NS (3 * 1000 * 1000)
#define AQ_BULK_HEADROOM 1
#define AQ_MIN_NS (50 * 1000)
#define AQ_YIELDER_CEILING_NS (50 * 1000000)
#define AQ_BULK_CEILING_NS (2 * 1000000)
#define AQ_BULK_CEILING_COMPILE_NS (8 * 1000000)
#define CAKE_STATE_IDLE 0
#define CAKE_STATE_COMPILATION 1
#define CAKE_STATE_GAMING 2
#define CAKE_PREEMPT_YIELDER_THRESHOLD_NS (100 * 1000)
#define CAKE_PREEMPT_VIP_THRESHOLD_NS (50 * 1000)
#endif