sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget,/translations/zh_CN/scheduler/sched-capacitymodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/zh_TW/scheduler/sched-capacitymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/it_IT/scheduler/sched-capacitymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/ja_JP/scheduler/sched-capacitymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/ko_KR/scheduler/sched-capacitymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget,/translations/sp_SP/scheduler/sched-capacitymodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhsection)}(hhh](htitle)}(hCapacity Aware Schedulingh]hCapacity Aware Scheduling}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhF/var/lib/git/docbuild/linux/Documentation/scheduler/sched-capacity.rsthKubh)}(hhh](h)}(h1. CPU Capacityh]h1. CPU Capacity}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h1.1 Introductionh]h1.1 Introduction}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhK ubh paragraph)}(hConventional, homogeneous SMP platforms are composed of purely identical CPUs. Heterogeneous platforms on the other hand are composed of CPUs with different performance characteristics - on such platforms, not all CPUs can be considered equal.h]hConventional, homogeneous SMP platforms are composed of purely identical CPUs. Heterogeneous platforms on the other hand are composed of CPUs with different performance characteristics - on such platforms, not all CPUs can be considered equal.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hCPU capacity is a measure of the performance a CPU can reach, normalized against the most performant CPU in the system. Heterogeneous systems are also called asymmetric CPU capacity systems, as they contain CPUs of different capacities.h]hCPU capacity is a measure of the performance a CPU can reach, normalized against the most performant CPU in the system. Heterogeneous systems are also called asymmetric CPU capacity systems, as they contain CPUs of different capacities.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(haDisparity in maximum attainable performance (IOW in maximum CPU capacity) stems from two factors:h]haDisparity in maximum attainable performance (IOW in maximum CPU capacity) stems from two factors:}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh bullet_list)}(hhh](h list_item)}(h:not all CPUs may have the same microarchitecture (µarch).h]h)}(hjh]h:not all CPUs may have the same microarchitecture (µarch).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1j hjhhhhhNubj )}(hwith Dynamic Voltage and Frequency Scaling (DVFS), not all CPUs may be physically able to attain the higher Operating Performance Points (OPP). h]h)}(hwith Dynamic Voltage and Frequency Scaling (DVFS), not all CPUs may be physically able to attain the higher Operating Performance Points (OPP).h]hwith Dynamic Voltage and Frequency Scaling (DVFS), not all CPUs may be physically able to attain the higher Operating Performance Points (OPP).}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj#ubah}(h]h ]h"]h$]h&]uh1j hjhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhKhhhhubh)}(hArm big.LITTLE systems are an example of both. The big CPUs are more performance-oriented than the LITTLE ones (more pipeline stages, bigger caches, smarter predictors, etc), and can usually reach higher OPPs than the LITTLE ones can.h]hArm big.LITTLE systems are an example of both. The big CPUs are more performance-oriented than the LITTLE ones (more pipeline stages, bigger caches, smarter predictors, etc), and can usually reach higher OPPs than the LITTLE ones can.}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hCPU performance is usually expressed in Millions of Instructions Per Second (MIPS), which can also be expressed as a given amount of instructions attainable per Hz, leading to::h]hCPU performance is usually expressed in Millions of Instructions Per Second (MIPS), which can also be expressed as a given amount of instructions attainable per Hz, leading to:}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh literal_block)}(h0capacity(cpu) = work_per_hz(cpu) * max_freq(cpu)h]h0capacity(cpu) = work_per_hz(cpu) * max_freq(cpu)}hjasbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1j_hhhK$hhhhubeh}(h] introductionah ]h"]1.1 introductionah$]h&]uh1hhhhhhhhK ubh)}(hhh](h)}(h1.2 Scheduler termsh]h1.2 Scheduler terms}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjyhhhhhK'ubh)}(hXTwo different capacity values are used within the scheduler. A CPU's ``original capacity`` is its maximum attainable capacity, i.e. its maximum attainable performance level. This original capacity is returned by the function arch_scale_cpu_capacity(). A CPU's ``capacity`` is its ``original capacity`` to which some loss of available performance (e.g. time spent handling IRQs) is subtracted.h](hGTwo different capacity values are used within the scheduler. A CPU’s }(hjhhhNhNubhliteral)}(h``original capacity``h]horiginal capacity}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh is its maximum attainable capacity, i.e. its maximum attainable performance level. This original capacity is returned by the function arch_scale_cpu_capacity(). A CPU’s }(hjhhhNhNubj)}(h ``capacity``h]hcapacity}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh is its }(hjhhhNhNubj)}(h``original capacity``h]horiginal capacity}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh[ to which some loss of available performance (e.g. time spent handling IRQs) is subtracted.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK)hjyhhubh)}(hNote that a CPU's ``capacity`` is solely intended to be used by the CFS class, while ``original capacity`` is class-agnostic. The rest of this document will use the term ``capacity`` interchangeably with ``original capacity`` for the sake of brevity.h](hNote that a CPU’s }(hjhhhNhNubj)}(h ``capacity``h]hcapacity}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh7 is solely intended to be used by the CFS class, while }(hjhhhNhNubj)}(h``original capacity``h]horiginal capacity}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh@ is class-agnostic. The rest of this document will use the term }(hjhhhNhNubj)}(h ``capacity``h]hcapacity}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh interchangeably with }(hjhhhNhNubj)}(h``original capacity``h]horiginal capacity}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh for the sake of brevity.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK0hjyhhubeh}(h]scheduler-termsah ]h"]1.2 scheduler termsah$]h&]uh1hhhhhhhhK'ubh)}(hhh](h)}(h1.3 Platform examplesh]h1.3 Platform examples}(hj1hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj.hhhhhK6ubh)}(hhh](h)}(h1.3.1 Identical OPPsh]h1.3.1 Identical OPPs}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj?hhhhhK9ubh)}(hGConsider an hypothetical dual-core asymmetric CPU capacity system whereh]hGConsider an hypothetical dual-core asymmetric CPU capacity system where}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK;hj?hhubj)}(hhh](j )}(hwork_per_hz(CPU0) = Wh]h)}(hjch]hwork_per_hz(CPU0) = W}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK=hjaubah}(h]h ]h"]h$]h&]uh1j hj^hhhhhNubj )}(hwork_per_hz(CPU1) = W/2h]h)}(hjzh]hwork_per_hz(CPU1) = W/2}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK>hjxubah}(h]h ]h"]h$]h&]uh1j hj^hhhhhNubj )}(h1all CPUs are running at the same fixed frequency h]h)}(h0all CPUs are running at the same fixed frequencyh]h0all CPUs are running at the same fixed frequency}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK?hjubah}(h]h ]h"]h$]h&]uh1j hj^hhhhhNubeh}(h]h ]h"]h$]h&]jAjBuh1jhhhK=hj?hhubh)}(h$By the above definition of capacity:h]h$By the above definition of capacity:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKAhj?hhubj)}(hhh](j )}(hcapacity(CPU0) = Ch]h)}(hjh]hcapacity(CPU0) = C}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKChjubah}(h]h ]h"]h$]h&]uh1j hjhhhhhNubj )}(hcapacity(CPU1) = C/2 h]h)}(hcapacity(CPU1) = C/2h]hcapacity(CPU1) = C/2}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKDhjubah}(h]h ]h"]h$]h&]uh1j hjhhhhhNubeh}(h]h ]h"]h$]h&]jAjBuh1jhhhKChj?hhubh)}(h[To draw the parallel with Arm big.LITTLE, CPU0 would be a big while CPU1 would be a LITTLE.h]h[To draw the parallel with Arm big.LITTLE, CPU0 would be a big while CPU1 would be a LITTLE.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKFhj?hhubh)}(hhWith a workload that periodically does a fixed amount of work, you will get an execution trace like so::h]hgWith a workload that periodically does a fixed amount of work, you will get an execution trace like so:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKIhj?hhubj`)}(hXCPU0 work ^ | ____ ____ ____ | | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time CPU1 work ^ | _________ _________ ____ | | | | | | +----+----+----+----+----+----+----+----+----+----+-> timeh]hXCPU0 work ^ | ____ ____ ____ | | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time CPU1 work ^ | _________ _________ ____ | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time}hjsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKLhj?hhubh)}(hCPU0 has the highest capacity in the system (C), and completes a fixed amount of work W in T units of time. On the other hand, CPU1 has half the capacity of CPU0, and thus only completes W/2 in T.h]hCPU0 has the highest capacity in the system (C), and completes a fixed amount of work W in T units of time. On the other hand, CPU1 has half the capacity of CPU0, and thus only completes W/2 in T.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKVhj?hhubeh}(h]identical-oppsah ]h"]1.3.1 identical oppsah$]h&]uh1hhj.hhhhhK9ubh)}(hhh](h)}(h1.3.2 Different max OPPsh]h1.3.2 Different max OPPs}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj3hhhhhK[ubh)}(hUsually, CPUs of different capacity values also have different maximum OPPs. Consider the same CPUs as above (i.e. same work_per_hz()) with:h]hUsually, CPUs of different capacity values also have different maximum OPPs. Consider the same CPUs as above (i.e. same work_per_hz()) with:}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK]hj3hhubj)}(hhh](j )}(hmax_freq(CPU0) = Fh]h)}(hjWh]hmax_freq(CPU0) = F}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK`hjUubah}(h]h ]h"]h$]h&]uh1j hjRhhhhhNubj )}(hmax_freq(CPU1) = 2/3 * F h]h)}(hmax_freq(CPU1) = 2/3 * Fh]hmax_freq(CPU1) = 2/3 * F}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKahjlubah}(h]h ]h"]h$]h&]uh1j hjRhhhhhNubeh}(h]h ]h"]h$]h&]jAjBuh1jhhhK`hj3hhubh)}(h This yields:h]h This yields:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKchj3hhubj)}(hhh](j )}(hcapacity(CPU0) = Ch]h)}(hjh]hcapacity(CPU0) = C}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKehjubah}(h]h ]h"]h$]h&]uh1j hjhhhhhNubj )}(hcapacity(CPU1) = C/3 h]h)}(hcapacity(CPU1) = C/3h]hcapacity(CPU1) = C/3}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjubah}(h]h ]h"]h$]h&]uh1j hjhhhhhNubeh}(h]h ]h"]h$]h&]jAjBuh1jhhhKehj3hhubh)}(hoExecuting the same workload as described in 1.3.1, which each CPU running at its maximum frequency results in::h]hnExecuting the same workload as described in 1.3.1, which each CPU running at its maximum frequency results in:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhj3hhubj`)}(hXCPU0 work ^ | ____ ____ ____ | | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time workload on CPU1 CPU1 work ^ | ______________ ______________ ____ | | | | | | +----+----+----+----+----+----+----+----+----+----+-> timeh]hXCPU0 work ^ | ____ ____ ____ | | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time workload on CPU1 CPU1 work ^ | ______________ ______________ ____ | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time}hjsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKkhj3hhubeh}(h]different-max-oppsah ]h"]1.3.2 different max oppsah$]h&]uh1hhj.hhhhhK[ubeh}(h]platform-examplesah ]h"]1.3 platform examplesah$]h&]uh1hhhhhhhhK6ubh)}(hhh](h)}(h1.4 Representation caveath]h1.4 Representation caveat}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKwubh)}(hXjIt should be noted that having a *single* value to represent differences in CPU performance is somewhat of a contentious point. The relative performance difference between two different µarchs could be X% on integer operations, Y% on floating point operations, Z% on branches, and so on. Still, results using this simple approach have been satisfactory for now.h](h!It should be noted that having a }(hj hhhNhNubhemphasis)}(h*single*h]hsingle}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhXA value to represent differences in CPU performance is somewhat of a contentious point. The relative performance difference between two different µarchs could be X% on integer operations, Y% on floating point operations, Z% on branches, and so on. Still, results using this simple approach have been satisfactory for now.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKyhjhhubeh}(h]representation-caveatah ]h"]1.4 representation caveatah$]h&]uh1hhhhhhhhKwubeh}(h] cpu-capacityah ]h"]1. cpu capacityah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h2. Task utilizationh]h2. Task utilization}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj?hhhhhKubh)}(hhh](h)}(h2.1 Introductionh]h2.1 Introduction}(hjShhhNhNubah}(h]h ]h"]h$]h&]uh1hhjPhhhhhKubh)}(hXCapacity aware scheduling requires an expression of a task's requirements with regards to CPU capacity. Each scheduler class can express this differently, and while task utilization is specific to CFS, it is convenient to describe it here in order to introduce more generic concepts.h]hXCapacity aware scheduling requires an expression of a task’s requirements with regards to CPU capacity. Each scheduler class can express this differently, and while task utilization is specific to CFS, it is convenient to describe it here in order to introduce more generic concepts.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjPhhubh)}(hTask utilization is a percentage meant to represent the throughput requirements of a task. A simple approximation of it is the task's duty cycle, i.e.::h]hTask utilization is a percentage meant to represent the throughput requirements of a task. A simple approximation of it is the task’s duty cycle, i.e.:}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjPhhubj`)}(htask_util(p) = duty_cycle(p)h]htask_util(p) = duty_cycle(p)}hj}sbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKhjPhhubh)}(hXFOn an SMP system with fixed frequencies, 100% utilization suggests the task is a busy loop. Conversely, 10% utilization hints it is a small periodic task that spends more time sleeping than executing. Variable CPU frequencies and asymmetric CPU capacities complexify this somewhat; the following sections will expand on these.h]hXFOn an SMP system with fixed frequencies, 100% utilization suggests the task is a busy loop. Conversely, 10% utilization hints it is a small periodic task that spends more time sleeping than executing. Variable CPU frequencies and asymmetric CPU capacities complexify this somewhat; the following sections will expand on these.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjPhhubeh}(h]id1ah ]h"]2.1 introductionah$]h&]uh1hhj?hhhhhKubh)}(hhh](h)}(h2.2 Frequency invarianceh]h2.2 Frequency invariance}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hOne issue that needs to be taken into account is that a workload's duty cycle is directly impacted by the current OPP the CPU is running at. Consider running a periodic workload at a given frequency F::h]hOne issue that needs to be taken into account is that a workload’s duty cycle is directly impacted by the current OPP the CPU is running at. Consider running a periodic workload at a given frequency F:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj`)}(hCPU work ^ | ____ ____ ____ | | | | | | | +----+----+----+----+----+----+----+----+----+----+-> timeh]hCPU work ^ | ____ ____ ____ | | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time}hjsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKhjhhubh)}(h!This yields duty_cycle(p) == 25%.h]h!This yields duty_cycle(p) == 25%.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h timeh]hCPU work ^ | _________ _________ ____ | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time}hjsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKhjhhubh)}(hThis yields duty_cycle(p) == 50%, despite the task having the exact same behaviour (i.e. executing the same amount of work) in both executions.h]hThis yields duty_cycle(p) == 50%, despite the task having the exact same behaviour (i.e. executing the same amount of work) in both executions.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hYThe task utilization signal can be made frequency invariant using the following formula::h]hXThe task utilization signal can be made frequency invariant using the following formula:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj`)}(hRtask_util_freq_inv(p) = duty_cycle(p) * (curr_frequency(cpu) / max_frequency(cpu))h]hRtask_util_freq_inv(p) = duty_cycle(p) * (curr_frequency(cpu) / max_frequency(cpu))}hj&sbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKhjhhubh)}(heApplying this formula to the two examples above yields a frequency invariant task utilization of 25%.h]heApplying this formula to the two examples above yields a frequency invariant task utilization of 25%.}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]frequency-invarianceah ]h"]2.2 frequency invarianceah$]h&]uh1hhj?hhhhhKubh)}(hhh](h)}(h2.3 CPU invarianceh]h2.3 CPU invariance}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjJhhhhhKubh)}(hCPU capacity has a similar effect on task utilization in that running an identical workload on CPUs of different capacity values will yield different duty cycles.h]hCPU capacity has a similar effect on task utilization in that running an identical workload on CPUs of different capacity values will yield different duty cycles.}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjJhhubh)}(h/Consider the system described in 1.3.2., i.e.::h]h.Consider the system described in 1.3.2., i.e.:}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjJhhubj`)}(h+- capacity(CPU0) = C - capacity(CPU1) = C/3h]h+- capacity(CPU0) = C - capacity(CPU1) = C/3}hjwsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKhjJhhubh)}(h\Executing a given periodic workload on each CPU at their maximum frequency would result in::h]h[Executing a given periodic workload on each CPU at their maximum frequency would result in:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjJhhubj`)}(hXCPU0 work ^ | ____ ____ ____ | | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time CPU1 work ^ | ______________ ______________ ____ | | | | | | +----+----+----+----+----+----+----+----+----+----+-> timeh]hXCPU0 work ^ | ____ ____ ____ | | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time CPU1 work ^ | ______________ ______________ ____ | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time}hjsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKhjJhhubh)}(hIOW,h]hIOW,}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjJhhubj)}(hhh](j )}(h?duty_cycle(p) == 25% if p runs on CPU0 at its maximum frequencyh]h)}(hjh]h?duty_cycle(p) == 25% if p runs on CPU0 at its maximum frequency}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j hjhhhhhNubj )}(h@duty_cycle(p) == 75% if p runs on CPU1 at its maximum frequency h]h)}(h?duty_cycle(p) == 75% if p runs on CPU1 at its maximum frequencyh]h?duty_cycle(p) == 75% if p runs on CPU1 at its maximum frequency}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1j hjhhhhhNubeh}(h]h ]h"]h$]h&]jAjBuh1jhhhKhjJhhubh)}(hSThe task utilization signal can be made CPU invariant using the following formula::h]hRThe task utilization signal can be made CPU invariant using the following formula:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjJhhubj`)}(hEtask_util_cpu_inv(p) = duty_cycle(p) * (capacity(cpu) / max_capacity)h]hEtask_util_cpu_inv(p) = duty_cycle(p) * (capacity(cpu) / max_capacity)}hjsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKhjJhhubh)}(hwith ``max_capacity`` being the highest CPU capacity value in the system. Applying this formula to the above example above yields a CPU invariant task utilization of 25%.h](hwith }(hjhhhNhNubj)}(h``max_capacity``h]h max_capacity}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh being the highest CPU capacity value in the system. Applying this formula to the above example above yields a CPU invariant task utilization of 25%.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjJhhubeh}(h]cpu-invarianceah ]h"]2.3 cpu invarianceah$]h&]uh1hhj?hhhhhKubh)}(hhh](h)}(h2.4 Invariant task utilizationh]h2.4 Invariant task utilization}(hj.hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj+hhhhhKubh)}(hBoth frequency and CPU invariance need to be applied to task utilization in order to obtain a truly invariant signal. The pseudo-formula for a task utilization that is both CPU and frequency invariant is thus, for a given task p::h]hBoth frequency and CPU invariance need to be applied to task utilization in order to obtain a truly invariant signal. The pseudo-formula for a task utilization that is both CPU and frequency invariant is thus, for a given task p:}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj+hhubj`)}(h curr_frequency(cpu) capacity(cpu) task_util_inv(p) = duty_cycle(p) * ------------------- * ------------- max_frequency(cpu) max_capacityh]h curr_frequency(cpu) capacity(cpu) task_util_inv(p) = duty_cycle(p) * ------------------- * ------------- max_frequency(cpu) max_capacity}hjJsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhKhj+hhubh)}(hIn other words, invariant task utilization describes the behaviour of a task as if it were running on the highest-capacity CPU in the system, running at its maximum frequency.h]hIn other words, invariant task utilization describes the behaviour of a task as if it were running on the highest-capacity CPU in the system, running at its maximum frequency.}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj+hhubh)}(hXAny mention of task utilization in the following sections will imply its invariant form.h]hXAny mention of task utilization in the following sections will imply its invariant form.}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj+hhubeh}(h]invariant-task-utilizationah ]h"]2.4 invariant task utilizationah$]h&]uh1hhj?hhhhhKubh)}(hhh](h)}(h2.5 Utilization estimationh]h2.5 Utilization estimation}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj|hhhhhKubh)}(hXKWithout a crystal ball, task behaviour (and thus task utilization) cannot accurately be predicted the moment a task first becomes runnable. The CFS class maintains a handful of CPU and task signals based on the Per-Entity Load Tracking (PELT) mechanism, one of those yielding an *average* utilization (as opposed to instantaneous).h](hXWithout a crystal ball, task behaviour (and thus task utilization) cannot accurately be predicted the moment a task first becomes runnable. The CFS class maintains a handful of CPU and task signals based on the Per-Entity Load Tracking (PELT) mechanism, one of those yielding an }(hjhhhNhNubj)}(h *average*h]haverage}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh+ utilization (as opposed to instantaneous).}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj|hhubh)}(hThis means that while the capacity aware scheduling criteria will be written considering a "true" task utilization (using a crystal ball), the implementation will only ever be able to use an estimator thereof.h]hThis means that while the capacity aware scheduling criteria will be written considering a “true” task utilization (using a crystal ball), the implementation will only ever be able to use an estimator thereof.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj|hhubeh}(h]utilization-estimationah ]h"]2.5 utilization estimationah$]h&]uh1hhj?hhhhhKubeh}(h]task-utilizationah ]h"]2. task utilizationah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h)3. Capacity aware scheduling requirementsh]h)3. Capacity aware scheduling requirements}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hhh](h)}(h3.1 CPU capacityh]h3.1 CPU capacity}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hLinux cannot currently figure out CPU capacity on its own, this information thus needs to be handed to it. Architectures must define arch_scale_cpu_capacity() for that purpose.h]hLinux cannot currently figure out CPU capacity on its own, this information thus needs to be handed to it. Architectures must define arch_scale_cpu_capacity() for that purpose.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hThe arm, arm64, and RISC-V architectures directly map this to the arch_topology driver CPU scaling data, which is derived from the capacity-dmips-mhz CPU binding; see Documentation/devicetree/bindings/cpu/cpu-capacity.txt.h]hThe arm, arm64, and RISC-V architectures directly map this to the arch_topology driver CPU scaling data, which is derived from the capacity-dmips-mhz CPU binding; see Documentation/devicetree/bindings/cpu/cpu-capacity.txt.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h]id2ah ]h"]3.1 cpu capacityah$]h&]uh1hhjhhhhhMubh)}(hhh](h)}(h3.2 Frequency invarianceh]h3.2 Frequency invariance}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhM ubh)}(hAs stated in 2.2, capacity-aware scheduling requires a frequency-invariant task utilization. Architectures must define arch_scale_freq_capacity(cpu) for that purpose.h]hAs stated in 2.2, capacity-aware scheduling requires a frequency-invariant task utilization. Architectures must define arch_scale_freq_capacity(cpu) for that purpose.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjhhubh)}(hXImplementing this function requires figuring out at which frequency each CPU have been running at. One way to implement this is to leverage hardware counters whose increment rate scale with a CPU's current frequency (APERF/MPERF on x86, AMU on arm64). Another is to directly hook into cpufreq frequency transitions, when the kernel is aware of the switched-to frequency (also employed by arm/arm64).h]hXImplementing this function requires figuring out at which frequency each CPU have been running at. One way to implement this is to leverage hardware counters whose increment rate scale with a CPU’s current frequency (APERF/MPERF on x86, AMU on arm64). Another is to directly hook into cpufreq frequency transitions, when the kernel is aware of the switched-to frequency (also employed by arm/arm64).}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h]id3ah ]h"]3.2 frequency invarianceah$]h&]uh1hhjhhhhhM ubeh}(h]&capacity-aware-scheduling-requirementsah ]h"])3. capacity aware scheduling requirementsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h4. Scheduler topologyh]h4. Scheduler topology}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjNhhhhhMubh)}(hDuring the construction of the sched domains, the scheduler will figure out whether the system exhibits asymmetric CPU capacities. Should that be the case:h]hDuring the construction of the sched domains, the scheduler will figure out whether the system exhibits asymmetric CPU capacities. Should that be the case:}(hj_hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjNhhubj)}(hhh](j )}(h6The sched_asym_cpucapacity static key will be enabled.h]h)}(hjrh]h6The sched_asym_cpucapacity static key will be enabled.}(hjthhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjpubah}(h]h ]h"]h$]h&]uh1j hjmhhhhhNubj )}(hyThe SD_ASYM_CPUCAPACITY_FULL flag will be set at the lowest sched_domain level that spans all unique CPU capacity values.h]h)}(hyThe SD_ASYM_CPUCAPACITY_FULL flag will be set at the lowest sched_domain level that spans all unique CPU capacity values.h]hyThe SD_ASYM_CPUCAPACITY_FULL flag will be set at the lowest sched_domain level that spans all unique CPU capacity values.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjubah}(h]h ]h"]h$]h&]uh1j hjmhhhhhNubj )}(hkThe SD_ASYM_CPUCAPACITY flag will be set for any sched_domain that spans CPUs with any range of asymmetry. h]h)}(hjThe SD_ASYM_CPUCAPACITY flag will be set for any sched_domain that spans CPUs with any range of asymmetry.h]hjThe SD_ASYM_CPUCAPACITY flag will be set for any sched_domain that spans CPUs with any range of asymmetry.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM"hjubah}(h]h ]h"]h$]h&]uh1j hjmhhhhhNubeh}(h]h ]h"]h$]h&]jAjBuh1jhhhMhjNhhubh)}(hThe sched_asym_cpucapacity static key is intended to guard sections of code that cater to asymmetric CPU capacity systems. Do note however that said key is *system-wide*. Imagine the following setup using cpusets::h](hThe sched_asym_cpucapacity static key is intended to guard sections of code that cater to asymmetric CPU capacity systems. Do note however that said key is }(hjhhhNhNubj)}(h *system-wide*h]h system-wide}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh,. Imagine the following setup using cpusets:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM%hjNhhubj`)}(hcapacity C/2 C ________ ________ / \ / \ CPUs 0 1 2 3 4 5 6 7 \__/ \______________/ cpusets cs0 cs1h]hcapacity C/2 C ________ ________ / \ / \ CPUs 0 1 2 3 4 5 6 7 \__/ \______________/ cpusets cs0 cs1}hjsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhM)hjNhhubh)}(hWhich could be created via:h]hWhich could be created via:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM0hjNhhubj`)}(hX:mkdir /sys/fs/cgroup/cpuset/cs0 echo 0-1 > /sys/fs/cgroup/cpuset/cs0/cpuset.cpus echo 0 > /sys/fs/cgroup/cpuset/cs0/cpuset.mems mkdir /sys/fs/cgroup/cpuset/cs1 echo 2-7 > /sys/fs/cgroup/cpuset/cs1/cpuset.cpus echo 0 > /sys/fs/cgroup/cpuset/cs1/cpuset.mems echo 0 > /sys/fs/cgroup/cpuset/cpuset.sched_load_balanceh]hX:mkdir /sys/fs/cgroup/cpuset/cs0 echo 0-1 > /sys/fs/cgroup/cpuset/cs0/cpuset.cpus echo 0 > /sys/fs/cgroup/cpuset/cs0/cpuset.mems mkdir /sys/fs/cgroup/cpuset/cs1 echo 2-7 > /sys/fs/cgroup/cpuset/cs1/cpuset.cpus echo 0 > /sys/fs/cgroup/cpuset/cs1/cpuset.mems echo 0 > /sys/fs/cgroup/cpuset/cpuset.sched_load_balance}hjsbah}(h]h ]h"]h$]h&]jojpforcelanguageshhighlight_args}uh1j_hhhM2hjNhhubh)}(hX'Since there *is* CPU capacity asymmetry in the system, the sched_asym_cpucapacity static key will be enabled. However, the sched_domain hierarchy of CPUs 0-1 spans a single capacity value: SD_ASYM_CPUCAPACITY isn't set in that hierarchy, it describes an SMP island and should be treated as such.h](h Since there }(hj hhhNhNubj)}(h*is*h]his}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubhX CPU capacity asymmetry in the system, the sched_asym_cpucapacity static key will be enabled. However, the sched_domain hierarchy of CPUs 0-1 spans a single capacity value: SD_ASYM_CPUCAPACITY isn’t set in that hierarchy, it describes an SMP island and should be treated as such.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM>hjNhhubh)}(hjTherefore, the 'canonical' pattern for protecting codepaths that cater to asymmetric CPU capacities is to:h]hnTherefore, the ‘canonical’ pattern for protecting codepaths that cater to asymmetric CPU capacities is to:}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMChjNhhubj)}(hhh](j )}(h+Check the sched_asym_cpucapacity static keyh]h)}(hj?h]h+Check the sched_asym_cpucapacity static key}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMFhj=ubah}(h]h ]h"]h$]h&]uh1j hj:hhhhhNubj )}(hIf it is enabled, then also check for the presence of SD_ASYM_CPUCAPACITY in the sched_domain hierarchy (if relevant, i.e. the codepath targets a specific CPU or group thereof) h]h)}(hIf it is enabled, then also check for the presence of SD_ASYM_CPUCAPACITY in the sched_domain hierarchy (if relevant, i.e. the codepath targets a specific CPU or group thereof)h]hIf it is enabled, then also check for the presence of SD_ASYM_CPUCAPACITY in the sched_domain hierarchy (if relevant, i.e. the codepath targets a specific CPU or group thereof)}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMGhjTubah}(h]h ]h"]h$]h&]uh1j hj:hhhhhNubeh}(h]h ]h"]h$]h&]jAjBuh1jhhhMFhjNhhubeh}(h]scheduler-topologyah ]h"]4. scheduler topologyah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(h+5. Capacity aware scheduling implementationh]h+5. Capacity aware scheduling implementation}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjzhhhhhMLubh)}(hhh](h)}(h5.1 CFSh]h5.1 CFS}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMOubh)}(hhh](h)}(h5.1.1 Capacity fitnessh]h5.1.1 Capacity fitness}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMRubh)}(h2The main capacity scheduling criterion of CFS is::h]h1The main capacity scheduling criterion of CFS is:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMThjhhubj`)}(h$task_util(p) < capacity(task_cpu(p))h]h$task_util(p) < capacity(task_cpu(p))}hjsbah}(h]h ]h"]h$]h&]jojpuh1j_hhhMVhjhhubh)}(hThis is commonly called the capacity fitness criterion, i.e. CFS must ensure a task "fits" on its CPU. If it is violated, the task will need to achieve more work than what its CPU can provide: it will be CPU-bound.h]hThis is commonly called the capacity fitness criterion, i.e. CFS must ensure a task “fits” on its CPU. If it is violated, the task will need to achieve more work than what its CPU can provide: it will be CPU-bound.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMXhjhhubh)}(hXFurthermore, uclamp lets userspace specify a minimum and a maximum utilization value for a task, either via sched_setattr() or via the cgroup interface (see Documentation/admin-guide/cgroup-v2.rst). As its name imply, this can be used to clamp task_util() in the previous criterion.h]hXFurthermore, uclamp lets userspace specify a minimum and a maximum utilization value for a task, either via sched_setattr() or via the cgroup interface (see Documentation/admin-guide/cgroup-v2.rst). As its name imply, this can be used to clamp task_util() in the previous criterion.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM\hjhhubeh}(h]capacity-fitnessah ]h"]5.1.1 capacity fitnessah$]h&]uh1hhjhhhhhMRubh)}(hhh](h)}(h5.1.2 Wakeup CPU selectionh]h5.1.2 Wakeup CPU selection}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMbubh)}(hX)CFS task wakeup CPU selection follows the capacity fitness criterion described above. On top of that, uclamp is used to clamp the task utilization values, which lets userspace have more leverage over the CPU selection of CFS tasks. IOW, CFS wakeup CPU selection searches for a CPU that satisfies::h]hX(CFS task wakeup CPU selection follows the capacity fitness criterion described above. On top of that, uclamp is used to clamp the task utilization values, which lets userspace have more leverage over the CPU selection of CFS tasks. IOW, CFS wakeup CPU selection searches for a CPU that satisfies:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMdhjhhubj`)}(hKclamp(task_util(p), task_uclamp_min(p), task_uclamp_max(p)) < capacity(cpu)h]hKclamp(task_util(p), task_uclamp_min(p), task_uclamp_max(p)) < capacity(cpu)}hj sbah}(h]h ]h"]h$]h&]jojpuh1j_hhhMihjhhubh)}(hXBy using uclamp, userspace can e.g. allow a busy loop (100% utilization) to run on any CPU by giving it a low uclamp.max value. Conversely, it can force a small periodic task (e.g. 10% utilization) to run on the highest-performance CPUs by giving it a high uclamp.min value.h]hXBy using uclamp, userspace can e.g. allow a busy loop (100% utilization) to run on any CPU by giving it a low uclamp.max value. Conversely, it can force a small periodic task (e.g. 10% utilization) to run on the highest-performance CPUs by giving it a high uclamp.min value.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMkhjhhubhnote)}(hWakeup CPU selection in CFS can be eclipsed by Energy Aware Scheduling (EAS), which is described in Documentation/scheduler/sched-energy.rst.h]h)}(hWakeup CPU selection in CFS can be eclipsed by Energy Aware Scheduling (EAS), which is described in Documentation/scheduler/sched-energy.rst.h]hWakeup CPU selection in CFS can be eclipsed by Energy Aware Scheduling (EAS), which is described in Documentation/scheduler/sched-energy.rst.}(hj. hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMrhj* ubah}(h]h ]h"]h$]h&]uh1j( hjhhhhhNubeh}(h]wakeup-cpu-selectionah ]h"]5.1.2 wakeup cpu selectionah$]h&]uh1hhjhhhhhMbubh)}(hhh](h)}(h5.1.3 Load balancingh]h5.1.3 Load balancing}(hjM hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjJ hhhhhMvubh)}(hA pathological case in the wakeup CPU selection occurs when a task rarely sleeps, if at all - it thus rarely wakes up, if at all. Consider::h]hA pathological case in the wakeup CPU selection occurs when a task rarely sleeps, if at all - it thus rarely wakes up, if at all. Consider:}(hj[ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMxhjJ hhubj`)}(hX3w == wakeup event capacity(CPU0) = C capacity(CPU1) = C / 3 workload on CPU0 CPU work ^ | _________ _________ ____ | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time w w w workload on CPU1 CPU work ^ | ____________________________________________ | | +----+----+----+----+----+----+----+----+----+----+-> wh]hX3w == wakeup event capacity(CPU0) = C capacity(CPU1) = C / 3 workload on CPU0 CPU work ^ | _________ _________ ____ | | | | | | +----+----+----+----+----+----+----+----+----+----+-> time w w w workload on CPU1 CPU work ^ | ____________________________________________ | | +----+----+----+----+----+----+----+----+----+----+-> w}hji sbah}(h]h ]h"]h$]h&]jojpuh1j_hhhM{hjJ hhubh)}(h9This workload should run on CPU0, but if the task either:h]h9This workload should run on CPU0, but if the task either:}(hjw hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjJ hhubj)}(hhh](j )}(hSwas improperly scheduled from the start (inaccurate initial utilization estimation)h]h)}(hSwas improperly scheduled from the start (inaccurate initial utilization estimation)h]hSwas improperly scheduled from the start (inaccurate initial utilization estimation)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j hj hhhhhNubj )}(hPwas properly scheduled from the start, but suddenly needs more processing power h]h)}(hOwas properly scheduled from the start, but suddenly needs more processing powerh]hOwas properly scheduled from the start, but suddenly needs more processing power}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1j hj hhhhhNubeh}(h]h ]h"]h$]h&]jAjBuh1jhhhMhjJ hhubh)}(hthen it might become CPU-bound, IOW ``task_util(p) > capacity(task_cpu(p))``; the CPU capacity scheduling criterion is violated, and there may not be any more wakeup event to fix this up via wakeup CPU selection.h](h$then it might become CPU-bound, IOW }(hj hhhNhNubj)}(h(``task_util(p) > capacity(task_cpu(p))``h]h$task_util(p) > capacity(task_cpu(p))}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh; the CPU capacity scheduling criterion is violated, and there may not be any more wakeup event to fix this up via wakeup CPU selection.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjJ hhubh)}(hXTasks that are in this situation are dubbed "misfit" tasks, and the mechanism put in place to handle this shares the same name. Misfit task migration leverages the CFS load balancer, more specifically the active load balance part (which caters to migrating currently running tasks). When load balance happens, a misfit active load balance will be triggered if a misfit task can be migrated to a CPU with more capacity than its current one.h]hXTasks that are in this situation are dubbed “misfit” tasks, and the mechanism put in place to handle this shares the same name. Misfit task migration leverages the CFS load balancer, more specifically the active load balance part (which caters to migrating currently running tasks). When load balance happens, a misfit active load balance will be triggered if a misfit task can be migrated to a CPU with more capacity than its current one.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjJ hhubeh}(h]load-balancingah ]h"]5.1.3 load balancingah$]h&]uh1hhjhhhhhMvubeh}(h]cfsah ]h"]5.1 cfsah$]h&]uh1hhjzhhhhhMOubh)}(hhh](h)}(h5.2 RTh]h5.2 RT}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(h5.2.1 Wakeup CPU selectionh]h5.2.1 Wakeup CPU selection}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(h@RT task wakeup CPU selection searches for a CPU that satisfies::h]h?RT task wakeup CPU selection searches for a CPU that satisfies:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj`)}(h-task_uclamp_min(p) <= capacity(task_cpu(cpu))h]h-task_uclamp_min(p) <= capacity(task_cpu(cpu))}hj, sbah}(h]h ]h"]h$]h&]jojpuh1j_hhhMhj hhubh)}(hwhile still following the usual priority constraints. If none of the candidate CPUs can satisfy this capacity criterion, then strict priority based scheduling is followed and CPU capacities are ignored.h]hwhile still following the usual priority constraints. If none of the candidate CPUs can satisfy this capacity criterion, then strict priority based scheduling is followed and CPU capacities are ignored.}(hj: hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h]id4ah ]h"]5.2.1 wakeup cpu selectionah$]h&]uh1hhj hhhhhMubeh}(h]rtah ]h"]5.2 rtah$]h&]uh1hhjzhhhhhMubh)}(hhh](h)}(h5.3 DLh]h5.3 DL}(hj[ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjX hhhhhMubh)}(hhh](h)}(h5.3.1 Wakeup CPU selectionh]h5.3.1 Wakeup CPU selection}(hjl hhhNhNubah}(h]h ]h"]h$]h&]uh1hhji hhhhhMubh)}(h@DL task wakeup CPU selection searches for a CPU that satisfies::h]h?DL task wakeup CPU selection searches for a CPU that satisfies:}(hjz hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhji hhubj`)}(h)task_bandwidth(p) < capacity(task_cpu(p))h]h)task_bandwidth(p) < capacity(task_cpu(p))}hj sbah}(h]h ]h"]h$]h&]jojpuh1j_hhhMhji hhubh)}(hwhile still respecting the usual bandwidth and deadline constraints. If none of the candidate CPUs can satisfy this capacity criterion, then the task will remain on its current CPU.h]hwhile still respecting the usual bandwidth and deadline constraints. If none of the candidate CPUs can satisfy this capacity criterion, then the task will remain on its current CPU.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhji hhubeh}(h]id5ah ]h"]5.3.1 wakeup cpu selectionah$]h&]uh1hhjX hhhhhMubeh}(h]dlah ]h"]5.3 dlah$]h&]uh1hhjzhhhhhMubeh}(h](capacity-aware-scheduling-implementationah ]h"]+5. capacity aware scheduling implementationah$]h&]uh1hhhhhhhhMLubeh}(h]capacity-aware-schedulingah ]h"]capacity aware schedulingah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(j j j<j9jvjsj+j(jjj0j-jjj4j1jjjjjGjDj(j%jyjvjjjKjHjj jCj@jwjtj j j j jjjG jD j j jU jR jM jJ j j j j u nametypes}(j j<jvj+jj0jj4jjjGj(jyjjKjjCjwj j jjG j jU jM j j uh}(j hj9hjshj(jyjj.j-j?jj3j1jjj?jjPjDjj%jJjvj+jj|jHjj jj@jjtjNj jzj jjjjD jj jJ jR j jJ j j jX j ji u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}j KsRparse_messages]transform_messages] transformerN include_log] decorationNhhub.