/* SPDX-License-Identifier: GPL-2.0 */
/*
 * scx_qmap: a demonstration and testing scheduler for sched_ext features.
 *
 * A simple scheduler that exercises a broad set of sched_ext features. Unlikely
 * to be useful for real workloads. It demonstrates:
 *
 * - BPF-side queueing using TIDs.
 * - BPF arena for scheduler state.
 * - Core-sched support.
 * - Hierarchical sub-scheduling: delegating cpus to child cgroup schedulers.
 *
 * Base design: Five FIFOs (arena-backed doubly-linked lists through per-task
 * context). A task is assigned to a FIFO by its compound weight. Each cpu
 * round-robins the FIFOs, dispatching more from higher ones.
 *
 * Sub-scheduling: Any qmap sched can delegate cpus to its own child cgroup
 * schedulers and keep the rest for its tasks. Terminology:
 *
 *   excl   - A cpu the delegatee owns wholly (ENQ_IMMED|ENQ|PREEMPT).
 *   shared - A cpu delegated as ENQ_IMMED only. Time-shared.
 *   held_excl / held_shared - What this node was handed by its parent.
 *            held-excl cpus are re-delegatable. A held-shared cpu is a
 *            time-share that stays self-local.
 *   self   - The excl cpus the node kept for itself, plus all of held_shared.
 *   owner  - Who holds a cid - a child slot, CID_SELF, or CID_NONE.
 *   avail  - Cpus whose caps are in effect, per ops.sub_ecaps_updated().
 *   usable - self AND avail. Placement decisions use this: self is the
 *            delegation split and can run ahead of what the cpus honor.
 *
 * The scheduler splits its held-excl cpus among self and the children in
 * proportion to each node's cpu.weight, handing each the floor of its share as
 * excl cpus. The leftover from rounding forms a shared pool the round-robin
 * timer hands around. With no excl cpu to delegate, the node evicts its
 * children.
 *
 * This policy is a demonstration only, not a practical one. The split
 * considers only direct children and is not work-conserving. It only exists to
 * drive sub-sched primitives with as simple logic as possible.
 *
 * Copyright (c) 2022 Meta Platforms, Inc. and affiliates.
 * Copyright (c) 2022 Tejun Heo <tj@kernel.org>
 * Copyright (c) 2022 David Vernet <dvernet@meta.com>
 */
#include <scx/common.bpf.h>

#include "scx_qmap.h"

enum consts {
	ONE_SEC_IN_NS		= 1000000000,
	ONE_MSEC_IN_NS		= 1000000,
	LOWPRI_INTV_NS		= 10 * ONE_MSEC_IN_NS,
	SHARED_DSQ		= 0,
	HIGHPRI_DSQ		= 1,
	LOWPRI_DSQ		= 2,
	HIGHPRI_WEIGHT		= 8668,		/* this is what -20 maps to */
};

char _license[] SEC("license") = "GPL";

const volatile u64 slice_ns;
const volatile u32 stall_user_nth;
const volatile u32 stall_kernel_nth;
const volatile u32 dsp_inf_loop_after;
const volatile u32 dsp_batch;
const volatile bool highpri_boosting;
const volatile bool print_dsqs_and_events;
const volatile bool print_msgs;
const volatile u64 sub_cgroup_id;
const volatile s32 disallow_tgid;
const volatile bool suppress_dump;
const volatile u32 immed_stress_nth;
const volatile u32 max_tasks;

/* sub-sched: period for handing the round-robin cid pool to the next child */
const volatile u64 round_robin_ns;

/*
 * Optional cid-override test harness. When cid_override_mode is non-zero,
 * qmap_init_cids() calls scx_bpf_cid_override() with the caller-supplied arrays
 * to exercise the kfunc's acceptance and error paths. See enum
 * qmap_cid_override for the modes.
 */
const volatile u32 cid_override_mode;
const volatile u32 cid_override_nr_shards;

UEI_DEFINE(uei);

/*
 * All scheduler state - per-cpu context, stats counters, core-sched sequence
 * numbers, sub-sched cgroup ids - lives in this single BPF arena map. Userspace
 * reaches it via skel->arena->qa.
 */
struct {
	__uint(type, BPF_MAP_TYPE_ARENA);
	__uint(map_flags, BPF_F_MMAPABLE);
	__uint(max_entries, 1 << 16);		/* upper bound in pages */
#if defined(__TARGET_ARCH_arm64) || defined(__aarch64__)
	__ulong(map_extra, 0x1ull << 32);	/* user/BPF mmap base */
#else
	__ulong(map_extra, 0x1ull << 44);
#endif
} arena SEC(".maps");

struct qmap_arena __arena_global qa;

/* ensure that BPF and userspace are seeing the same size for qmap_cmask */
_Static_assert(QMAP_CMASK_WORDS == CMASK_NR_WORDS(SCX_QMAP_MAX_CPUS),
	       "QMAP_CMASK_WORDS must equal CMASK_NR_WORDS(SCX_QMAP_MAX_CPUS)");
_Static_assert(sizeof(struct qmap_cmask) ==
	       struct_size_t(struct scx_cmask, bits, QMAP_CMASK_WORDS),
	       "qmap_cmask must be exactly sized to back a full scx_cmask");

/* Per-queue locks. Each in its own .data section as bpf_res_spin_lock requires. */
__hidden struct bpf_res_spin_lock qa_q_lock0 SEC(".data.qa_q_lock0");
__hidden struct bpf_res_spin_lock qa_q_lock1 SEC(".data.qa_q_lock1");
__hidden struct bpf_res_spin_lock qa_q_lock2 SEC(".data.qa_q_lock2");
__hidden struct bpf_res_spin_lock qa_q_lock3 SEC(".data.qa_q_lock3");
__hidden struct bpf_res_spin_lock qa_q_lock4 SEC(".data.qa_q_lock4");

static struct bpf_res_spin_lock *qa_q_lock(s32 qid)
{
	switch (qid) {
	case 0:	return &qa_q_lock0;
	case 1:	return &qa_q_lock1;
	case 2:	return &qa_q_lock2;
	case 3:	return &qa_q_lock3;
	case 4:	return &qa_q_lock4;
	default: return NULL;
	}
}

/*
 * If enabled, CPU performance target is set according to the queue index
 * according to the following table.
 */
static const u32 qidx_to_cpuperf_target[] = {
	[0] = SCX_CPUPERF_ONE * 0 / 4,
	[1] = SCX_CPUPERF_ONE * 1 / 4,
	[2] = SCX_CPUPERF_ONE * 2 / 4,
	[3] = SCX_CPUPERF_ONE * 3 / 4,
	[4] = SCX_CPUPERF_ONE * 4 / 4,
};

/*
 * Per-queue sequence numbers to implement core-sched ordering.
 *
 * Tail seq is assigned to each queued task and incremented. Head seq tracks the
 * sequence number of the latest dispatched task. The distance between the a
 * task's seq and the associated queue's head seq is called the queue distance
 * and used when comparing two tasks for ordering. See qmap_core_sched_before().
 */

/*
 * Per-task scheduling context. Allocated from the qa.task_ctxs[] slab in
 * arena. While the task is alive the entry is referenced from task_ctx_stor;
 * while it's free the entry sits on the free list singly-linked through
 * @next_free.
 *
 * When the task is queued on one of the five priority FIFOs, @q_idx is the
 * queue index and @q_next/@q_prev link it in the queue's doubly-linked list.
 * @q_idx is -1 when the task isn't on any queue.
 */
struct task_ctx {
	struct task_ctx __arena	*next_free;	/* only valid on free list */
	struct task_ctx __arena	*q_next;	/* queue link, NULL if tail */
	struct task_ctx __arena	*q_prev;	/* queue link, NULL if head */
	struct qmap_fifo __arena *fifo;		/* queue we're on, NULL if not queued */
	u64			tid;
	s32			pid;	/* for dump only */
	bool			force_local;	/* Dispatch directly to local_dsq */
	bool			highpri;
	u64			core_sched_seq;
	struct scx_cmask	cpus_allowed;	/* per-task affinity in cid space */
};

/*
 * Slab stride for task_ctx. cpus_allowed's flex array bits[] overlaps the
 * tail bytes appended per entry; struct_size() gives the actual per-entry
 * footprint.
 */
#define TASK_CTX_STRIDE							\
	struct_size_t(struct task_ctx, cpus_allowed.bits,		\
		      CMASK_NR_WORDS(SCX_QMAP_MAX_CPUS))

/* All task_ctx pointers are arena pointers. */
typedef struct task_ctx __arena task_ctx_t;

/* Holds an arena pointer to the task's slab entry. */
struct task_ctx_stor_val {
	task_ctx_t		*taskc;
};

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

/* Protects the task_ctx slab free list. */
__hidden struct bpf_res_spin_lock qa_task_lock SEC(".data.qa_task_lock");

static int qmap_spin_lock(struct bpf_res_spin_lock *lock)
{
	if (bpf_res_spin_lock(lock)) {
		scx_bpf_error("res_spin_lock failed");
		return -EBUSY;
	}
	return 0;
}

/*
 * Try prev_cid, then scan cpus_allowed AND idle_cids AND usable_cids
 * round-robin from prev_cid + 1. Atomic claim retries on race; bounded by
 * IDLE_PICK_RETRIES to keep the verifier's insn budget in check.
 */
#define IDLE_PICK_RETRIES	16

static s32 pick_direct_dispatch_cid(struct task_struct *p, s32 prev_cid,
				    task_ctx_t *taskc)
{
	u32 nr_cids = scx_bpf_nr_cids();
	s32 cid;
	u32 i;

	if (cmask_test(prev_cid, &qa.usable_cids.mask) &&
	    cmask_test_and_clear(prev_cid, &qa.idle_cids.mask))
		return prev_cid;

	cid = prev_cid;
	bpf_for(i, 0, IDLE_PICK_RETRIES) {
		cid = cmask_next_and2_set_wrap(&taskc->cpus_allowed,
					       &qa.idle_cids.mask,
					       &qa.usable_cids.mask, cid + 1);
		barrier_var(cid);
		if (cid >= nr_cids)
			return -1;
		if (cmask_test_and_clear(cid, &qa.idle_cids.mask))
			return cid;
	}
	return -1;
}

