• Patrick Bellasi's avatar
    sched/core: Optimize sched_feat() for !CONFIG_SCHED_DEBUG builds · 765cc3a4
    Patrick Bellasi authored
    When the kernel is compiled with !CONFIG_SCHED_DEBUG support, we expect that
    all SCHED_FEAT are turned into compile time constants being propagated
    to support compiler optimizations.
    
    Specifically, we expect that code blocks like this:
    
       if (sched_feat(FEATURE_NAME) [&& <other_conditions>]) {
    	/* FEATURE CODE */
       }
    
    are turned into dead-code in case FEATURE_NAME defaults to FALSE, and thus
    being removed by the compiler from the finale image.
    
    For this mechanism to properly work it's required for the compiler to
    have full access, from each translation unit, to whatever is the value
    defined by the sched_feat macro. This macro is defined as:
    
       #define sched_feat(x) (sysctl_sched_features & (1UL << __SCHED_FEAT_##x))
    
    and thus, the compiler can optimize that code only if the value of
    sysctl_sched_features is visible within each translation unit.
    
    Since:
    
       029632fb ("sched: Make separate sched*.c translation units")
    
    the scheduler code has been split into separate translation units
    however the definition of sysctl_sched_features is part of
    kernel/sched/core.c while, for all the other scheduler modules, it is
    visible only via kernel/sched/sched.h as an:
    
       extern const_debug unsigned int sysctl_sched_features
    
    Unfortunately, an extern reference does not allow the compiler to apply
    constants propagation. Thus, on !CONFIG_SCHED_DEBUG kernel we still end up
    with code to load a memory reference and (eventually) doing an unconditional
    jump of a chunk of code.
    
    This mechanism is unavoidable when sched_features can be turned on and off at
    run-time. However, this is not the case for "production" kernels compiled with
    !CONFIG_SCHED_DEBUG. In this case, sysctl_sched_features is just a constant value
    which cannot be changed at run-time and thus memory loads and jumps can be
    avoided altogether.
    
    This patch fixes the case of !CONFIG_SCHED_DEBUG kernel by declaring a local version
    of the sysctl_sched_features constant for each translation unit. This will
    ultimately allow the compiler to perform constants propagation and dead-code
    pruning.
    
    Tests have been done, with !CONFIG_SCHED_DEBUG on a v4.14-rc8 with and without
    the patch, by running 30 iterations of:
    
       perf bench sched messaging --pipe --thread --group 4 --loop 50000
    
    on a 40 cores Intel(R) Xeon(R) CPU E5-2690 v2 @ 3.00GHz using the
    powersave governor to rule out variations due to frequency scaling.
    
    Statistics on the reported completion time:
    
                       count     mean       std     min       99%     max
      v4.14-rc8         30.0  15.7831  0.176032  15.442  16.01226  16.014
      v4.14-rc8+patch   30.0  15.5033  0.189681  15.232  15.93938  15.962
    
    ... show a 1.8% speedup on average completion time and 0.5% speedup in the
    99 percentile.
    Signed-off-by: default avatarPatrick Bellasi <patrick.bellasi@arm.com>
    Signed-off-by: default avatarChris Redpath <chris.redpath@arm.com>
    Reviewed-by: default avatarDietmar Eggemann <dietmar.eggemann@arm.com>
    Reviewed-by: default avatarBrendan Jackman <brendan.jackman@arm.com>
    Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
    Cc: Juri Lelli <juri.lelli@redhat.com>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Morten Rasmussen <morten.rasmussen@arm.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Vincent Guittot <vincent.guittot@linaro.org>
    Link: http://lkml.kernel.org/r/20171108184101.16006-1-patrick.bellasi@arm.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    765cc3a4
core.c 166 KB