sched/tune: Add support for negative boost values
authorSrinath Sridharan <srinathsr@google.com>
Thu, 28 Jul 2016 16:28:55 +0000 (17:28 +0100)
committerAmit Pundir <amit.pundir@linaro.org>
Wed, 14 Sep 2016 09:29:32 +0000 (14:59 +0530)
Change-Id: I164ee04ba98c3a776605f18cb65ee61b3e917939

Contains also:

eas/stune: schedtune cpu boost_max must be non-negative.

This is to avoid under-accounting cpu capacity which may
cause task stacking and frequency spikes.

Change-Id: Ie1c1cbd52a6edb77b4c15a830030aa748dff6f29

include/trace/events/sched.h
kernel/sched/fair.c
kernel/sched/tune.c

index 11898fb48c0130f95d6dab089052adae97cc3ed7..debcf417c535a69f4e8954e7ad354e1b647977f2 100644 (file)
@@ -731,14 +731,14 @@ TRACE_EVENT(sched_tune_config,
  */
 TRACE_EVENT(sched_boost_cpu,
 
-       TP_PROTO(int cpu, unsigned long util, unsigned long margin),
+       TP_PROTO(int cpu, unsigned long util, long margin),
 
        TP_ARGS(cpu, util, margin),
 
        TP_STRUCT__entry(
                __field( int,           cpu                     )
                __field( unsigned long, util                    )
-               __field( unsigned long, margin                  )
+               __field(long,           margin                  )
        ),
 
        TP_fast_assign(
@@ -747,7 +747,7 @@ TRACE_EVENT(sched_boost_cpu,
                __entry->margin = margin;
        ),
 
-       TP_printk("cpu=%d util=%lu margin=%lu",
+       TP_printk("cpu=%d util=%lu margin=%ld",
                  __entry->cpu,
                  __entry->util,
                  __entry->margin)
@@ -759,7 +759,7 @@ TRACE_EVENT(sched_boost_cpu,
 TRACE_EVENT(sched_tune_tasks_update,
 
        TP_PROTO(struct task_struct *tsk, int cpu, int tasks, int idx,
-               unsigned int boost, unsigned int max_boost),
+               int boost, int max_boost),
 
        TP_ARGS(tsk, cpu, tasks, idx, boost, max_boost),
 
@@ -769,8 +769,8 @@ TRACE_EVENT(sched_tune_tasks_update,
                __field( int,           cpu             )
                __field( int,           tasks           )
                __field( int,           idx             )
-               __field( unsigned int,  boost           )
-               __field( unsigned int,  max_boost       )
+               __field( int,           boost           )
+               __field( int,           max_boost       )
        ),
 
        TP_fast_assign(
@@ -784,7 +784,7 @@ TRACE_EVENT(sched_tune_tasks_update,
        ),
 
        TP_printk("pid=%d comm=%s "
-                       "cpu=%d tasks=%d idx=%d boost=%u max_boost=%u",
+                       "cpu=%d tasks=%d idx=%d boost=%d max_boost=%d",
                __entry->pid, __entry->comm,
                __entry->cpu, __entry->tasks, __entry->idx,
                __entry->boost, __entry->max_boost)
@@ -820,7 +820,7 @@ TRACE_EVENT(sched_tune_boostgroup_update,
  */
 TRACE_EVENT(sched_boost_task,
 
-       TP_PROTO(struct task_struct *tsk, unsigned long util, unsigned long margin),
+       TP_PROTO(struct task_struct *tsk, unsigned long util, long margin),
 
        TP_ARGS(tsk, util, margin),
 
@@ -828,7 +828,7 @@ TRACE_EVENT(sched_boost_task,
                __array( char,  comm,   TASK_COMM_LEN           )
                __field( pid_t,         pid                     )
                __field( unsigned long, util                    )
-               __field( unsigned long, margin                  )
+               __field( long,          margin                  )
 
        ),
 
@@ -839,7 +839,7 @@ TRACE_EVENT(sched_boost_task,
                __entry->margin = margin;
        ),
 
-       TP_printk("comm=%s pid=%d util=%lu margin=%lu",
+       TP_printk("comm=%s pid=%d util=%lu margin=%ld",
                  __entry->comm, __entry->pid,
                  __entry->util,
                  __entry->margin)
index f8f5529dcae8d0ac92c2721ee80be1ed4952e1a6..a3e6fa63be4dc97575fe9e628f9491663d86bf1e 100644 (file)
@@ -5271,22 +5271,25 @@ static bool cpu_overutilized(int cpu)
 
 #ifdef CONFIG_SCHED_TUNE
 
-static unsigned long
-schedtune_margin(unsigned long signal, unsigned long boost)
+static long
+schedtune_margin(unsigned long signal, long boost)
 {
-       unsigned long long margin = 0;
+       long long margin = 0;
 
        /*
         * Signal proportional compensation (SPC)
         *
         * The Boost (B) value is used to compute a Margin (M) which is
         * proportional to the complement of the original Signal (S):
-        *   M = B * (SCHED_LOAD_SCALE - S)
+        *   M = B * (SCHED_LOAD_SCALE - S), if B is positive
+        *   M = B * S, if B is negative
         * The obtained M could be used by the caller to "boost" S.
         */
-       margin  = SCHED_LOAD_SCALE - signal;
-       margin *= boost;
-
+       if (boost >= 0) {
+               margin  = SCHED_LOAD_SCALE - signal;
+               margin *= boost;
+       } else
+               margin = -signal * boost;
        /*
         * Fast integer division by constant:
         *  Constant   :                 (C) = 100
@@ -5302,13 +5305,15 @@ schedtune_margin(unsigned long signal, unsigned long boost)
        margin  *= 1311;
        margin >>= 17;
 
+       if (boost < 0)
+               margin *= -1;
        return margin;
 }
 
-static inline unsigned int
+static inline int
 schedtune_cpu_margin(unsigned long util, int cpu)
 {
-       unsigned int boost;
+       int boost;
 
 #ifdef CONFIG_CGROUP_SCHEDTUNE
        boost = schedtune_cpu_boost(cpu);
@@ -5321,12 +5326,12 @@ schedtune_cpu_margin(unsigned long util, int cpu)
        return schedtune_margin(util, boost);
 }
 
-static inline unsigned long
+static inline long
 schedtune_task_margin(struct task_struct *task)
 {
-       unsigned int boost;
+       int boost;
        unsigned long util;
-       unsigned long margin;
+       long margin;
 
 #ifdef CONFIG_CGROUP_SCHEDTUNE
        boost = schedtune_task_boost(task);
@@ -5344,13 +5349,13 @@ schedtune_task_margin(struct task_struct *task)
 
 #else /* CONFIG_SCHED_TUNE */
 
-static inline unsigned int
+static inline int
 schedtune_cpu_margin(unsigned long util, int cpu)
 {
        return 0;
 }
 
-static inline unsigned int
+static inline int
 schedtune_task_margin(struct task_struct *task)
 {
        return 0;
@@ -5362,7 +5367,7 @@ static inline unsigned long
 boosted_cpu_util(int cpu)
 {
        unsigned long util = cpu_util(cpu);
-       unsigned long margin = schedtune_cpu_margin(util, cpu);
+       long margin = schedtune_cpu_margin(util, cpu);
 
        trace_sched_boost_cpu(cpu, util, margin);
 
@@ -5373,7 +5378,7 @@ static inline unsigned long
 boosted_task_util(struct task_struct *task)
 {
        unsigned long util = task_util(task);
-       unsigned long margin = schedtune_task_margin(task);
+       long margin = schedtune_task_margin(task);
 
        trace_sched_boost_task(task, util, margin);
 
index 8ca8db2de818322f672af067b768bc0fc59ed86e..afc4a774716103c7e7ffbecf19d2909febec9ba9 100644 (file)
@@ -213,10 +213,11 @@ static struct schedtune *allocated_group[BOOSTGROUPS_COUNT] = {
  */
 struct boost_groups {
        /* Maximum boost value for all RUNNABLE tasks on a CPU */
-       unsigned boost_max;
+       bool idle;
+       int boost_max;
        struct {
                /* The boost for tasks on that boost group */
-               unsigned boost;
+               int boost;
                /* Count of RUNNABLE tasks on that boost group */
                unsigned tasks;
        } group[BOOSTGROUPS_COUNT];
@@ -229,7 +230,7 @@ static void
 schedtune_cpu_update(int cpu)
 {
        struct boost_groups *bg;
-       unsigned boost_max;
+       int boost_max;
        int idx;
 
        bg = &per_cpu(cpu_boost_groups, cpu);
@@ -243,9 +244,13 @@ schedtune_cpu_update(int cpu)
                 */
                if (bg->group[idx].tasks == 0)
                        continue;
+
                boost_max = max(boost_max, bg->group[idx].boost);
        }
-
+       /* Ensures boost_max is non-negative when all cgroup boost values
+        * are neagtive. Avoids under-accounting of cpu capacity which may cause
+        * task stacking and frequency spikes.*/
+       boost_max = max(boost_max, 0);
        bg->boost_max = boost_max;
 }
 
@@ -391,7 +396,7 @@ int schedtune_task_boost(struct task_struct *p)
        return task_boost;
 }
 
-static u64
+static s64
 boost_read(struct cgroup_subsys_state *css, struct cftype *cft)
 {
        struct schedtune *st = css_st(css);
@@ -401,11 +406,13 @@ boost_read(struct cgroup_subsys_state *css, struct cftype *cft)
 
 static int
 boost_write(struct cgroup_subsys_state *css, struct cftype *cft,
-           u64 boost)
+           s64 boost)
 {
        struct schedtune *st = css_st(css);
+       unsigned threshold_idx;
+       int boost_pct;
 
-       if (boost < 0 || boost > 100)
+       if (boost < -100 || boost > 100)
                return -EINVAL;
 
        st->boost = boost;
@@ -423,8 +430,8 @@ boost_write(struct cgroup_subsys_state *css, struct cftype *cft,
 static struct cftype files[] = {
        {
                .name = "boost",
-               .read_u64 = boost_read,
-               .write_u64 = boost_write,
+               .read_s64 = boost_read,
+               .write_s64 = boost_write,
        },
        { }     /* terminate */
 };