/*
 * Force a reference to the arena map. The verifier associates an arena with
 * a program by finding an LD_IMM64 instruction that loads the arena's BPF
 * map; programs that only use arena pointers returned from task-local
 * storage (like qmap_select_cpu) never reference @arena directly. Without
 * this, the verifier rejects addr_space_cast with "addr_space_cast insn
 * can only be used in a program that has an associated arena".
 */
#define QMAP_TOUCH_ARENA() do { asm volatile("" :: "r"(&arena)); } while (0)

static task_ctx_t *lookup_task_ctx(struct task_struct *p)
{
	struct task_ctx_stor_val *v;

	QMAP_TOUCH_ARENA();

	v = bpf_task_storage_get(&task_ctx_stor, p, 0, 0);
	if (!v || !v->taskc)
		return NULL;
	return v->taskc;
}

/* Append @taskc to the tail of @fifo. Must not already be queued. */
static void qmap_fifo_enqueue(struct qmap_fifo __arena *fifo, task_ctx_t *taskc)
{
	struct bpf_res_spin_lock *lock = qa_q_lock(fifo->idx);

	if (!lock || qmap_spin_lock(lock))
		return;
	taskc->fifo = fifo;
	taskc->q_next = NULL;
	taskc->q_prev = fifo->tail;
	if (fifo->tail)
		fifo->tail->q_next = taskc;
	else
		fifo->head = taskc;
	fifo->tail = taskc;
	bpf_res_spin_unlock(lock);
}

/* Pop the head of @fifo. Returns NULL if empty. */
static task_ctx_t *qmap_fifo_pop(struct qmap_fifo __arena *fifo)
{
	struct bpf_res_spin_lock *lock = qa_q_lock(fifo->idx);
	task_ctx_t *taskc;

	if (!lock || qmap_spin_lock(lock))
		return NULL;
	taskc = fifo->head;
	if (taskc) {
		fifo->head = taskc->q_next;
		if (taskc->q_next)
			taskc->q_next->q_prev = NULL;
		else
			fifo->tail = NULL;
		taskc->q_next = NULL;
		taskc->q_prev = NULL;
		taskc->fifo = NULL;
	}
	bpf_res_spin_unlock(lock);
	return taskc;
}

/* Remove @taskc from its fifo. No-op if not queued. */
static void qmap_fifo_remove(task_ctx_t *taskc)
{
	struct qmap_fifo __arena *fifo = taskc->fifo;
	struct bpf_res_spin_lock *lock;

	if (!fifo)
		return;

	lock = qa_q_lock(fifo->idx);
	if (!lock || qmap_spin_lock(lock))
		return;

	/* Re-check under lock — a concurrent pop may have cleared fifo. */
	if (taskc->fifo != fifo) {
		bpf_res_spin_unlock(lock);
		return;
	}

	if (taskc->q_next)
		taskc->q_next->q_prev = taskc->q_prev;
	else
		fifo->tail = taskc->q_prev;
	if (taskc->q_prev)
		taskc->q_prev->q_next = taskc->q_next;
	else
		fifo->head = taskc->q_next;
	taskc->q_next = NULL;
	taskc->q_prev = NULL;
	taskc->fifo = NULL;
	bpf_res_spin_unlock(lock);
}

s32 BPF_STRUCT_OPS(qmap_select_cid, struct task_struct *p,
		   s32 prev_cid, u64 wake_flags)
{
	task_ctx_t *taskc;
	s32 cid;

	if (!(taskc = lookup_task_ctx(p)))
		return prev_cid;

	if (p->scx.weight < 2 && !(p->flags & PF_KTHREAD))
		return prev_cid;

	cid = pick_direct_dispatch_cid(p, prev_cid, taskc);

	if (cid >= 0) {
		taskc->force_local = true;
		return cid;
	} else {
		return prev_cid;
	}
}

/*
 * A received time-shared cid is held ENQ_IMMED-only, so inserts meant to run
 * there must set SCX_ENQ_IMMED.
 */
static u64 needs_immed(s32 cid)
{
	return qa.cid_shared[cid] ? SCX_ENQ_IMMED : 0;
}

/* first cid this node does NOT hold for fault injection, -1 if none */
static s32 first_unavail_cid(void)
{
	s32 nr_cids = qa.nr_cids, c;

	if (nr_cids > SCX_QMAP_MAX_CPUS) {
		scx_bpf_error("-ERANGE");
		return -1;
	}

	bpf_for(c, 0, nr_cids) {
		if (!cmask_test(c, &qa.held_excl.mask) &&
		    !cmask_test(c, &qa.held_shared.mask))
			return c;
	}
	return -1;
}

static int weight_to_idx(u32 weight)
{
	/* Coarsely map the compound weight to a FIFO. */
	if (weight <= 25)
		return 0;
	else if (weight <= 50)
		return 1;
	else if (weight < 200)
		return 2;
	else if (weight < 400)
		return 3;
	else
		return 4;
}

void BPF_STRUCT_OPS(qmap_enqueue, struct task_struct *p, u64 enq_flags)
{
	static u32 user_cnt, kernel_cnt;
	task_ctx_t *taskc;
	int idx = weight_to_idx(p->scx.weight);
	s32 cid;

	if (enq_flags & SCX_ENQ_REENQ) {
		u64 reason = p->scx.flags & SCX_TASK_REENQ_REASON_MASK;

		__sync_fetch_and_add(&qa.nr_reenqueued, 1);
		if (scx_bpf_task_cid(p) == 0)
			__sync_fetch_and_add(&qa.nr_reenqueued_cid0, 1);
		/* cap-loss and IMMED-handback bounces, relocated below */
		if (reason == SCX_TASK_REENQ_CAP)
			__sync_fetch_and_add(&qa.nr_reenq_cap, 1);
		else if (reason == SCX_TASK_REENQ_IMMED)
			__sync_fetch_and_add(&qa.nr_reenq_immed, 1);
	}

	if (p->flags & PF_KTHREAD) {
		if (stall_kernel_nth && !(++kernel_cnt % stall_kernel_nth))
			return;
	} else {
		if (stall_user_nth && !(++user_cnt % stall_user_nth))
			return;
	}

	if (qa.test_error_cnt && !--qa.test_error_cnt)
		scx_bpf_error("test triggering error");

	if (!(taskc = lookup_task_ctx(p)))
		return;

	/*
	 * All enqueued tasks must have their core_sched_seq updated for correct
	 * core-sched ordering. Also, take a look at the end of qmap_dispatch().
	 */
	taskc->core_sched_seq = qa.core_sched_tail_seqs[idx]++;

	/*
	 * A task of ours that can run on none of our self cids - the parent
	 * didn't grant them or we delegated them to children - would starve in
	 * SHARED/FIFO since we only pull from those on self cids.
	 *
	 * Force it onto its first allowed cid's local DSQ with SCX_ENQ_RESCUE.
	 * If we hold ENQ on that cid it runs. Otherwise the kernel diverts the
	 * task to its rescue path. IMMED would turn the insert into a legal
	 * placement on a time-shared cid and the kernel would bounce it back
	 * here instead of rescuing it.
	 */
	if (!cmask_intersects(&taskc->cpus_allowed, &qa.self_cids.mask)) {
		s32 c = cmask_next_set_wrap(&taskc->cpus_allowed, 0);

		if (c >= 0 && c < scx_bpf_nr_cids()) {
			taskc->force_local = false;
			__sync_fetch_and_add(&qa.nr_rescue_dsp, 1);
			scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL_ON | c, slice_ns,
					   enq_flags | SCX_ENQ_RESCUE);
			return;
		}
	}

	/*
	 * Fault injection: deliberately dispatch one of our own tasks to a cid
	 * we don't hold. The inserts carry SCX_ENQ_RESCUE and divert to the
	 * kernel rescue path, a deterministic rescue-traffic generator. Under
	 * -B 0 the kernel cap check rejects and re-enqueues them instead, so
	 * nr_inject_attempts tracks nr_reenq_cap 1:1 and proves delivery-time
	 * enforcement. Throttled.
	 */
	if (qa.inject_mode == QMAP_INJ_WRONG_CID && p->nr_cpus_allowed > 1 &&
	    !(enq_flags & SCX_ENQ_REENQ)) {
		static u32 inj_cnt;

		if (!(++inj_cnt % 64)) {
			s32 bad = first_unavail_cid();

			if (bad >= 0 && cmask_test(bad, &taskc->cpus_allowed)) {
				__sync_fetch_and_add(&qa.nr_inject_attempts, 1);
				__sync_fetch_and_add(&qa.nr_rescue_dsp, 1);
				scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL_ON | bad, slice_ns,
						   enq_flags | SCX_ENQ_RESCUE);
				return;
			}
		}
	}

	/*
	 * IMMED stress testing: Every immed_stress_nth'th enqueue, dispatch
	 * directly to prev_cpu's local DSQ even when busy to force dsq->nr > 1
	 * and exercise the kernel IMMED reenqueue trigger paths.
	 */
	if (immed_stress_nth && !(enq_flags & SCX_ENQ_REENQ)) {
		static u32 immed_stress_cnt;

		if (!(++immed_stress_cnt % immed_stress_nth)) {
			taskc->force_local = false;
			scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL_ON | scx_bpf_task_cid(p),
					   slice_ns, enq_flags);
			return;
		}
	}

	/*
	 * If qmap_select_cid() is telling us to or this is the last runnable
	 * task on the CPU, enqueue locally.
	 */
	if (taskc->force_local) {
		taskc->force_local = false;
		scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL, slice_ns,
				   enq_flags | needs_immed(scx_bpf_task_cid(p)));
		return;
	}

	/* see lowpri_timerfn() */
	if (__COMPAT_has_generic_reenq() &&
	    p->scx.weight < 2 && !(p->flags & PF_KTHREAD) && !(enq_flags & SCX_ENQ_REENQ)) {
		scx_bpf_dsq_insert(p, LOWPRI_DSQ, slice_ns, enq_flags);
		return;
	}

	/* if select_cid() wasn't called, try direct dispatch */
	if (!__COMPAT_is_enq_cpu_selected(enq_flags) &&
	    (cid = pick_direct_dispatch_cid(p, scx_bpf_task_cid(p), taskc)) >= 0) {
		__sync_fetch_and_add(&qa.nr_ddsp_from_enq, 1);
		scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL_ON | cid, slice_ns,
				   enq_flags | needs_immed(cid));
		return;
	}

	/*
	 * If the task was re-enqueued due to the CPU being preempted by a
	 * higher priority scheduling class, just re-enqueue the task directly
	 * on the global DSQ. As we want another CPU to pick it up, find and
	 * kick an idle cid.
	 */
	if (enq_flags & SCX_ENQ_REENQ) {
		s32 cid;

		scx_bpf_dsq_insert(p, SHARED_DSQ, 0, enq_flags);
		cid = cmask_next_and2_set_wrap(&taskc->cpus_allowed,
					       &qa.idle_cids.mask,
					       &qa.usable_cids.mask, 0);
		if (cid < scx_bpf_nr_cids())
			scx_bpf_kick_cid(cid, SCX_KICK_IDLE);
		return;
	}

	/* Queue on the selected FIFO. */
	qmap_fifo_enqueue(&qa.fifos[idx], taskc);

	if (highpri_boosting && p->scx.weight >= HIGHPRI_WEIGHT) {
		taskc->highpri = true;
		__sync_fetch_and_add(&qa.nr_highpri_queued, 1);
	}
	__sync_fetch_and_add(&qa.nr_enqueued, 1);
}

