On Tue, Nov 29, 2022 at 10:22:56PM -1000, Tejun Heo wrote: > + /** > + * dispatch - Dispatch tasks from the BPF scheduler into dsq's > + * @cpu: CPU to dispatch tasks for > + * @prev: previous task being switched out > + * > + * Called when a CPU can't find a task to execute after ops.consume(). > + * The operation should dispatch one or more tasks from the BPF > + * scheduler to the dsq's using scx_bpf_dispatch(). The maximum number > + * of tasks which can be dispatched in a single call is specified by the > + * @dispatch_max_batch field of this struct. > + */ > + void (*dispatch)(s32 cpu, struct task_struct *prev); > + > + /** > + * consume - Consume tasks from the dsq's to the local dsq for execution > + * @cpu: CPU to consume tasks for > + * > + * Called when a CPU's local dsq is empty. The operation should transfer > + * one or more tasks from the dsq's to the CPU's local dsq using > + * scx_bpf_consume(). If this function fails to fill the local dsq, > + * ops.dispatch() will be called. > + * > + * This operation is unnecessary if the BPF scheduler always dispatches > + * either to one of the local dsq's or the global dsq. If implemented, > + * this operation is also responsible for consuming the global_dsq. > + */ > + void (*consume)(s32 cpu); > + > + /** > + * consume_final - Final consume call before going idle > + * @cpu: CPU to consume tasks for > + * > + * After ops.consume() and .dispatch(), @cpu still doesn't have a task > + * to execute and is about to go idle. This operation can be used to > + * implement more aggressive consumption strategies. Otherwise > + * equivalent to ops.consume(). > + */ > + void (*consume_final)(s32 cpu); Doesn't really change the big picture but I ended up merging ops.consume[_final]() into ops.dispatch() which should make the dispatch path both simpler and more flexible. Thanks. -- tejun