/* SPDX-License-Identifier: GPL-2.0 */ /* * A simple scheduler. * * By default, it operates as a simple global weighted vtime scheduler and can * be switched to FIFO scheduling. It also demonstrates the following niceties. * * - Statistics tracking how many tasks are queued to local and global dsq's. * - Termination notification for userspace. * * While very simple, this scheduler should work reasonably well on CPUs with a * uniform L3 cache topology. While preemption is not implemented, the fact that * the scheduling queue is shared across all CPUs means that whatever is at the * front of the queue is likely to be executed fairly quickly given enough * number of CPUs. The FIFO scheduling mode may be beneficial to some workloads * but comes with the usual problems with FIFO scheduling where saturating * threads can easily drown out interactive ones. * * 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>
char _license[] SEC("license") = "GPL";
constvolatilebool fifo_sched;
static u64 vtime_now;
UEI_DEFINE(uei);
/* * Built-in DSQs such as SCX_DSQ_GLOBAL cannot be used as priority queues * (meaning, cannot be dispatched to with scx_bpf_dsq_insert_vtime()). We * therefore create a separate DSQ with ID 0 that we dispatch to and consume * from. If scx_simple only supported global FIFO scheduling, then we could just * use SCX_DSQ_GLOBAL.
*/ #define SHARED_DSQ 0
/* * Limit the amount of budget that an idling task can accumulate * to one slice.
*/ if (time_before(vtime, vtime_now - SCX_SLICE_DFL))
vtime = vtime_now - SCX_SLICE_DFL;
void BPF_STRUCT_OPS(simple_running, struct task_struct *p)
{ if (fifo_sched) return;
/* * Global vtime always progresses forward as tasks start executing. The * test and update can be performed concurrently from multiple CPUs and * thus racy. Any error should be contained and temporary. Let's just * live with it.
*/ if (time_before(vtime_now, p->scx.dsq_vtime))
vtime_now = p->scx.dsq_vtime;
}
/* * Scale the execution time by the inverse of the weight and charge. * * Note that the default yield implementation yields by setting * @p->scx.slice to zero and the following would treat the yielding task * as if it has consumed all its slice. If this penalizes yielding tasks * too much, determine the execution time by taking explicit timestamps * instead of depending on @p->scx.slice.
*/
p->scx.dsq_vtime += (SCX_SLICE_DFL - p->scx.slice) * 100 / p->scx.weight;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.