void BPF_STRUCT_OPS(qmap_dequeue, struct task_struct *p, u64 deq_flags)
{
	task_ctx_t *taskc;

	__sync_fetch_and_add(&qa.nr_dequeued, 1);
	if (deq_flags & SCX_DEQ_CORE_SCHED_EXEC)
		__sync_fetch_and_add(&qa.nr_core_sched_execed, 1);

	taskc = lookup_task_ctx(p);
	if (taskc && taskc->fifo) {
		if (taskc->highpri)
			__sync_fetch_and_sub(&qa.nr_highpri_queued, 1);
		qmap_fifo_remove(taskc);
	}
}

static void update_core_sched_head_seq(struct task_struct *p)
{
	int idx = weight_to_idx(p->scx.weight);
	task_ctx_t *taskc;

	if ((taskc = lookup_task_ctx(p)))
		qa.core_sched_head_seqs[idx] = taskc->core_sched_seq;
}

/*
 * One pass over SHARED_DSQ: rescue stranded tasks and boost highpri ones. A
 * task whose cids were lost while it was queued in the fifos would strand on
 * SHARED_DSQ, which is consumed only on self cids it can't run on - move it to
 * the kernel rescue path. One whose cids were lost after the highpri cull is
 * likewise rescued out of HIGHPRI_DSQ below.
 *
 * To demonstrate the use of scx_bpf_dsq_move(), implement silly selective
 * priority boosting mechanism by moving highpri tasks to HIGHPRI_DSQ and then
 * consuming them first. This makes minor difference only when dsp_batch is
 * larger than 1.
 *
 * scx_bpf_dsq_move[_vtime]() are allowed both from ops.dispatch() and
 * non-rq-lock holding BPF programs. As demonstration, this function is called
 * from qmap_dispatch() and monitor_timerfn().
 */
static bool scan_shared_dsq(bool from_timer)
{
	struct task_struct *p;
	s32 this_cid = scx_bpf_this_cid();
	u32 nr_cids = scx_bpf_nr_cids();

	/* rescue strands and move highpri tasks to HIGHPRI_DSQ */
	bpf_for_each(scx_dsq, p, SHARED_DSQ, 0) {
		static u64 highpri_seq;
		task_ctx_t *taskc;
		s32 c;

		if (!(taskc = lookup_task_ctx(p)))
			return false;

		/* stranded? rescue - it can't be dispatched here either way */
		if (!cmask_intersects(&taskc->cpus_allowed, &qa.self_cids.mask)) {
			c = cmask_next_set_wrap(&taskc->cpus_allowed, 0);
			if (c >= 0 && c < scx_bpf_nr_cids()) {
				__sync_fetch_and_add(&qa.nr_rescue_dsp, 1);
				scx_bpf_dsq_move(BPF_FOR_EACH_ITER, p, SCX_DSQ_LOCAL_ON | c,
						 SCX_ENQ_RESCUE);
			}
			continue;
		}

		if (taskc->highpri) {
			/* exercise the set_*() and vtime interface too */
			scx_bpf_dsq_move_set_slice(BPF_FOR_EACH_ITER, slice_ns * 2);
			scx_bpf_dsq_move_set_vtime(BPF_FOR_EACH_ITER, highpri_seq++);
			scx_bpf_dsq_move_vtime(BPF_FOR_EACH_ITER, p, HIGHPRI_DSQ, 0);
		}
	}

	/*
	 * Scan HIGHPRI_DSQ and dispatch until a task that can run here is
	 * found. Prefer this_cid if the task allows it; otherwise RR-scan the
	 * task's cpus_allowed starting after this_cid.
	 */
	bpf_for_each(scx_dsq, p, HIGHPRI_DSQ, 0) {
		task_ctx_t *taskc;
		bool dispatched = false;
		s32 cid;

		if (!(taskc = lookup_task_ctx(p)))
			return false;

		/* only run highpri tasks on cids this node can use right now */
		if (cmask_test(this_cid, &taskc->cpus_allowed) &&
		    cmask_test(this_cid, &qa.usable_cids.mask))
			cid = this_cid;
		else
			cid = cmask_next_and_set_wrap(&taskc->cpus_allowed,
						      &qa.usable_cids.mask,
						      this_cid + 1);
		if (cid >= nr_cids) {
			s32 c;

			/* self cids lack caps in effect yet, leave it queued */
			if (cmask_intersects(&taskc->cpus_allowed, &qa.self_cids.mask))
				continue;

			/* stranded after the cull - rescue it from here */
			c = cmask_next_set_wrap(&taskc->cpus_allowed, 0);
			if (c >= 0 && c < nr_cids) {
				__sync_fetch_and_add(&qa.nr_rescue_dsp, 1);
				scx_bpf_dsq_move(BPF_FOR_EACH_ITER, p, SCX_DSQ_LOCAL_ON | c,
						 SCX_ENQ_RESCUE);
			}
			continue;
		}

		if (scx_bpf_dsq_move(BPF_FOR_EACH_ITER, p, SCX_DSQ_LOCAL_ON | cid,
				     SCX_ENQ_PREEMPT | needs_immed(cid))) {
			if (cid == this_cid) {
				dispatched = true;
				__sync_fetch_and_add(&qa.nr_expedited_local, 1);
			} else {
				__sync_fetch_and_add(&qa.nr_expedited_remote, 1);
			}
			if (from_timer)
				__sync_fetch_and_add(&qa.nr_expedited_from_timer, 1);
		} else {
			__sync_fetch_and_add(&qa.nr_expedited_lost, 1);
		}

		if (dispatched)
			return true;
	}

	return false;
}

void BPF_STRUCT_OPS(qmap_dispatch, s32 cid, struct task_struct *prev)
{
	struct task_struct *p;
	struct cpu_ctx __arena *cpuc;
	task_ctx_t *taskc;
	u32 batch = dsp_batch ?: 1;
	s32 owner, i;

	if (scan_shared_dsq(false))
		return;

	/*
	 * Sub-sched routing: a child-owned cid goes to its owner. Never run
	 * this node's own tasks on a delegated cid. Read without the guard.
	 */
	owner = qa.part.cid_owner[cid];
	if (owner == CID_SHARED) {
		/* route to the live rr holder (0 = self, runs below) */
		s32 pos = qa.part.rr_pos;
		u64 holder_cgid = (pos >= 0 && pos < MAX_PARTS) ?
				  qa.part.rr_slots[pos] : 0;

		if (holder_cgid) {
			scx_bpf_sub_dispatch(holder_cgid);
			return;
		}
	} else if (owner >= 0 && owner < MAX_SUB_SCHEDS) {
		u64 cgid = qa.sub_sched_ctxs[owner].cgroup_id;

		if (cgid) {
			if (scx_bpf_sub_dispatch(cgid))
				__sync_fetch_and_add(&qa.sub_sched_ctxs[owner].nr_dsps, 1);
			return;
		}
	}

	if (!qa.nr_highpri_queued && scx_bpf_dsq_move_to_local(SHARED_DSQ, needs_immed(cid)))
		return;

	if (dsp_inf_loop_after && qa.nr_dispatched > dsp_inf_loop_after) {
		/*
		 * PID 2 should be kthreadd which should mostly be idle and off
		 * the scheduler. Let's keep dispatching it to force the kernel
		 * to call this function over and over again.
		 */
		p = bpf_task_from_pid(2);
		if (p) {
			scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL, slice_ns, 0);
			bpf_task_release(p);
			return;
		}
	}

	cpuc = &qa.cpu_ctxs[scx_bpf_this_cid()];

	for (i = 0; i < 5; i++) {
		/* Advance the dispatch cursor and pick the fifo. */
		if (!cpuc->dsp_cnt) {
			cpuc->dsp_idx = (cpuc->dsp_idx + 1) % 5;
			cpuc->dsp_cnt = 1 << cpuc->dsp_idx;
		}

		/* Dispatch or advance. */
		bpf_repeat(BPF_MAX_LOOPS) {
			task_ctx_t *taskc;

			taskc = qmap_fifo_pop(&qa.fifos[cpuc->dsp_idx]);
			if (!taskc)
				break;

			p = scx_bpf_tid_to_task(taskc->tid);
			if (!p)
				continue;

			if (taskc->highpri)
				__sync_fetch_and_sub(&qa.nr_highpri_queued, 1);

			update_core_sched_head_seq(p);
			__sync_fetch_and_add(&qa.nr_dispatched, 1);

			scx_bpf_dsq_insert(p, SHARED_DSQ, slice_ns, 0);

			/*
			 * scx_qmap uses a global BPF queue that any CPU's
			 * dispatch can pop from. If this CPU popped a task that
			 * can't run here, it gets stranded on SHARED_DSQ after
			 * consume_dispatch_q() skips it. Kick the task's home
			 * CPU so it drains SHARED_DSQ.
			 *
			 * There's a race between the pop and the flush of the
			 * buffered dsq_insert:
			 *
			 *  CPU 0 (dispatching)      CPU 1 (home, idle)
			 *  ~~~~~~~~~~~~~~~~~~~      ~~~~~~~~~~~~~~~~~~~
			 *  pop from BPF queue
			 *  dsq_insert(buffered)
			 *                           balance:
			 *                             SHARED_DSQ empty
			 *                             BPF queue empty
			 *                             -> goes idle
			 *  flush -> on SHARED
			 *  kick CPU 1
			 *                           wakes, drains task
			 *
			 * The kick prevents indefinite stalls but a per-CPU
			 * kthread like ksoftirqd can be briefly stranded when
			 * its home CPU enters idle with softirq pending,
			 * triggering:
			 *
			 *  "NOHZ tick-stop error: local softirq work is pending, handler #N!!!"
			 *
			 * from report_idle_softirq(). The kick lands shortly
			 * after and the home CPU drains the task. This could be
			 * avoided by e.g. dispatching pinned tasks to local or
			 * global DSQs, but the current code is left as-is to
			 * document this class of issue -- other schedulers
			 * seeing similar warnings can use this as a reference.
			 */
			if (!cmask_test(cid, &taskc->cpus_allowed))
				scx_bpf_kick_cid(scx_bpf_task_cid(p), 0);
			batch--;
			cpuc->dsp_cnt--;
			if (!batch || !scx_bpf_dispatch_nr_slots()) {
				if (scan_shared_dsq(false) ||
				    scx_bpf_dsq_move_to_local(SHARED_DSQ, needs_immed(cid)))
					return;
				goto prev;
			}
			if (!cpuc->dsp_cnt)
				break;
		}

		cpuc->dsp_cnt = 0;
	}

	if (scan_shared_dsq(false))
		return;
