• Quentin Perret's avatar
    sched/fair: Speed-up energy-aware wake-ups · eb92692b
    Quentin Perret authored
    EAS computes the energy impact of migrating a waking task when deciding
    on which CPU it should run. However, the current approach is known to
    have a high algorithmic complexity, which can result in prohibitively
    high wake-up latencies on systems with complex energy models, such as
    systems with per-CPU DVFS. On such systems, the algorithm complexity is
    in O(n^2) (ignoring the cost of searching for performance states in the
    EM) with 'n' the number of CPUs.
    
    To address this, re-factor the EAS wake-up path to compute the energy
    'delta' (with and without the task) on a per-performance domain basis,
    rather than system-wide, which brings the complexity down to O(n).
    
    No functional changes intended.
    
    Test results
    ~~~~~~~~~~~~
    
    * Setup: Tested on a Google Pixel 3, with a Snapdragon 845 (4+4 CPUs,
      A55/A75). Base kernel is 5.3-rc5 + Pixel3 specific patches. Android
      userspace, no graphics.
    
    * Test case:  Run a periodic rt-app task, with 16ms period, ramping down
      from 70% to 10%, in 5% steps of 500 ms each (json avail. at [1]).
      Frequencies of all CPUs are pinned to max (using scaling_min_freq
      CPUFreq sysfs entries) to reduce variability. The time to run
      select_task_rq_fair() is measured using the function profiler
      (/sys/kernel/debug/tracing/trace_stat/function*). See the test script
      for more details [2].
    
    Test 1:
    
    I hacked the DT to 'fake' per-CPU DVFS. That is, we end up with one
    CPUFreq policy per CPU (8 policies in total). Since all frequencies are
    pinned to max for the test, this should have no impact on the actual
    frequency selection, but it does in the EAS calculation.
    
          +---------------------------+----------------------------------+
          | Without patch             | With patch                       |
    +-----+-----+----------+----------+-----+-----------------+----------+
    | CPU | Hit | Avg (us) | s^2 (us) | Hit | Avg (us)        | s^2 (us) |
    |-----+-----+----------+----------+-----+-----------------+----------+
    |  0  | 274 | 38.303   | 1750.239 | 401 | 14.126 (-63.1%) | 146.625  |
    |  1  | 197 | 49.529   | 1695.852 | 314 | 16.135 (-67.4%) | 167.525  |
    |  2  | 142 | 34.296   | 1758.665 | 302 | 14.133 (-58.8%) | 130.071  |
    |  3  | 172 | 31.734   | 1490.975 | 641 | 14.637 (-53.9%) | 139.189  |
    |  4  | 316 | 7.834    | 178.217  | 425 | 5.413  (-30.9%) | 20.803   |
    |  5  | 447 | 8.424    | 144.638  | 556 | 5.929  (-29.6%) | 27.301   |
    |  6  | 581 | 14.886   | 346.793  | 456 | 5.711  (-61.6%) | 23.124   |
    |  7  | 456 | 10.005   | 211.187  | 997 | 4.708  (-52.9%) | 21.144   |
    +-----+-----+----------+----------+-----+-----------------+----------+
                 * Hit, Avg and s^2 are as reported by the function profiler
    
    Test 2:
    I also ran the same test with a normal DT, with 2 CPUFreq policies, to
    see if this causes regressions in the most common case.
    
          +---------------------------+----------------------------------+
          | Without patch             | With patch                       |
    +-----+-----+----------+----------+-----+-----------------+----------+
    | CPU | Hit | Avg (us) | s^2 (us) | Hit | Avg (us)        | s^2 (us) |
    |-----+-----+----------+----------+-----+-----------------+----------+
    |  0  | 345 | 22.184   | 215.321  | 580 | 18.635 (-16.0%) | 146.892  |
    |  1  | 358 | 18.597   | 200.596  | 438 | 12.934 (-30.5%) | 104.604  |
    |  2  | 359 | 25.566   | 200.217  | 397 | 10.826 (-57.7%) | 74.021   |
    |  3  | 362 | 16.881   | 200.291  | 718 | 11.455 (-32.1%) | 102.280  |
    |  4  | 457 | 3.822    | 9.895    | 757 | 4.616  (+20.8%) | 13.369   |
    |  5  | 344 | 4.301    | 7.121    | 594 | 5.320  (+23.7%) | 18.798   |
    |  6  | 472 | 4.326    | 7.849    | 464 | 5.648  (+30.6%) | 22.022   |
    |  7  | 331 | 4.630    | 13.937   | 408 | 5.299  (+14.4%) | 18.273   |
    +-----+-----+----------+----------+-----+-----------------+----------+
                 * Hit, Avg and s^2 are as reported by the function profiler
    
    In addition to these two tests, I also ran 50 iterations of the Lisa
    EAS functional test suite [3] with this patch applied on Arm Juno r0,
    Arm Juno r2, Arm TC2 and Hikey960, and could not see any regressions
    (all EAS functional tests are passing).
    
     [1] https://paste.debian.net/1100055/
     [2] https://paste.debian.net/1100057/
     [3] https://github.com/ARM-software/lisa/blob/master/lisa/tests/scheduler/eas_behaviour.pySigned-off-by: default avatarQuentin Perret <quentin.perret@arm.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: dietmar.eggemann@arm.com
    Cc: juri.lelli@redhat.com
    Cc: morten.rasmussen@arm.com
    Cc: qais.yousef@arm.com
    Cc: qperret@qperret.net
    Cc: rjw@rjwysocki.net
    Cc: tkjos@google.com
    Cc: valentin.schneider@arm.com
    Cc: vincent.guittot@linaro.org
    Link: https://lkml.kernel.org/r/20190912094404.13802-1-qperret@qperret.netSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    eb92692b
fair.c 279 KB