<div dir="ltr"><div>Hi everyone ~</div><div><br></div><div>I've read a few different references on CFS and have been looking through fair.c at the CFS scheduler code. One thing I'm not completely understanding is what happens when too many processes are running such that <font face="monospace">nr_running * min_granularity > sched_latency</font></div><div><br></div><div>I know that the scheduler will expand the period so that each process can run for at least the min_granularity, <b>but how does that interact with nice numbers</b>? Here's the code for expanding the period:</div><div><font face="monospace"><br></font></div><div><font face="monospace">/*<br> * The idea is to set a period in which each task runs once.<br> *<br> * When there are too many tasks (sched_nr_latency) we have to stretch<br> * this period because otherwise the slices get too small.<br> *<br> * p = (nr <= nl) ? l : l*nr/nl<br> */<br>static u64 __sched_period(unsigned long nr_running)<br>{<br>        if (unlikely(nr_running > sched_nr_latency))<br>                return nr_running * sysctl_sched_min_granularity;<br>        else<br>                return sysctl_sched_latency;<br>}</font><br></div><div><b><br></b></div><div>Here's the code for calculating an individual process's slice. It looks like the weighting formula is used here regardless of whether the period has been expanded.</div><div><ul><li style="margin-left:15px">If that's the case, doesn't that mean that some processes will still get a slice that's smaller than the min_granularity?</li></ul></div><div><font face="monospace">/*<br> * We calculate the wall-time slice from the period by taking a part<br> * proportional to the weight.<br> *<br> * s = p*P[w/rw]<br> */<br>static u64 sched_slice(struct cfs_rq *cfs_rq, struct sched_entity *se)<br>{<br>        u64 slice = __sched_period(cfs_rq->nr_running + !se->on_rq);<br><br>        for_each_sched_entity(se) {<br>                struct load_weight *load;<br>                struct load_weight lw;<br><br>                cfs_rq = cfs_rq_of(se);<br>                load = &cfs_rq->load;<br><br>                if (unlikely(!se->on_rq)) {<br>                        lw = cfs_rq->load;<br><br>                        update_load_add(&lw, se->load.weight);<br>                        load = &lw;<br>                }<br>                slice = __calc_delta(slice, se->load.weight, load);<br>        }<br>        return slice;<br>}<br></font></div><div><font face="monospace"><br></font></div><div>I ran a test by starting five busy processes with a nice level of -10. Next, I launched ~40 busy processes with a nice level of 0 (all procs were set to use the same CPU). I expected CFS to expand the period and assign each process a slice equal to the min granularity. However, the 5 processes with nice = -10 still used considerably more CPU than the other processes. </div><div><font face="monospace"><b><br></b></font></div><div>Is <font face="monospace">__calc_delta </font><font face="arial, sans-serif">in the function above actually expanding the slice further based on the nice weighting of the tasks? The </font><span style="font-family:monospace">__calc_delta </span><font face="arial, sans-serif">function is a bit difficult to follow, so I haven't quite figured out what it's doing.</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">tl;dr I know that CFS expands the period if lots of processes are running. What I'm not sure about is how nice levels affect the slice each task gets if the period has been expanded due to a high number of running tasks.</font></div><div><font face="arial, sans-serif"><br></font></div><div><font face="arial, sans-serif">Thanks!</font></div></div>