prev:
	/*
	 * No other tasks. @prev will keep running. Update its core_sched_seq as
	 * if the task were enqueued and dispatched immediately.
	 *
	 * No @prev to keep running means the CPU goes idle. If its claim was
	 * never used, that is not a transition and ops.update_idle() stays
	 * silent. Restore the claim here.
	 */
	if (prev) {
		taskc = lookup_task_ctx(prev);
		if (!taskc)
			return;

		taskc->core_sched_seq =
			qa.core_sched_tail_seqs[weight_to_idx(prev->scx.weight)]++;
	} else {
		cmask_set(cid, &qa.idle_cids.mask);
	}
}

void BPF_STRUCT_OPS(qmap_tick, struct task_struct *p)
{
	struct cpu_ctx __arena *cpuc = &qa.cpu_ctxs[scx_bpf_this_cid()];
	int idx;

	/*
	 * Use the running avg of weights to select the target cpuperf level.
	 * This is a demonstration of the cpuperf feature rather than a
	 * practical strategy to regulate CPU frequency.
	 */
	cpuc->avg_weight = cpuc->avg_weight * 3 / 4 + p->scx.weight / 4;
	idx = weight_to_idx(cpuc->avg_weight);
	cpuc->cpuperf_target = qidx_to_cpuperf_target[idx];

	scx_bpf_cidperf_set(scx_bpf_task_cid(p), cpuc->cpuperf_target);
}

/*
 * The distance from the head of the queue scaled by the weight of the queue.
 * The lower the number, the older the task and the higher the priority.
 */
static s64 task_qdist(struct task_struct *p, task_ctx_t *taskc)
{
	int idx = weight_to_idx(p->scx.weight);
	s64 qdist;

	qdist = taskc->core_sched_seq - qa.core_sched_head_seqs[idx];

	/*
	 * As queue index increments, the priority doubles. The queue w/ index 3
	 * is dispatched twice more frequently than 2. Reflect the difference by
	 * scaling qdists accordingly. Note that the shift amount needs to be
	 * flipped depending on the sign to avoid flipping priority direction.
	 */
	if (qdist >= 0)
		return qdist << (4 - idx);
	else
		return qdist << idx;
}

/*
 * This is called to determine the task ordering when core-sched is picking
 * tasks to execute on SMT siblings and should encode about the same ordering as
 * the regular scheduling path. Use the priority-scaled distances from the head
 * of the queues to compare the two tasks which should be consistent with the
 * dispatch path behavior.
 */
bool BPF_STRUCT_OPS(qmap_core_sched_before,
		    struct task_struct *a, struct task_struct *b)
{
	task_ctx_t *taskc_a = lookup_task_ctx(a);
	task_ctx_t *taskc_b = lookup_task_ctx(b);

	/*
	 * A task delegated to a sub-scheduler has no task_ctx here. Order such
	 * pairs by the kernel's default ordering - a running task after every
	 * waiting task, then by runnable_at.
	 */
	if (!taskc_a || !taskc_b) {
		if (a->on_cpu != b->on_cpu)
			return b->on_cpu;
		return time_before(a->scx.runnable_at, b->scx.runnable_at);
	}

	return task_qdist(a, taskc_a) < task_qdist(b, taskc_b);
}

/*
 * sched_switch tracepoint and cpu_release handlers are no longer needed.
 * With SCX_OPS_ALWAYS_ENQ_IMMED, wakeup_preempt_scx() reenqueues IMMED
 * tasks when a higher-priority scheduling class takes the CPU.
 */

s32 BPF_STRUCT_OPS_SLEEPABLE(qmap_init_task, struct task_struct *p,
			     struct scx_init_task_args *args)
{
	struct task_ctx_stor_val *v;
	task_ctx_t *taskc;

	if (qa.inject_mode == QMAP_INJ_INIT_FAIL &&
	    !bpf_strncmp(p->comm, 6, "qmfail"))
		return -ENOMEM;

	if (p->tgid == disallow_tgid)
		p->scx.disallow = true;

	/* pop a slab entry off the free list */
	if (qmap_spin_lock(&qa_task_lock))
		return -EBUSY;
	taskc = qa.task_free_head;
	if (taskc)
		qa.task_free_head = taskc->next_free;
	bpf_res_spin_unlock(&qa_task_lock);
	if (!taskc) {
		scx_bpf_error("task_ctx slab exhausted (max_tasks=%u)", max_tasks);
		return -ENOMEM;
	}

	taskc->next_free = NULL;
	taskc->q_next = NULL;
	taskc->q_prev = NULL;
	taskc->fifo = NULL;
	taskc->tid = p->scx.tid;
	taskc->pid = p->pid;
	taskc->force_local = false;
	taskc->highpri = false;
	taskc->core_sched_seq = 0;
	cmask_init(&taskc->cpus_allowed, 0, scx_bpf_nr_cids());
	bpf_rcu_read_lock();
	cmask_from_cpumask(&taskc->cpus_allowed, p->cpus_ptr);
	bpf_rcu_read_unlock();

	v = bpf_task_storage_get(&task_ctx_stor, p, NULL,
				 BPF_LOCAL_STORAGE_GET_F_CREATE);
	if (!v) {
		/* push back to the free list */
		if (!qmap_spin_lock(&qa_task_lock)) {
			taskc->next_free = qa.task_free_head;
			qa.task_free_head = taskc;
			bpf_res_spin_unlock(&qa_task_lock);
		}
		return -ENOMEM;
	}
	v->taskc = taskc;
	return 0;
}

void BPF_STRUCT_OPS(qmap_exit_task, struct task_struct *p,
		    struct scx_exit_task_args *args)
{
	struct task_ctx_stor_val *v;
	task_ctx_t *taskc;

	v = bpf_task_storage_get(&task_ctx_stor, p, NULL, 0);
	if (!v || !v->taskc)
		return;
	taskc = v->taskc;
	v->taskc = NULL;

	if (qmap_spin_lock(&qa_task_lock))
		return;
	taskc->next_free = qa.task_free_head;
	qa.task_free_head = taskc;
	bpf_res_spin_unlock(&qa_task_lock);
}

void BPF_STRUCT_OPS(qmap_dump, struct scx_dump_ctx *dctx)
{
	task_ctx_t *taskc;
	s32 i;

	QMAP_TOUCH_ARENA();

	if (suppress_dump)
		return;

	/*
	 * Walk the queue lists without locking - kfunc calls (scx_bpf_dump)
	 * aren't in the verifier's kfunc_spin_allowed() list so we can't hold
	 * a lock and dump. Best-effort; racing may print stale tids but the
	 * walk is bounded by bpf_repeat() so it always terminates.
	 */
	bpf_for(i, 0, 5) {
		scx_bpf_dump("QMAP FIFO[%d]:", i);
		taskc = qa.fifos[i].head;
		bpf_repeat(4096) {
			if (!taskc)
				break;
			scx_bpf_dump(" %d:%llu", taskc->pid, taskc->tid);
			taskc = taskc->q_next;
		}
		scx_bpf_dump("\n");
	}
}

void BPF_STRUCT_OPS(qmap_dump_cid, struct scx_dump_ctx *dctx, s32 cid, bool idle)
{
	struct cpu_ctx __arena *cpuc = &qa.cpu_ctxs[cid];

	if (suppress_dump || idle)
		return;

	scx_bpf_dump("QMAP: dsp_idx=%llu dsp_cnt=%llu avg_weight=%u cpuperf_target=%u",
		     cpuc->dsp_idx, cpuc->dsp_cnt, cpuc->avg_weight,
		     cpuc->cpuperf_target);
}

