lkml.org 
[lkml]   [2016]   [Apr]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 1/6] sched/fair: Generalize the load/util averages resolution definition
    Date
    Integer metric needs fixed point arithmetic. In sched/fair, a few
    metrics, e.g., weight, load, load_avg, util_avg, freq, and capacity,
    may have different fixed point ranges, which makes their update and
    usage error-prone.

    In order to avoid the errors relating to the fixed point range, we
    definie a basic fixed point range, and then formalize all metrics to
    base on the basic range.

    The basic range is 1024 or (1 << 10). Further, one can recursively
    apply the basic range to have larger range.

    Pointed out by Ben Segall, weight (visible to user, e.g., NICE-0 has
    1024) and load (e.g., NICE_0_LOAD) have independent ranges, but they
    must be well calibrated.

    Signed-off-by: Yuyang Du <yuyang.du@intel.com>
    ---
    include/linux/sched.h | 16 +++++++++++++---
    kernel/sched/fair.c | 4 ----
    kernel/sched/sched.h | 15 ++++++++++-----
    3 files changed, 23 insertions(+), 12 deletions(-)

    diff --git a/include/linux/sched.h b/include/linux/sched.h
    index 45e848c..bc652fe 100644
    --- a/include/linux/sched.h
    +++ b/include/linux/sched.h
    @@ -935,9 +935,19 @@ enum cpu_idle_type {
    };

    /*
    + * Integer metrics need fixed point arithmetic, e.g., sched/fair
    + * has a few: load, load_avg, util_avg, freq, and capacity.
    + *
    + * We define a basic fixed point arithmetic range, and then formalize
    + * all these metrics based on that basic range.
    + */
    +# define SCHED_FIXEDPOINT_SHIFT 10
    +# define SCHED_FIXEDPOINT_SCALE (1L << SCHED_FIXEDPOINT_SHIFT)
    +
    +/*
    * Increase resolution of cpu_capacity calculations
    */
    -#define SCHED_CAPACITY_SHIFT 10
    +#define SCHED_CAPACITY_SHIFT SCHED_FIXEDPOINT_SHIFT
    #define SCHED_CAPACITY_SCALE (1L << SCHED_CAPACITY_SHIFT)

    /*
    @@ -1203,8 +1213,8 @@ struct load_weight {
    * 1) load_avg factors frequency scaling into the amount of time that a
    * sched_entity is runnable on a rq into its weight. For cfs_rq, it is the
    * aggregated such weights of all runnable and blocked sched_entities.
    - * 2) util_avg factors frequency and cpu scaling into the amount of time
    - * that a sched_entity is running on a CPU, in the range [0..SCHED_LOAD_SCALE].
    + * 2) util_avg factors frequency and cpu capacity scaling into the amount of time
    + * that a sched_entity is running on a CPU, in the range [0..SCHED_CAPACITY_SCALE].
    * For cfs_rq, it is the aggregated such times of all runnable and
    * blocked sched_entities.
    * The 64 bit load_sum can:
    diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
    index b8cc1c3..88ab334 100644
    --- a/kernel/sched/fair.c
    +++ b/kernel/sched/fair.c
    @@ -2662,10 +2662,6 @@ static u32 __compute_runnable_contrib(u64 n)
    return contrib + runnable_avg_yN_sum[n];
    }

    -#if (SCHED_LOAD_SHIFT - SCHED_LOAD_RESOLUTION) != 10 || SCHED_CAPACITY_SHIFT != 10
    -#error "load tracking assumes 2^10 as unit"
    -#endif
    -
    #define cap_scale(v, s) ((v)*(s) >> SCHED_CAPACITY_SHIFT)

    /*
    diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
    index a7cbad7..03ce2de 100644
    --- a/kernel/sched/sched.h
    +++ b/kernel/sched/sched.h
    @@ -54,18 +54,23 @@ static inline void update_cpu_load_active(struct rq *this_rq) { }
    * increased costs.
    */
    #if 0 /* BITS_PER_LONG > 32 -- currently broken: it increases power usage under light load */
    -# define SCHED_LOAD_RESOLUTION 10
    -# define scale_load(w) ((w) << SCHED_LOAD_RESOLUTION)
    -# define scale_load_down(w) ((w) >> SCHED_LOAD_RESOLUTION)
    +# define SCHED_LOAD_SHIFT (SCHED_FIXEDPOINT_SHIFT + SCHED_FIXEDPOINT_SHIFT)
    +# define scale_load(w) ((w) << SCHED_FIXEDPOINT_SHIFT)
    +# define scale_load_down(w) ((w) >> SCHED_FIXEDPOINT_SHIFT)
    #else
    -# define SCHED_LOAD_RESOLUTION 0
    +# define SCHED_LOAD_SHIFT (SCHED_FIXEDPOINT_SHIFT)
    # define scale_load(w) (w)
    # define scale_load_down(w) (w)
    #endif

    -#define SCHED_LOAD_SHIFT (10 + SCHED_LOAD_RESOLUTION)
    #define SCHED_LOAD_SCALE (1L << SCHED_LOAD_SHIFT)

    +/*
    + * NICE_0's weight (visible to user) and its load (invisible to user) have
    + * independent ranges, but they should be well calibrated. We use scale_load()
    + * and scale_load_down(w) to convert between them, the following must be true:
    + * scale_load(sched_prio_to_weight[20]) == NICE_0_LOAD
    + */
    #define NICE_0_LOAD SCHED_LOAD_SCALE
    #define NICE_0_SHIFT SCHED_LOAD_SHIFT

    --
    2.1.4
    \
     
     \ /
      Last update: 2016-04-05 14:21    [W:4.721 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site