Scheduler(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸŽ€ Scheduler πŸŽ€

okay so this is Scheduler(9) from the Kernel API Manual, and bestie, we're about to get into the Mali CSF scheduling lore. ✨ No cap, it's actually kind of iconic.

Mali CSF hardware adopts a firmware-assisted scheduling model, where the firmware takes care of scheduling aspects β€” to some extent. Like, it's not doing everything, but it's definitely in the mix. πŸ’…

The scheduling happens at the scheduling group level, and each group contains 1 to N queues (N is FW/hardware dependent, and exposed through the firmware interface). Each queue is assigned a command stream ring buffer, which serves as a way to get jobs submitted to the GPU, among other things. πŸŒ€

The firmware can schedule a maximum of M groups (M is FW/hardware dependent, and exposed through the firmware interface). Passed this maximum number of groups, the kernel has to take care of rotating the groups passed to the firmware so every group gets a chance to have its queues scheduled for execution. πŸ”

The current implementation only supports with kernel-mode queues. In other terms, userspace doesn't have access to the ring-buffer. Instead, userspace passes indirect command stream buffers that are called from the queue ring-buffer by the kernel using a pre-defined sequence of command stream instructions to ensure the userspace driver always gets consistent results (cache maintenance, synchronization, ...). πŸ”’

We rely on the drm_gpu_scheduler framework to deal with job dependencies and submission. As any other driver dealing with a FW-scheduler, we use the 1:1 entity:scheduler mode, such that each entity has its own job scheduler. When a job is ready to be executed (all its dependencies are met), it is pushed to the appropriate queue ring-buffer, and the group is scheduled for execution if it wasn't already active. πŸš€

Kernel-side group scheduling is timeslice-based. When we have less groups than there are slots, the periodic tick is disabled and we just let the FW schedule the active groups. When there are more groups than slots, we let each group have a chance to execute stuff for a given amount of time, and then re-evaluate and pick new groups to schedule. The group selection algorithm is based on priority+round-robin. ⏱️

Even though user-mode queues is out of the scope right now, the current design takes them into account by avoiding any guess on the group/queue state that would be based on information we wouldn't have if userspace was in charge of the ring-buffer. That's also one of the reason we don't do 'cooperative' scheduling (encoding FW group slot reservation as dma_fence that would be returned from the drm_gpu_scheduler::prepare_job hook, and treating group rotation as a queue of waiters, ordered by job submission order). This approach would work for kernel-mode queues, but would make user-mode queues a lot more complicated to retrofit. πŸ™…β™€οΈ


🌈 SEE ALSO 🌈

Kernel file: ./drivers/gpu/drm/panthor/panthor_sched.c

periodt. this page is from ./drivers/gpu/drm/panthor, dated October 2026, and it's literally Scheduler(9) πŸ’…βœ¨

πŸ“¦ where this page comes from