void BPF_STRUCT_OPS(qmap_dump_task, struct scx_dump_ctx *dctx, struct task_struct *p)
{
	struct task_ctx_stor_val *v;
	task_ctx_t *taskc;

	QMAP_TOUCH_ARENA();

	if (suppress_dump)
		return;
	v = bpf_task_storage_get(&task_ctx_stor, p, NULL, 0);
	if (!v || !v->taskc)
		return;
	taskc = v->taskc;

	scx_bpf_dump("QMAP: force_local=%d core_sched_seq=%llu",
		     taskc->force_local, taskc->core_sched_seq);
}

s32 BPF_STRUCT_OPS(qmap_cpuctl_init, struct cgroup *cgrp, struct scx_cgroup_init_args *args)
{
	QMAP_TOUCH_ARENA();

	if (print_msgs)
		bpf_printk("CGRP INIT %llu weight=%u period=%lu quota=%ld burst=%lu",
			   cgrp->kn->id, args->weight, args->bw_period_us,
			   args->bw_quota_us, args->bw_burst_us);

	if (qa.inject_mode == QMAP_INJ_CGRP_INIT_FAIL) {
		char name[7] = {};

		bpf_probe_read_kernel_str(name, sizeof(name), cgrp->kn->name);
		if (!bpf_strncmp(name, 6, "qmfail"))
			return -ENOMEM;
	}

	return 0;
}

static void redistribute(void);

void BPF_STRUCT_OPS(qmap_cpuctl_set_weight, struct cgroup *cgrp, u32 weight)
{
	u64 cgid = cgrp->kn->id;
	s32 i;

	QMAP_TOUCH_ARENA();

	if (print_msgs)
		bpf_printk("CGRP SET %llu weight=%u", cgid, weight);

	/*
	 * Knobs belong to the parent, so this op carries the child subs'
	 * attach point weights. Adjust the matching sub's share of the cid
	 * partition. Other cgroups don't participate in the split.
	 */
	for (i = 0; i < MAX_SUB_SCHEDS; i++) {
		if (qa.sub_sched_ctxs[i].cgroup_id != cgid)
			continue;
		if (qa.sub_sched_ctxs[i].weight != weight) {
			qa.sub_sched_ctxs[i].weight = weight;
			redistribute();
		}
		break;
	}
}

void BPF_STRUCT_OPS(qmap_cpuctl_set_bandwidth, struct cgroup *cgrp, u64 period_us,
		    u64 quota_us, u64 burst_us)
{
	if (print_msgs)
		bpf_printk("CGRP SET %llu period=%lu quota=%ld burst=%lu",
			   cgrp->kn->id, period_us, quota_us, burst_us);
}

void BPF_STRUCT_OPS(qmap_cpuctl_move, struct task_struct *p, struct cgroup *from,
		    struct cgroup *to)
{
	if (print_msgs)
		bpf_printk("CGRP MOVE %d %llu -> %llu",
			   p->pid, from->kn->id, to->kn->id);
}

void BPF_STRUCT_OPS(qmap_update_idle, s32 cid, bool idle)
{
	QMAP_TOUCH_ARENA();

	/*
	 * The kernel delivers update_idle() for every cid this node holds
	 * SCX_CAP_BASE on. Track every cid's idle state regardless of
	 * delegation: the direct-dispatch pick masks idle_cids with usable_cids
	 * at selection, so a cid already idle when it returns to self needs no
	 * reseed here.
	 */
	if (idle)
		cmask_set(cid, &qa.idle_cids.mask);
	else
		cmask_clear(cid, &qa.idle_cids.mask);
}

void BPF_STRUCT_OPS(qmap_set_cmask, struct task_struct *p,
		    const struct scx_cmask *cmask_in)
{
	struct scx_cmask __arena *cmask = (struct scx_cmask __arena *)(long)cmask_in;
	task_ctx_t *taskc;

	taskc = lookup_task_ctx(p);
	if (!taskc)
		return;
	cmask_copy(&taskc->cpus_allowed, cmask);
}

struct monitor_timer {
	struct bpf_timer timer;
};

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, 1);
	__type(key, u32);
	__type(value, struct monitor_timer);
} monitor_timer SEC(".maps");

/*
 * Aggregate cidperf across the first nr_online_cids cids. Post-hotplug
 * the first-N-are-online invariant drifts, so some cap/cur values may
 * be stale. For this demo monitor that's fine; the scheduler exits on
 * the enable-time hotplug_seq mismatch and userspace restarts, which
 * rebuilds the layout.
 */
static void monitor_cpuperf(void)
{
	u32 nr_online = scx_bpf_nr_online_cids();
	u64 cap_sum = 0, cur_sum = 0, cur_min = SCX_CPUPERF_ONE, cur_max = 0;
	u64 target_sum = 0, target_min = SCX_CPUPERF_ONE, target_max = 0;
	s32 cid;

	QMAP_TOUCH_ARENA();

	bpf_for(cid, 0, nr_online) {
		struct cpu_ctx __arena *cpuc = &qa.cpu_ctxs[cid];
		u32 cap = scx_bpf_cidperf_cap(cid);
		u32 cur = scx_bpf_cidperf_cur(cid);
		u32 target;

		cur_min = cur < cur_min ? cur : cur_min;
		cur_max = cur > cur_max ? cur : cur_max;

		cur_sum += (u64)cur * cap / SCX_CPUPERF_ONE;
		cap_sum += cap;

		target = cpuc->cpuperf_target;
		target_sum += target;
		target_min = target < target_min ? target : target_min;
		target_max = target > target_max ? target : target_max;
	}

	if (!nr_online || !cap_sum)
		return;

	qa.cpuperf_min = cur_min;
	qa.cpuperf_avg = cur_sum * SCX_CPUPERF_ONE / cap_sum;
	qa.cpuperf_max = cur_max;

	qa.cpuperf_target_min = target_min;
	qa.cpuperf_target_avg = target_sum / nr_online;
	qa.cpuperf_target_max = target_max;
}

/*
 * Dump the currently queued tasks in the shared DSQ to demonstrate the usage of
 * scx_bpf_dsq_nr_queued() and DSQ iterator. Raise the dispatch batch count to
 * see meaningful dumps in the trace pipe.
 */
static void dump_shared_dsq(void)
{
	struct task_struct *p;
	s32 nr;

	if (!(nr = scx_bpf_dsq_nr_queued(SHARED_DSQ)))
		return;

	bpf_printk("Dumping %d tasks in SHARED_DSQ in reverse order", nr);

	bpf_rcu_read_lock();
	bpf_for_each(scx_dsq, p, SHARED_DSQ, SCX_DSQ_ITER_REV)
		bpf_printk("%s[%d]", p->comm, p->pid);
	bpf_rcu_read_unlock();
}

static int monitor_timerfn(void *map, int *key, struct bpf_timer *timer)
{
	bpf_rcu_read_lock();
	scan_shared_dsq(true);
	bpf_rcu_read_unlock();

	monitor_cpuperf();

	if (print_dsqs_and_events) {
		struct scx_event_stats events;

		dump_shared_dsq();

		__COMPAT_scx_bpf_events(&events, sizeof(events));

		bpf_printk("%35s: %lld", "SCX_EV_SELECT_CPU_FALLBACK",
			   scx_read_event(&events, SCX_EV_SELECT_CPU_FALLBACK));
		bpf_printk("%35s: %lld", "SCX_EV_DISPATCH_LOCAL_DSQ_OFFLINE",
			   scx_read_event(&events, SCX_EV_DISPATCH_LOCAL_DSQ_OFFLINE));
		bpf_printk("%35s: %lld", "SCX_EV_DISPATCH_KEEP_LAST",
			   scx_read_event(&events, SCX_EV_DISPATCH_KEEP_LAST));
		bpf_printk("%35s: %lld", "SCX_EV_ENQ_SKIP_EXITING",
			   scx_read_event(&events, SCX_EV_ENQ_SKIP_EXITING));
		bpf_printk("%35s: %lld", "SCX_EV_REFILL_SLICE_DFL",
			   scx_read_event(&events, SCX_EV_REFILL_SLICE_DFL));
		bpf_printk("%35s: %lld", "SCX_EV_BYPASS_DURATION",
			   scx_read_event(&events, SCX_EV_BYPASS_DURATION));
		bpf_printk("%35s: %lld", "SCX_EV_BYPASS_DISPATCH",
			   scx_read_event(&events, SCX_EV_BYPASS_DISPATCH));
		bpf_printk("%35s: %lld", "SCX_EV_BYPASS_ACTIVATE",
			   scx_read_event(&events, SCX_EV_BYPASS_ACTIVATE));
	}

	if (bpf_timer_start(timer, ONE_SEC_IN_NS, 0))
		scx_bpf_error("failed to re-arm stats timer");
	return 0;
}

struct lowpri_timer {
	struct bpf_timer timer;
};

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, 1);
	__type(key, u32);
	__type(value, struct lowpri_timer);
} lowpri_timer SEC(".maps");

/*
 * Nice 19 tasks are put into the lowpri DSQ. Every 10ms, reenq is triggered and
 * the tasks are transferred to SHARED_DSQ.
 */
static int lowpri_timerfn(void *map, int *key, struct bpf_timer *timer)
{
	scx_bpf_dsq_reenq(LOWPRI_DSQ, 0);
	if (bpf_timer_start(timer, LOWPRI_INTV_NS, 0))
		scx_bpf_error("failed to re-arm lowpri timer");
	return 0;
}

struct round_robin_timer {
	struct bpf_timer timer;
};

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, 1);
	__type(key, u32);
	__type(value, struct round_robin_timer);
} round_robin_timer SEC(".maps");

enum part_pending_flags {
	PART_REFRESH = BIT_U64(0),
	PART_REDISTRIBUTE = BIT_U64(1),
};

/*
 * Partition update synchronization. qa.part can be written from concurrent
 * contexts. This single-runner guard admits one writer at a time without
 * holding a lock across the grant/revoke kfuncs. part_pending coalesces
 * refresh and repartition requests that arrive while it is held.
 *
 * They live in .bss, not the arena: rr_advance() runs from a bpf_timer
 * callback, where the verifier rejects atomic ops on arena memory.
 */
static u64 part_busy;
static u64 part_pending;

