[RFC,v2,3/8] sched/fair: add function to convert boost value into "margin"

Message ID 20161027174108.31139-4-patrick.bellasi@arm.com
State New
Headers show

Commit Message

Patrick Bellasi Oct. 27, 2016, 5:41 p.m.
The basic idea of the boost knob is to "artificially inflate" a signal
to make a task (or CPU) appears more demanding than what actually it is.

Independently from the specific signal, a consistent and possibly
simple semantic for the concept of "signal boosting" must define:
1. how we translate a boost percentage into a "margin" value,
   to be added to the original signal we want to inflate
2. what is the meaning of a boost value from a user-space perspective

This patch provides the implementation of a possible boost semantic,
namely "Signal Proportional Compensation" (SPC), where the "Boost
Percentage" (BP) is used to compute a "Margin" (M) which is proportional
to the complement of the "Original Signal" (OS):

  M = BP * (SCHED_CAPACITY_SCALE - OS)

The computed margin can added to the OS to obtain a "Boosted Signal" (BS)

  BS = OS + M

The proposed boost semantic has these main features:
- each signal gets a boost which is proportional to its delta with respect
  to the maximum available capacity in the system,
  i.e. SCHED_CAPACITY_SCALE
- a 100% boosting has a clear understanding from a user-space perspective,
  it means to run (possibly) "all" tasks at the maximum OPP
- each boosting value means to speedup the task by a quantity
  which is proportional to the maximum speedup achievable by that
  task on that system

Thus this semantics is somehow forcing a behaviour which is:

  50% boosting means to run at half-way between the current and the
    maximum performance which a task could achieve on that system

NOTE: this code is suitable for all signals operating in range
      [0..SCHED_CAPACITY_SCALE]

Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com>

---
 kernel/sched/fair.c | 37 +++++++++++++++++++++++++++++++++++++
 kernel/sched/tune.c |  9 +++++++++
 kernel/sched/tune.h | 13 +++++++++++++
 3 files changed, 59 insertions(+)
 create mode 100644 kernel/sched/tune.h

-- 
2.10.1

Patch

diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 79d464a..fdacc29 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -34,6 +34,7 @@ 
 #include <trace/events/sched.h>
 
 #include "sched.h"
+#include "tune.h"
 
 /*
  * Targeted preemption latency for CPU-bound tasks:
@@ -5543,6 +5544,42 @@  static int select_idle_sibling(struct task_struct *p, int prev, int target)
 	return target;
 }
 
+#ifdef CONFIG_SCHED_TUNE
+
+struct reciprocal_value schedtune_spc_rdiv;
+
+/*
+ * schedtune_margin returns the "margin" to be added on top of
+ * the original value of a "signal".
+ *
+ * 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_CAPACITY_SCALE - S)
+ *
+ * The obtained value M could be used by the caller to "boost" S.
+ */
+static unsigned long
+schedtune_margin(unsigned long signal, unsigned int boost)
+{
+	unsigned long long margin = 0;
+
+	/* Do not boost saturated signals */
+	if (signal >= SCHED_CAPACITY_SCALE)
+		return 0UL;
+
+	/* Signal Proportional Compensation (SPC) */
+	margin = SCHED_CAPACITY_SCALE - signal;
+	if (boost < 100) {
+		margin *= boost;
+		margin  = reciprocal_divide(margin, schedtune_spc_rdiv);
+	}
+
+	return margin;
+}
+
+#endif /* CONFIG_SCHED_TUNE */
+
 /*
  * cpu_util returns the amount of capacity of a CPU that is used by CFS
  * tasks. The unit of the return value must be the one of capacity so we can
diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c
index 7336118..c28a06f 100644
--- a/kernel/sched/tune.c
+++ b/kernel/sched/tune.c
@@ -5,6 +5,7 @@ 
  */
 
 #include "sched.h"
+#include "tune.h"
 
 unsigned int sysctl_sched_cfs_boost __read_mostly;
 
@@ -21,3 +22,11 @@  sysctl_sched_cfs_boost_handler(struct ctl_table *table, int write,
 	return 0;
 }
 
+static int
+schedtune_init(void)
+{
+	schedtune_spc_rdiv = reciprocal_value(100);
+	return 0;
+}
+late_initcall(schedtune_init);
+
diff --git a/kernel/sched/tune.h b/kernel/sched/tune.h
new file mode 100644
index 0000000..515d02a
--- /dev/null
+++ b/kernel/sched/tune.h
@@ -0,0 +1,13 @@ 
+/*
+ * Scheduler Tunability (SchedTune) Extensions for CFS
+ *
+ * Copyright (C) 2016 ARM Ltd, Patrick Bellasi <patrick.bellasi@arm.com>
+ */
+
+#ifdef CONFIG_SCHED_TUNE
+
+#include <linux/reciprocal_div.h>
+
+extern struct reciprocal_value schedtune_spc_rdiv;
+
+#endif /* CONFIG_SCHED_TUNE */