diff mbox

[v8,4/8] x86/sysctl: Add sysctl for ITMT scheduling feature

Message ID 07cc62426a28bad57b01ab16bb903a9c84fa5421.1479844244.git.tim.c.chen@linux.intel.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Tim Chen Nov. 22, 2016, 8:23 p.m. UTC
Intel Turbo Boost Max Technology 3.0 (ITMT) feature
allows some cores to be boosted to higher turbo
frequency than others.

Add /proc/sys/kernel/sched_itmt_enabled so operator
can enable/disable scheduling of tasks that favor cores
with higher turbo boost frequency potential.

By default, system that is ITMT capable and single
socket has this feature turned on.  It is more likely
to be lightly loaded and operates in Turbo range.

When there is a change in the ITMT scheduling operation
desired, a rebuild of the sched domain is initiated
so the scheduler can set up sched domains with appropriate
flag to enable/disable ITMT scheduling operations.

Co-developed-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Co-developed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
---
 arch/x86/include/asm/topology.h |   7 ++-
 arch/x86/kernel/itmt.c          | 108 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 112 insertions(+), 3 deletions(-)

Comments

Borislav Petkov Nov. 28, 2016, 8:56 a.m. UTC | #1
On Tue, Nov 22, 2016 at 12:23:56PM -0800, Tim Chen wrote:
> Intel Turbo Boost Max Technology 3.0 (ITMT) feature
> allows some cores to be boosted to higher turbo
> frequency than others.
> 
> Add /proc/sys/kernel/sched_itmt_enabled so operator
> can enable/disable scheduling of tasks that favor cores
> with higher turbo boost frequency potential.
> 
> By default, system that is ITMT capable and single
> socket has this feature turned on.  It is more likely
> to be lightly loaded and operates in Turbo range.
> 
> When there is a change in the ITMT scheduling operation
> desired, a rebuild of the sched domain is initiated
> so the scheduler can set up sched domains with appropriate
> flag to enable/disable ITMT scheduling operations.
> 
> Co-developed-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> Co-developed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
> ---
>  arch/x86/include/asm/topology.h |   7 ++-
>  arch/x86/kernel/itmt.c          | 108 +++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 112 insertions(+), 3 deletions(-)

...

> +/*
> + * Boolean to control whether we want to move processes to cpu capable
> + * of higher turbo frequency for cpus supporting Intel Turbo Boost Max
> + * Technology 3.0.
> + *
> + * It can be set via /proc/sys/kernel/sched_itmt_enabled
> + */
> +unsigned int __read_mostly sysctl_sched_itmt_enabled;

Err, can we not have the boolean in the name itself?

I.e., have it called sysctl_sched_itmt and 1 means enabled and 0
disabled? I.e., the classic thing. :)

Ditto for the sysctl name?
Tim Chen Nov. 29, 2016, 5:30 p.m. UTC | #2
On Mon, 2016-11-28 at 09:56 +0100, Borislav Petkov wrote:
> On Tue, Nov 22, 2016 at 12:23:56PM -0800, Tim Chen wrote:
> > 
> > Intel Turbo Boost Max Technology 3.0 (ITMT) feature
> > allows some cores to be boosted to higher turbo
> > frequency than others.
> > 
> > Add /proc/sys/kernel/sched_itmt_enabled so operator
> > can enable/disable scheduling of tasks that favor cores
> > with higher turbo boost frequency potential.
> > 
> > By default, system that is ITMT capable and single
> > socket has this feature turned on.  It is more likely
> > to be lightly loaded and operates in Turbo range.
> > 
> > When there is a change in the ITMT scheduling operation
> > desired, a rebuild of the sched domain is initiated
> > so the scheduler can set up sched domains with appropriate
> > flag to enable/disable ITMT scheduling operations.
> > 
> > Co-developed-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> > Co-developed-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> > Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
> > ---
> >  arch/x86/include/asm/topology.h |   7 ++-
> >  arch/x86/kernel/itmt.c          | 108 +++++++++++++++++++++++++++++++++++++++-
> >  2 files changed, 112 insertions(+), 3 deletions(-)
> ...
> 
> > 
> > +/*
> > + * Boolean to control whether we want to move processes to cpu capable
> > + * of higher turbo frequency for cpus supporting Intel Turbo Boost Max
> > + * Technology 3.0.
> > + *
> > + * It can be set via /proc/sys/kernel/sched_itmt_enabled
> > + */sched_autogroup_enabled
> > +unsigned int __read_mostly sysctl_sched_itmt_enabled;
> Err, can we not have the boolean in the name itself?
> 
> I.e., have it called sysctl_sched_itmt and 1 means enabled and 0
> disabled? I.e., the classic thing. :)
> 
> Ditto for the sysctl name?

I am following the convention in /proc/sys/kernel/sched_autogroup_enabled
and sysctl_sched_autogroup_enabled that's also in /proc/sys/kernel.

Thanks.

Tim

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Borislav Petkov Nov. 29, 2016, 5:51 p.m. UTC | #3
On Tue, Nov 29, 2016 at 09:30:49AM -0800, Tim Chen wrote:
> I am following the convention in /proc/sys/kernel/sched_autogroup_enabled
> and sysctl_sched_autogroup_enabled that's also in /proc/sys/kernel.

That's hardly a convention to me:

$ ls -l /proc/sys/kernel/*abled
-rw-r--r-- 1 root root 0 Nov 29 18:47 /proc/sys/kernel/ftrace_enabled
-rw-r--r-- 1 root root 0 Nov 29 18:47 /proc/sys/kernel/kexec_load_disabled
-rw-r--r-- 1 root root 0 Nov 29 18:47 /proc/sys/kernel/modules_disabled

enabled, disabled, ...
diff mbox

Patch

diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 8ace951..4813df5 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -152,23 +152,26 @@  extern bool x86_topology_update;
 #include <asm/percpu.h>
 
 DECLARE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
+extern unsigned int __read_mostly sysctl_sched_itmt_enabled;
 
 /* Interface to set priority of a cpu */
 void sched_set_itmt_core_prio(int prio, int core_cpu);
 
 /* Interface to notify scheduler that system supports ITMT */
-void sched_set_itmt_support(void);
+int sched_set_itmt_support(void);
 
 /* Interface to notify scheduler that system revokes ITMT support */
 void sched_clear_itmt_support(void);
 
 #else /* CONFIG_SCHED_ITMT */
 
+#define sysctl_sched_itmt_enabled	0
 static inline void sched_set_itmt_core_prio(int prio, int core_cpu)
 {
 }
-static inline void sched_set_itmt_support(void)
+static inline int sched_set_itmt_support(void)
 {
+	return 0;
 }
 static inline void sched_clear_itmt_support(void)
 {
diff --git a/arch/x86/kernel/itmt.c b/arch/x86/kernel/itmt.c
index 63c9b3e..672fbf7 100644
--- a/arch/x86/kernel/itmt.c
+++ b/arch/x86/kernel/itmt.c
@@ -34,6 +34,68 @@  DEFINE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
 /* Boolean to track if system has ITMT capabilities */
 static bool __read_mostly sched_itmt_capable;
 
+/*
+ * Boolean to control whether we want to move processes to cpu capable
+ * of higher turbo frequency for cpus supporting Intel Turbo Boost Max
+ * Technology 3.0.
+ *
+ * It can be set via /proc/sys/kernel/sched_itmt_enabled
+ */
+unsigned int __read_mostly sysctl_sched_itmt_enabled;
+
+static int sched_itmt_update_handler(struct ctl_table *table, int write,
+				     void __user *buffer, size_t *lenp,
+				     loff_t *ppos)
+{
+	unsigned int old_sysctl;
+	int ret;
+
+	mutex_lock(&itmt_update_mutex);
+
+	if (!sched_itmt_capable) {
+		mutex_unlock(&itmt_update_mutex);
+		return -EINVAL;
+	}
+
+	old_sysctl = sysctl_sched_itmt_enabled;
+	ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+
+	if (!ret && write && old_sysctl != sysctl_sched_itmt_enabled) {
+		x86_topology_update = true;
+		rebuild_sched_domains();
+	}
+
+	mutex_unlock(&itmt_update_mutex);
+
+	return ret;
+}
+
+static unsigned int zero;
+static unsigned int one = 1;
+static struct ctl_table itmt_kern_table[] = {
+	{
+		.procname	= "sched_itmt_enabled",
+		.data		= &sysctl_sched_itmt_enabled,
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= sched_itmt_update_handler,
+		.extra1		= &zero,
+		.extra2		= &one,
+	},
+	{}
+};
+
+static struct ctl_table itmt_root_table[] = {
+	{
+		.procname	= "kernel",
+		.mode		= 0555,
+		.child		= itmt_kern_table,
+	},
+	{}
+};
+
+static struct ctl_table_header *itmt_sysctl_header;
+
 /**
  * sched_set_itmt_support() - Indicate platform supports ITMT
  *
@@ -45,14 +107,39 @@  static bool __read_mostly sched_itmt_capable;
  *
  * This must be done only after sched_set_itmt_core_prio
  * has been called to set the cpus' priorities.
+ * It must not be called with cpu hot plug lock
+ * held as we need to acquire the lock to rebuild sched domains
+ * later.
+ *
+ * Return: 0 on success
  */
-void sched_set_itmt_support(void)
+int sched_set_itmt_support(void)
 {
 	mutex_lock(&itmt_update_mutex);
 
+	if (sched_itmt_capable) {
+		mutex_unlock(&itmt_update_mutex);
+		return 0;
+	}
+
+	itmt_sysctl_header = register_sysctl_table(itmt_root_table);
+	if (!itmt_sysctl_header) {
+		mutex_unlock(&itmt_update_mutex);
+		return -ENOMEM;
+	}
+
 	sched_itmt_capable = true;
 
+	sysctl_sched_itmt_enabled = 1;
+
+	if (sysctl_sched_itmt_enabled) {
+		x86_topology_update = true;
+		rebuild_sched_domains();
+	}
+
 	mutex_unlock(&itmt_update_mutex);
+
+	return 0;
 }
 
 /**
@@ -61,13 +148,32 @@  void sched_set_itmt_support(void)
  * This function is used by the OS to indicate that it has
  * revoked the platform's support of ITMT feature.
  *
+ * It must not be called with cpu hot plug lock
+ * held as we need to acquire the lock to rebuild sched domains
+ * later.
  */
 void sched_clear_itmt_support(void)
 {
 	mutex_lock(&itmt_update_mutex);
 
+	if (!sched_itmt_capable) {
+		mutex_unlock(&itmt_update_mutex);
+		return;
+	}
 	sched_itmt_capable = false;
 
+	if (itmt_sysctl_header) {
+		unregister_sysctl_table(itmt_sysctl_header);
+		itmt_sysctl_header = NULL;
+	}
+
+	if (sysctl_sched_itmt_enabled) {
+		/* disable sched_itmt if we are no longer ITMT capable */
+		sysctl_sched_itmt_enabled = 0;
+		x86_topology_update = true;
+		rebuild_sched_domains();
+	}
+
 	mutex_unlock(&itmt_update_mutex);
 }