static bool part_try_start(void)
{
	/* set busy, report whether it was previously clear (we acquired it) */
	return !__sync_fetch_and_or(&part_busy, 1);
}

static void part_end(void)
{
	__sync_fetch_and_and(&part_busy, 0);
}

/*
 * compute_partition() scratch.
 *
 * The excl-held cids are handed out in cid order: position 0..nr_excl-1 over
 * the held cids is split into contiguous ranges, one per participant that gets
 * at least one excl cid. Range k is owned by cp_range_owner[k] and ends at the
 * cumulative position cp_range_end[k].
 */
static s32 cp_range_owner[MAX_PARTS];	/* exclusive range k: its owner id ... */
static s32 cp_range_end[MAX_PARTS];	/* ... and the cumulative position it ends at */

/* a participant in the partition: self or an attached child */
struct participant {
	s32 slot;	/* child slot, or CID_SELF */
	u32 weight;	/* cpu.weight */
};

/**
 * place_one - assign one excl-held cid to its owner
 * @cid: the excl-held cid to place
 * @n: its position among the excl-held cids, in [0, nr_excl)
 * @total_excl:	how many positions are owned exclusively (the rest are shared)
 *
 * Position @n below @total_excl is owned exclusively. It falls in the range
 * whose cumulative end it is under, owned by cp_range_owner[]. A position at or
 * above @total_excl is the rounding leftover which joins the shared pool.
 *
 * A separate __noinline function to help verification.
 */
__noinline int place_one(s32 cid, s32 n, s32 total_excl)
{
	s32 owner = CID_SELF, i, s;

	if (cid < 0 || cid >= SCX_QMAP_MAX_CPUS || n < 0 || n >= SCX_QMAP_MAX_CPUS ||
	    total_excl < 0) {
		scx_bpf_error("-ERANGE");
		return 0;
	}

	if (n < total_excl) {
		for (i = 0; i < MAX_PARTS; i++) {
			if (n < cp_range_end[i]) {
				owner = cp_range_owner[i];
				break;
			}
		}
		qa.part.cid_owner[cid] = owner;
	} else {
		s = n - total_excl;
		if (s < 0 || s >= MAX_PARTS) {
			scx_bpf_error("-ERANGE");
			return 0;
		}
		qa.part.shared_cids[s] = cid;
		/* time-shared: dispatch resolves the live holder via rr_pos */
		qa.part.cid_owner[cid] = CID_SHARED;
	}
	return 0;
}

/**
 * compute_partition - build the cid partition from this node's held caps
 *
 * Decide each cid's owner, the shared pool and the rr rotation. __noinline to
 * help verification. See the comment at the top of the file.
 */
__noinline void compute_partition(void)
{
	s32 nr_cids = qa.nr_cids;
	s32 nr_excl, total_excl = 0, nr_rr = 0;
	s32 sum_w, i, cid, n = 0, share, self_w;
	u64 cgid_snap[MAX_SUB_SCHEDS];
	s32 w_snap[MAX_SUB_SCHEDS];

	if (nr_cids > SCX_QMAP_MAX_CPUS) {
		scx_bpf_error("-ERANGE");
		return;
	}

	/* find out the cids we hold */
	scx_bpf_sub_caps(0, SCX_CAP_ENQ, &qa.held_excl.mask);
	scx_bpf_sub_caps(0, SCX_CAP_ENQ_IMMED, &qa.held_shared.mask);
	cmask_andnot(&qa.held_shared.mask, &qa.held_excl.mask);	/* held only as ENQ_IMMED */

	qa.part.nr_shared = 0;
	qa.part.nr_rr = 0;
	qa.part.rr_pos = 0;

	nr_excl = cmask_weight(&qa.held_excl.mask);
	qa.part.nr_excl = nr_excl;

	/* no excl cid: held_shared stays self-local, the rest unheld */
	if (!nr_excl) {
		bpf_for(cid, 0, nr_cids) {
			if (cmask_test(cid, &qa.held_shared.mask))
				qa.part.cid_owner[cid] = CID_SELF;
			else
				qa.part.cid_owner[cid] = CID_NONE;
		}
		return;
	}

	/*
	 * Snapshot membership and weights so the sum_w and share loops agree. A
	 * mid-compute change would otherwise wrap nr_shared negative. The self
	 * weight is fixed at the default: a cgroup's weight is its parent's
	 * knob, not the scheduler's own business.
	 */
	self_w = 100;
	bpf_for(i, 0, MAX_SUB_SCHEDS) {
		cgid_snap[i] = qa.sub_sched_ctxs[i].cgroup_id;
		w_snap[i] = cgid_snap[i] ? (qa.sub_sched_ctxs[i].weight ?: 100) : 0;
	}

	/*
	 * Participants are self plus each child. Give each a fixed range/rr
	 * slot: self at slot 0, child i at slot i+1.
	 *
	 * sum_w totals every participant's weight.
	 */
	sum_w = self_w;
	bpf_for(i, 0, MAX_SUB_SCHEDS) {
		barrier_var(sum_w);
		sum_w += w_snap[i];
	}

	/*
	 * Split [0, nr_excl) into one contiguous range per participant, each
	 * the floor of its weight share. cp_range_owner[]/cp_range_end[] record
	 * each range's owner and cumulative end, total_excl counts the
	 * exclusive slots, and the rest (nr_excl - total_excl) are shared.
	 * rr_slots[] lists every participant for the round-robin.
	 */
	share = (u64)nr_excl * self_w / sum_w;
	total_excl += share;
	cp_range_owner[0] = CID_SELF;
	cp_range_end[0] = total_excl;
	qa.part.rr_slots[nr_rr++] = 0;		/* self holds slot 0 (cgid 0 = no grant) */

	bpf_for(i, 0, MAX_SUB_SCHEDS) {
		u64 cgid = cgid_snap[i];
		s32 w = w_snap[i];

		barrier_var(total_excl);
		share = (u64)nr_excl * w / sum_w;
		total_excl += share;
		cp_range_owner[i + 1] = cgid ? i : CID_NONE;
		cp_range_end[i + 1] = total_excl;

		if (cgid) {
			barrier_var(nr_rr);
			if (nr_rr < 0 || nr_rr >= MAX_PARTS) {
				scx_bpf_error("-ERANGE");
				return;
			}
			qa.part.rr_slots[nr_rr++] = cgid;
		}
	}

	/* assign each cid: held-excl by position, the rest self/none */
	bpf_for(cid, 0, nr_cids) {
		if (cmask_test(cid, &qa.held_excl.mask)) {
			place_one(cid, n, total_excl);
			n++;
			barrier_var(n);
		} else if (cmask_test(cid, &qa.held_shared.mask)) {
			qa.part.cid_owner[cid] = CID_SELF;	/* time-share, self-local */
		} else {
			qa.part.cid_owner[cid] = CID_NONE;	/* not held */
		}
	}

	qa.part.nr_shared = nr_excl - total_excl;
	qa.part.nr_rr = nr_rr;
}

/*
 * Charge elapsed wall time to each cid's current owner. Runs under the
 * partition guard before every ownership change and from the stats flush, so
 * alloc_ns[] reflects the layout that was in effect. Shared-pool time is
 * charged to the live round-robin holder.
 */
static __noinline void account_alloc(void)
{
	u64 now = bpf_ktime_get_ns();
	s32 rr_owner = CID_SELF;
	s32 nr_cids = qa.nr_cids;
	u64 delta;
	s32 cid, i;

	if (nr_cids < 0 || nr_cids > SCX_QMAP_MAX_CPUS) {
		scx_bpf_error("-ERANGE");
		return;
	}

	/* first call starts the clock */
	if (!qa.alloc_ts) {
		qa.alloc_ts = now;
		return;
	}
	delta = now - qa.alloc_ts;
	qa.alloc_ts = now;
	qa.alloc_window_ns += delta;

	/* resolve the live shared-pool holder to an owner id */
	if (qa.part.nr_shared && qa.part.nr_rr) {
		u32 pos = qa.part.rr_pos;
		u64 cgid = pos < MAX_PARTS ? qa.part.rr_slots[pos] : 0;

		if (cgid) {
			rr_owner = CID_NONE;
			bpf_for(i, 0, MAX_SUB_SCHEDS)
				if (qa.sub_sched_ctxs[i].cgroup_id == cgid)
					rr_owner = i;
		}
	}

	bpf_for(cid, 0, nr_cids) {
		s32 owner = qa.part.cid_owner[cid];

		if (owner == CID_SHARED)
			owner = rr_owner;
		if (owner >= 0 && owner < MAX_SUB_SCHEDS)
			qa.alloc_ns[owner] += delta;
		else if (owner == CID_SELF)
			qa.self_alloc_ns += delta;
	}
}

/*
 * usable_cids = self_cids & avail_cids. The inputs have separate writers,
 * apply_partition() and qmap_sub_ecaps_updated(), so the result is rebuilt in
 * full under the partition guard, in scratch first so that readers never see
 * self_cids alone.
 */
static void refresh_usable(void)
{
	cmask_copy(&qa.usable_scratch.mask, &qa.self_cids.mask);
	cmask_and(&qa.usable_scratch.mask, &qa.avail_cids.mask);
	cmask_copy(&qa.usable_cids.mask, &qa.usable_scratch.mask);
}

/*
 * apply_partition - execute the plan compute_partition() built
 *
 * Turn the owner map into the per-child, shared and self cmasks and issue the
 * grant/revoke kfuncs as a delta against each child's previous grant. If no
 * excl cid, evict every child.
 */
__noinline void apply_partition(void)
{
	s32 nr_cids = qa.nr_cids;
	s32 nr_shared = qa.part.nr_shared;
	s32 i, cid;

	if (nr_cids < 0 || nr_cids > SCX_QMAP_MAX_CPUS ||
	    nr_shared < 0 || nr_shared > MAX_PARTS) {
		scx_bpf_error("-ERANGE");
		return;
	}

	/* no excl cpu: run own tasks on the held shares, evict children */
	if (!qa.part.nr_excl) {
		cmask_copy(&qa.self_cids.mask, &qa.held_shared.mask);
		refresh_usable();
		bpf_for(i, 0, MAX_SUB_SCHEDS)
			if (qa.sub_sched_ctxs[i].cgroup_id)
				scx_bpf_sub_kill(qa.sub_sched_ctxs[i].cgroup_id,
						 "parent holds no excl cpu to distribute");
		return;
	}

	/*
	 * Snapshot the old pool. The per-child revoke below clears ENQ_IMMED on
	 * the previously-granted pool, so a cid that left the pool (now a
	 * sibling's excl) doesn't keep a stale ENQ_IMMED on its last holder.
	 */
	cmask_copy(&qa.prev_rr_cids.mask, &qa.rr_cids.mask);

	/* turn the owner map into the rr pool, per-child excl, and self sets */
	cmask_init(&qa.rr_cids.mask, 0, nr_cids);
	cmask_init(&qa.self_cids.mask, 0, nr_cids);

	/* snapshot each child's grant, then rebuild the new sets below */
	bpf_for(i, 0, MAX_SUB_SCHEDS) {
		cmask_copy(&qa.sub_sched_ctxs[i].prev_granted.mask,
			   &qa.sub_sched_ctxs[i].granted_cids.mask);
		cmask_init(&qa.sub_sched_ctxs[i].granted_cids.mask, 0, nr_cids);
	}

	bpf_for(i, 0, nr_shared)
		cmask_set(qa.part.shared_cids[i], &qa.rr_cids.mask);
	bpf_for(cid, 0, nr_cids) {
		s32 o = qa.part.cid_owner[cid];

		if (cmask_test(cid, &qa.rr_cids.mask))
			continue;
		if (o >= 0 && o < MAX_SUB_SCHEDS)
			cmask_set(cid, &qa.sub_sched_ctxs[o].granted_cids.mask);
		else if (o == CID_SELF)
			cmask_set(cid, &qa.self_cids.mask);
	}
	refresh_usable();

	/*
	 * Apply each child's exclusive cids as a delta against its previous
	 * grant. Separately clear the previous shared grant (ENQ_IMMED on the
	 * old pool), covering cids still pooled and cids that left for a
	 * sibling's excl. The current holder is granted the new pool below.
	 */
	bpf_for(i, 0, MAX_SUB_SCHEDS) {
		struct sub_sched_ctx __arena *ssc = &qa.sub_sched_ctxs[i];
		u64 cgid = ssc->cgroup_id;

		if (!cgid)
			continue;

		cmask_copy(&qa.to_revoke_cids.mask, &ssc->prev_granted.mask);
		cmask_andnot(&qa.to_revoke_cids.mask, &ssc->granted_cids.mask);
		cmask_copy(&qa.to_grant_cids.mask, &ssc->granted_cids.mask);
		cmask_andnot(&qa.to_grant_cids.mask, &ssc->prev_granted.mask);

		scx_bpf_sub_revoke(cgid, SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
				   &qa.prev_rr_cids.mask);
		scx_bpf_sub_revoke(cgid, SCX_CAP_ENQ | SCX_CAP_PREEMPT |
				   SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
				   &qa.to_revoke_cids.mask);
		scx_bpf_sub_grant(cgid, SCX_CAP_ENQ | SCX_CAP_PREEMPT |
				  SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
				  &qa.to_grant_cids.mask, NULL);
	}

	/* the current holder of the shared pool gets ENQ_IMMED on all of it */
	if (nr_shared) {
		s32 pos = qa.part.rr_pos;
		u64 holder_cgid;

		if (pos < 0 || pos >= MAX_PARTS) {
			scx_bpf_error("-ERANGE");
			return;
		}

		holder_cgid = qa.part.rr_slots[pos];	/* 0 = self, nothing to grant */
		if (holder_cgid)
			scx_bpf_sub_grant(holder_cgid,
					  SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
					  &qa.rr_cids.mask, NULL);
	}
}

/**
 * execute_partition - Run pending partition updates
 *
 * The rr timer is the backstop if the loop reaches its iteration limit.
 */
static void execute_partition(void)
{
	u64 pending;
	s32 i;

	bpf_for(i, 0, 1024) {
		if (!part_try_start())
			break;

		pending = __sync_fetch_and_and(&part_pending, 0);
		if (pending & PART_REDISTRIBUTE) {
			/* charge elapsed time before repartitioning */
			account_alloc();
			compute_partition();
			apply_partition();
		} else if (pending & PART_REFRESH) {
			refresh_usable();
		}

		/*
		 * Requests are published before trying the guard. Releasing it
		 * before checking pending work ensures a racing request is
		 * either observed here or handled by a caller that acquires the
		 * guard.
		 */
		part_end();
		if (!__sync_fetch_and_or(&part_pending, 0))
			break;
	}
}

static void redistribute(void)
{
	__sync_fetch_and_or(&part_pending, PART_REDISTRIBUTE);
	execute_partition();
}

/*
 * Userspace pokes this (PROG_RUN) to bring alloc_ns[] current before reading
 * it for the stats display. Skipping when the partition guard is held is
 * fine - alloc_ts is untouched, so the elapsed time is charged next time.
 */
SEC("syscall")
int flush_alloc(void *ctx)
{
	if (part_try_start()) {
		account_alloc();
		part_end();
		execute_partition();
	}
	return 0;
}

/*
 * Hand the shared pool to the next participant in the rotation. Self's turn
 * just revokes the pool back to this sched. A child's turn grants it ENQ_IMMED
 * on the entire pool. As only excl-held cids are time-shared, a wall-clock
 * rotation works. Driven by the round-robin timer.
 */
static void rr_advance(void)
{
	s32 nr_shared, old_pos, new_pos;
	u64 old_cgid, new_cgid;
	u32 nr_rr;		/* unsigned for % */

	/* a redistribute holds the partition and rebuilds the pool, so skip */
	if (!part_try_start())
		return;

	nr_rr = qa.part.nr_rr;
	nr_shared = qa.part.nr_shared;

	if (nr_shared < 0 || nr_shared > MAX_PARTS) {
		scx_bpf_error("-ERANGE");
		return;
	}

	if (nr_shared && nr_rr >= 2) {
		/* close out the outgoing holder's pool time */
		account_alloc();

		old_pos = qa.part.rr_pos;
		new_pos = (old_pos + 1) % nr_rr;
		old_cgid = qa.part.rr_slots[old_pos];
		new_cgid = qa.part.rr_slots[new_pos];
		qa.part.rr_pos = new_pos;

		/*
		 * Move the ENQ_IMMED cap to the next participant. The shared
		 * cids stay marked CID_SHARED. qmap_dispatch() resolves the
		 * live holder via rr_pos without the guard, so a dispatch
		 * racing this handoff may reenqueue a task once. Harmless for a
		 * time-share.
		 */
		if (old_cgid)
			scx_bpf_sub_revoke(old_cgid,
					   SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
					   &qa.rr_cids.mask);
		if (new_cgid)
			scx_bpf_sub_grant(new_cgid,
					  SCX_CAP_ENQ_IMMED | SCX_CAP_PERF,
					  &qa.rr_cids.mask, NULL);
	}

	part_end();

	execute_partition();
}

/* advance the time-shared cid pool every round_robin_ns */
static int round_robin_timerfn(void *map, int *key, struct bpf_timer *timer)
{
	rr_advance();
	if (bpf_timer_start(timer, round_robin_ns, 0))
		scx_bpf_error("failed to re-arm round-robin timer");
	return 0;
}

/*
 * Custom cid layout for the cid-override test. On invalid input the kfunc
 * scx_error()s and aborts the scheduler.
 */
s32 BPF_STRUCT_OPS_SLEEPABLE(qmap_init_cids)
{
	u32 nr_cpu_ids = scx_bpf_nr_cpu_ids();

	if (!cid_override_mode)
		return 0;

	/* the arena arrays are sized SCX_QMAP_MAX_CPUS */
	if (nr_cpu_ids > SCX_QMAP_MAX_CPUS) {
		scx_bpf_error("nr_cpu_ids=%u exceeds SCX_QMAP_MAX_CPUS=%d",
			      nr_cpu_ids, SCX_QMAP_MAX_CPUS);
		return -EINVAL;
	}

	scx_bpf_cid_override(qa.cid_override_cpu_to_cid, nr_cpu_ids,
			     qa.cid_override_shard_start, cid_override_nr_shards);
	return 0;
}

s32 BPF_STRUCT_OPS_SLEEPABLE(qmap_init)
{
	u8 __arena *slab;
	u32 nr_pages, key = 0, i;
	u32 nr_cids, nr_cpu_ids;
	struct bpf_timer *timer;
	s32 ret;

	nr_cids = scx_bpf_nr_cids();
	nr_cpu_ids = scx_bpf_nr_cpu_ids();

	if (nr_cids > SCX_QMAP_MAX_CPUS) {
		scx_bpf_error("nr_cids=%u exceeds SCX_QMAP_MAX_CPUS=%d",
			      nr_cids, SCX_QMAP_MAX_CPUS);
		return -EINVAL;
	}
	if (nr_cpu_ids > SCX_QMAP_MAX_CPUS) {
		scx_bpf_error("nr_cpu_ids=%u exceeds SCX_QMAP_MAX_CPUS=%d",
			      nr_cpu_ids, SCX_QMAP_MAX_CPUS);
		return -EINVAL;
	}

	/*
	 * Allocate the task_ctx slab in arena and thread the entire slab onto
	 * the free list. max_tasks is set by userspace before load. Each entry
	 * is TASK_CTX_STRIDE bytes - task_ctx's trailing cpus_allowed flex
	 * array extends into the stride tail.
	 */
	if (!max_tasks) {
		scx_bpf_error("max_tasks must be > 0");
		return -EINVAL;
	}

	nr_pages = (max_tasks * TASK_CTX_STRIDE + PAGE_SIZE - 1) / PAGE_SIZE;
	slab = bpf_arena_alloc_pages(&arena, NULL, nr_pages, NUMA_NO_NODE, 0);
	if (!slab) {
		scx_bpf_error("failed to allocate task_ctx slab");
		return -ENOMEM;
	}
	qa.task_ctxs = (task_ctx_t *)slab;

	bpf_for(i, 0, 5)
		qa.fifos[i].idx = i;

	bpf_for(i, 0, max_tasks) {
		task_ctx_t *cur = (task_ctx_t *)(slab + i * TASK_CTX_STRIDE);
		task_ctx_t *next = (i + 1 < max_tasks) ?
			(task_ctx_t *)(slab + (i + 1) * TASK_CTX_STRIDE) : NULL;
		cur->next_free = next;
	}
	qa.task_free_head = (task_ctx_t *)slab;

	/* cache the cid count, trusted to be <= SCX_QMAP_MAX_CPUS hereafter */
	qa.nr_cids = nr_cids;

	/* cmasks are embedded in qa, so they only need initializing */
	cmask_init(&qa.idle_cids.mask, 0, nr_cids);
	cmask_init(&qa.rr_cids.mask, 0, nr_cids);
	cmask_init(&qa.prev_rr_cids.mask, 0, nr_cids);
	cmask_init(&qa.self_cids.mask, 0, nr_cids);
	cmask_init(&qa.avail_cids.mask, 0, nr_cids);
	cmask_init(&qa.usable_cids.mask, 0, nr_cids);
	cmask_init(&qa.to_revoke_cids.mask, 0, nr_cids);
	cmask_init(&qa.to_grant_cids.mask, 0, nr_cids);
	cmask_init(&qa.usable_scratch.mask, 0, nr_cids);
	cmask_init(&qa.held_excl.mask, 0, nr_cids);
	cmask_init(&qa.held_shared.mask, 0, nr_cids);

	scx_bpf_sub_caps(0, SCX_CAP_ENQ, &qa.held_excl.mask);
	scx_bpf_sub_caps(0, SCX_CAP_ENQ_IMMED, &qa.held_shared.mask);
	cmask_andnot(&qa.held_shared.mask, &qa.held_excl.mask);

	bpf_for(i, 0, MAX_SUB_SCHEDS) {
		cmask_init(&qa.sub_sched_ctxs[i].granted_cids.mask, 0, nr_cids);
		cmask_init(&qa.sub_sched_ctxs[i].prev_granted.mask, 0, nr_cids);
	}

	/*
	 * The root starts holding every cid and gets no ecaps notifications, so
	 * its avail set is fixed here. qmap_sub_ecaps_updated() maintains the
	 * per-cid state as effective caps settle, and redistribute() rebuilds
	 * owner and self from held caps. A non-root node starts with nothing.
	 */
	bpf_for(i, 0, nr_cids) {
		if (!sub_cgroup_id) {
			cmask_set(i, &qa.self_cids.mask);
			cmask_set(i, &qa.avail_cids.mask);
			cmask_set(i, &qa.usable_cids.mask);
			qa.part.cid_owner[i] = CID_SELF;
		} else {
			qa.part.cid_owner[i] = CID_NONE;
		}
	}
	qa.part.nr_shared = 0;

	ret = scx_bpf_create_dsq(SHARED_DSQ, -1);
	if (ret) {
		scx_bpf_error("failed to create DSQ %d (%d)", SHARED_DSQ, ret);
		return ret;
	}

	ret = scx_bpf_create_dsq(HIGHPRI_DSQ, -1);
	if (ret) {
		scx_bpf_error("failed to create DSQ %d (%d)", HIGHPRI_DSQ, ret);
		return ret;
	}

	ret = scx_bpf_create_dsq(LOWPRI_DSQ, -1);
	if (ret)
		return ret;

	timer = bpf_map_lookup_elem(&monitor_timer, &key);
	if (!timer)
		return -ESRCH;
	bpf_timer_init(timer, &monitor_timer, CLOCK_MONOTONIC);
	bpf_timer_set_callback(timer, monitor_timerfn);
	ret = bpf_timer_start(timer, ONE_SEC_IN_NS, 0);
	if (ret)
		return ret;

	if (__COMPAT_has_generic_reenq()) {
		/* see lowpri_timerfn() */
		timer = bpf_map_lookup_elem(&lowpri_timer, &key);
		if (!timer)
			return -ESRCH;
		bpf_timer_init(timer, &lowpri_timer, CLOCK_MONOTONIC);
		bpf_timer_set_callback(timer, lowpri_timerfn);
		ret = bpf_timer_start(timer, LOWPRI_INTV_NS, 0);
		if (ret)
			return ret;
	}

	/* sub-sched: drive the boundary-cid round-robin from a bpf timer */
	timer = bpf_map_lookup_elem(&round_robin_timer, &key);
	if (!timer)
		return -ESRCH;
	bpf_timer_init(timer, &round_robin_timer, CLOCK_MONOTONIC);
	bpf_timer_set_callback(timer, round_robin_timerfn);
	ret = bpf_timer_start(timer, round_robin_ns, 0);
	if (ret)
		return ret;

	return 0;
}

void BPF_STRUCT_OPS(qmap_exit, struct scx_exit_info *ei)
{
	UEI_RECORD(uei, ei);
}

/*
 * Seed a new sub slot with the cgroup's current weight. The kernel delivers
 * ops.cpuctl_set_weight() only on value-changing writes, so a weight set
 * before the sub attached would otherwise go unnoticed.
 */
static u32 cgrp_cur_weight(u64 cgid)
{
	struct cgroup_subsys_state *css;
	struct cgroup *cgrp;
	u32 weight = 100;

	cgrp = bpf_cgroup_from_id(cgid);
	if (!cgrp)
		return weight;

	css = BPF_CORE_READ(cgrp, subsys[cpu_cgrp_id]);
	if (css) {
		struct task_group *tg = container_of(css, struct task_group, css);
		u32 w = BPF_CORE_READ(tg, scx.weight);

		if (w)
			weight = w;
	}
	bpf_cgroup_release(cgrp);
	return weight;
}

s32 BPF_STRUCT_OPS(qmap_sub_attach, struct scx_sub_attach_args *args)
{
	s32 i;

	/* as long as there is at least one excl cpu, children can attach */
	if (!cmask_weight(&qa.held_excl.mask))
		return -ENOSPC;

	for (i = 0; i < MAX_SUB_SCHEDS; i++) {
		if (qa.sub_sched_ctxs[i].cgroup_id)
			continue;

		qa.sub_sched_ctxs[i].cgroup_id = args->ops->sub_cgroup_id;
		qa.sub_sched_ctxs[i].weight = cgrp_cur_weight(args->ops->sub_cgroup_id);
		qa.nr_sub_scheds++;
		bpf_printk("attaching sub-sched[%d] on %s", i, args->cgroup_path);
		redistribute();
		return 0;
	}

	return -ENOSPC;
}

void BPF_STRUCT_OPS(qmap_sub_detach, struct scx_sub_detach_args *args)
{
	s32 i;

	for (i = 0; i < MAX_SUB_SCHEDS; i++) {
		if (qa.sub_sched_ctxs[i].cgroup_id != args->ops->sub_cgroup_id)
			continue;

		qa.sub_sched_ctxs[i].cgroup_id = 0;
		qa.sub_sched_ctxs[i].weight = 100;
		cmask_init(&qa.sub_sched_ctxs[i].granted_cids.mask, 0, qa.nr_cids);
		qa.nr_sub_scheds--;
		bpf_printk("detaching sub-sched[%d] on %s", i, args->cgroup_path);
		redistribute();
		break;
	}
}

void BPF_STRUCT_OPS(qmap_sub_caps_updated, const struct scx_cmask *cmask, u64 caps)
{
	/* our held caps changed, redistribute */
	redistribute();
}

void BPF_STRUCT_OPS(qmap_sub_ecaps_updated, s32 cid, u64 before, u64 after)
{
	/*
	 * Effective caps updated. Track which cids hold shared caps so a self
	 * task placed there enqueues IMMED, and which cids have ENQ_IMMED in
	 * effect at all (avail, see the header comment).
	 */
	if (after & SCX_CAP_ENQ_IMMED) {
		qa.cid_shared[cid] = (after & SCX_CAP_ENQ) ? 0 : 1;
		cmask_set(cid, &qa.avail_cids.mask);
	} else {
		qa.cid_shared[cid] = 0;
		cmask_clear(cid, &qa.avail_cids.mask);
	}

	__sync_fetch_and_or(&part_pending, PART_REFRESH);
	execute_partition();
}

SCX_OPS_CID_DEFINE(qmap_ops,
	       .flags			= SCX_OPS_ENQ_EXITING | SCX_OPS_TID_TO_TASK,
	       .select_cid		= (void *)qmap_select_cid,
	       .enqueue			= (void *)qmap_enqueue,
	       .dequeue			= (void *)qmap_dequeue,
	       .dispatch		= (void *)qmap_dispatch,
	       .tick			= (void *)qmap_tick,
	       .core_sched_before	= (void *)qmap_core_sched_before,
	       .set_cmask		= (void *)qmap_set_cmask,
	       .update_idle		= (void *)qmap_update_idle,
	       .init_task		= (void *)qmap_init_task,
	       .exit_task		= (void *)qmap_exit_task,
	       .dump			= (void *)qmap_dump,
	       .dump_cid		= (void *)qmap_dump_cid,
	       .dump_task		= (void *)qmap_dump_task,
	       .cpuctl_init		= (void *)qmap_cpuctl_init,
	       .cpuctl_set_weight	= (void *)qmap_cpuctl_set_weight,
	       .cpuctl_set_bandwidth	= (void *)qmap_cpuctl_set_bandwidth,
	       .cpuctl_move		= (void *)qmap_cpuctl_move,
	       .sub_attach		= (void *)qmap_sub_attach,
	       .sub_detach		= (void *)qmap_sub_detach,
	       .sub_caps_updated	= (void *)qmap_sub_caps_updated,
	       .sub_ecaps_updated	= (void *)qmap_sub_ecaps_updated,
	       .init_cids		= (void *)qmap_init_cids,
	       .init			= (void *)qmap_init,
	       .exit			= (void *)qmap_exit,
	       .timeout_ms		= 5000U,
	       .name			= "qmap");
