Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1494397 > unrolled thread
| Started by | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| First post | 2016-10-01 13:50 +0200 |
| Last post | 2016-10-03 18:50 +0200 |
| Articles | 11 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v5 0/9] Support Intel® Turbo Boost Max Technology 3.0 Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-10-01 13:50 +0200
[PATCH v5 8/9] acpi: bus: Set _OSC for diverse core support Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-10-01 13:50 +0200
[PATCH v5 3/9] x86/topology: Define x86's arch_update_cpu_topology Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-10-01 13:50 +0200
[PATCH v5 4/9] x86: Enable Intel Turbo Boost Max Technology 3.0 Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-10-01 13:50 +0200
Re: [PATCH v5 4/9] x86: Enable Intel Turbo Boost Max Technology 3.0 Thomas Gleixner <tglx@linutronix.de> - 2016-10-05 16:30 +0200
Re: [PATCH v5 4/9] x86: Enable Intel Turbo Boost Max Technology 3.0 Tim Chen <tim.c.chen@linux.intel.com> - 2016-10-05 18:10 +0200
[PATCH v5 6/9] x86/sched: Add SD_ASYM_PACKING flags to x86 ITMT CPU Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-10-01 13:50 +0200
[PATCH v5 2/9] x86/topology: Provide topology_num_packages() Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-10-01 13:50 +0200
[PATCH v5 1/9] sched: Extend scheduler's asym packing Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-10-01 13:50 +0200
Re: [PATCH v5 1/9] sched: Extend scheduler's asym packing Nilay Vaish <nilayvaish@gmail.com> - 2016-10-01 18:40 +0200
Re: [PATCH v5 1/9] sched: Extend scheduler's asym packing Tim Chen <tim.c.chen@linux.intel.com> - 2016-10-03 18:50 +0200
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-10-01 13:50 +0200 |
| Subject | [PATCH v5 0/9] Support Intel® Turbo Boost Max Technology 3.0 |
| Message-ID | <snqXL-7RK-9@gated-at.bofh.it> |
v5:
- Simplify intel_pstate for enabling ITMT feature
- Put x86_sched_itmt_flags related functions under proper
CONFIG_SCHED_MC/SMT flags
- Comment to note that rebuild_sched_domain is not needed after updating
CPU priorities.
- Define sysctl_sched_itmt_enabled to 0 when ITMT is not used in
arch/x86/include/asm/topology.h
- Dropped patch "Fix numa in package topology bug", as this is
already applied
v4:
- Split x86 multi-node numa topology bug fix and setting
of SD_ASYM flag for ITMT topology into 2 patches
- Split the sysctl changes for ITMT enablement and setting of ITMT
capability/core priorities into 2 patches.
- Avoid unnecessary rebuild of sched domains when ITMT sysctl or
capabilities are updated.
- Fix missing stub function for topology_max_packages for !SMP case.
- Rename set_sched_itmt() to sched_set_itmt_support().
- Various updates to itmt.c to eliminate goto and make logic tighter.
- Various change logs and comments update.
- intel_pstate: Split function to process cppc and enable ITMT
- intel_pstate: Just keep the cppc_perf information till we use CPPC for HWP
v3:
- Fix race clash when more than one program are enabling/disabling ITMT
- Remove group_priority_cpu macro to simplify code.
- Error reported by 0-day for compile issue on ARM
v2
- The patchset is split into two parts so that CPPC changes can be merged first
1. Only ACPI CPPC changes (It is posted separately)
2. ITMT changes (scheduler and Intel P-State)
- Changes in patch: sched,x86: Enable Turbo Boost Max Technology
1. Use arch_update_cpu_topology to indicate need to completely
rebuild sched domain when ITMT related sched domain flags change
2. Enable client (single node) platform capable of ITMT with ITMT
scheduling by default
3. Implement arch_asym_cpu_priority to provide the cpu priority
value to scheduler for asym packing.
4. Fix a compile bug for i386 architecture.
- Changes in patch: sched: Extend scheduler's asym packing
1. Use arch_asym_cpu_priority() to provide cpu priority
value used for asym packing to the scheduler.
- Changes in acpi: bus: Enable HWP CPPC objects and
acpi: bus: Set _OSC for diverse core support
Minor code cleanup by removing #ifdef
- Changes in Kconfig for Intel P-State
Avoid building CPPC lib for i386 for issue reported by 0-day
- Feature is enabled by default for single socket systems
With Intel® Turbo Boost Max Technology 3.0 (ITMT), single-threaded performance is
optimized by identifying processor's fastest core and running critical workloads
on it.
Refere to:
http://www.intel.com/content/www/us/en/architecture-and-technology/turbo-boost/turbo-boost-max-technology.html
This patchset consist of all changes required to support ITMT feature:
- Use CPPC information in Intel P-State driver to get performance information
- Scheduler enhancements
- cppc lib patches (split in to a seprate series)
This featured can be enabled by writing at runtime
# echo 1 > /proc/sys/kernel/sched_itmt_enabled
This featured can be disabled by writing at runtime
# echo 0 > /proc/sys/kernel/sched_itmt_enabled
Peter Zijlstra (Intel) (1):
x86/topology: Fix numa in package topology bug
Rafael J. Wysocki (1):
cpufreq: intel_pstate: Use CPPC to get max performance
Srinivas Pandruvada (2):
acpi: bus: Enable HWP CPPC objects
acpi: bus: Set _OSC for diverse core support
Tim Chen (6):
sched: Extend scheduler's asym packing
x86/topology: Provide topology_num_packages()
x86/topology: Define x86's arch_update_cpu_topology
x86: Enable Intel Turbo Boost Max Technology 3.0
x86/sysctl: Add sysctl for ITMT scheduling feature
x86/sched: Add SD_ASYM_PACKING flags to x86 ITMT CPU
arch/x86/Kconfig | 9 ++
arch/x86/include/asm/topology.h | 28 ++++++
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/itmt.c | 189 ++++++++++++++++++++++++++++++++++++++++
arch/x86/kernel/smpboot.c | 44 +++++++++-
drivers/acpi/bus.c | 10 +++
drivers/cpufreq/Kconfig.x86 | 1 +
drivers/cpufreq/intel_pstate.c | 56 +++++++++++-
include/linux/acpi.h | 1 +
include/linux/sched.h | 2 +
kernel/sched/core.c | 18 ++++
kernel/sched/fair.c | 35 +++++---
kernel/sched/sched.h | 6 ++
13 files changed, 384 insertions(+), 16 deletions(-)
create mode 100644 arch/x86/kernel/itmt.c
--
2.7.4
[toc] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-10-01 13:50 +0200 |
| Subject | [PATCH v5 8/9] acpi: bus: Set _OSC for diverse core support |
| Message-ID | <snqXL-7RK-19@gated-at.bofh.it> |
| In reply to | #1494397 |
Set the OSC_SB_CPC_DIVERSE_HIGH_SUPPORT (bit 12) to enable diverse core support. This is required to inform BIOS the support of Intel Turbo Boost Max Technology 3.0 feature. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> --- drivers/acpi/bus.c | 3 +++ include/linux/acpi.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 61643a5..8ab6ec2 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -337,6 +337,9 @@ static void acpi_bus_osc_support(void) } #endif + if (IS_ENABLED(CONFIG_SCHED_ITMT)) + capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_DIVERSE_HIGH_SUPPORT; + if (!ghes_disable) capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT; if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) diff --git a/include/linux/acpi.h b/include/linux/acpi.h index e746552..53841a2 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -462,6 +462,7 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); #define OSC_SB_CPCV2_SUPPORT 0x00000040 #define OSC_SB_PCLPI_SUPPORT 0x00000080 #define OSC_SB_OSLPI_SUPPORT 0x00000100 +#define OSC_SB_CPC_DIVERSE_HIGH_SUPPORT 0x00001000 extern bool osc_sb_apei_support_acked; extern bool osc_pc_lpi_support_confirmed; -- 2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-10-01 13:50 +0200 |
| Subject | [PATCH v5 3/9] x86/topology: Define x86's arch_update_cpu_topology |
| Message-ID | <snqXM-7RK-29@gated-at.bofh.it> |
| In reply to | #1494397 |
From: Tim Chen <tim.c.chen@linux.intel.com>
The scheduler calls arch_update_cpu_topology() to check whether the
scheduler domains have to be rebuilt.
So far x86 has no requirement for this, but the upcoming ITMT support
makes this necessary.
Request the rebuild when the x86 internal update flag is set.
Suggested-by: Morten Rasmussen <morten.rasmussen@arm.com>
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
arch/x86/include/asm/topology.h | 1 +
arch/x86/kernel/smpboot.c | 11 +++++++++++
2 files changed, 12 insertions(+)
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 3e95dfc..323f61f 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -149,4 +149,5 @@ struct pci_bus;
int x86_pci_root_bus_node(int bus);
void x86_pci_root_bus_resources(int bus, struct list_head *resources);
+extern bool x86_topology_update;
#endif /* _ASM_X86_TOPOLOGY_H */
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 6a763a2..38901b3 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -109,6 +109,17 @@ static bool logical_packages_frozen __read_mostly;
/* Maximum number of SMT threads on any online core */
int __max_smt_threads __read_mostly;
+/* Flag to indicate if a complete sched domain rebuild is required */
+bool x86_topology_update;
+
+int arch_update_cpu_topology(void)
+{
+ int retval = x86_topology_update;
+
+ x86_topology_update = false;
+ return retval;
+}
+
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
{
unsigned long flags;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-10-01 13:50 +0200 |
| Subject | [PATCH v5 4/9] x86: Enable Intel Turbo Boost Max Technology 3.0 |
| Message-ID | <snqXM-7RK-33@gated-at.bofh.it> |
| In reply to | #1494397 |
From: Tim Chen <tim.c.chen@linux.intel.com>
On platforms supporting Intel Turbo Boost Max Technology 3.0, the maximum
turbo frequencies of some cores in a CPU package may be higher than for
the other cores in the same package. In that case, better performance
(and possibly lower energy consumption as well) can be achieved by
making the scheduler prefer to run tasks on the CPUs with higher max
turbo frequencies.
To that end, set up a core priority metric to abstract the core
preferences based on the maximum turbo frequency. In that metric,
the cores with higher maximum turbo frequencies are higher-priority
than the other cores in the same package and that causes the scheduler
to favor them when making load-balancing decisions using the asymmertic
packing approach. At the same time, the priority of SMT threads with a
higher CPU number is reduced so as to avoid scheduling tasks on all of
the threads that belong to a favored core before all of the other cores
have been given a task to run.
The priority metric will be initialized by the P-state driver with the
help of the sched_set_itmt_core_prio() function. The P-state driver
will also determine whether or not ITMT is supported by the platform
and will call sched_set_itmt_support() to indicate that.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
arch/x86/Kconfig | 9 ++++
arch/x86/include/asm/topology.h | 22 ++++++++++
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/itmt.c | 95 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 127 insertions(+)
create mode 100644 arch/x86/kernel/itmt.c
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2a1f0ce..6dfb97d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -927,6 +927,15 @@ config SCHED_MC
making when dealing with multi-core CPU chips at a cost of slightly
increased overhead in some places. If unsure say N here.
+config SCHED_ITMT
+ bool "Intel Turbo Boost Max Technology (ITMT) scheduler support"
+ depends on SCHED_MC && CPU_SUP_INTEL && X86_INTEL_PSTATE
+ ---help---
+ ITMT enabled scheduler support improves the CPU scheduler's decision
+ to move tasks to cpu core that can be boosted to a higher frequency
+ than others. It will have better performance at a cost of slightly
+ increased overhead in task migrations. If unsure say N here.
+
source "kernel/Kconfig.preempt"
config UP_LATE_INIT
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 323f61f..637d847 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -150,4 +150,26 @@ int x86_pci_root_bus_node(int bus);
void x86_pci_root_bus_resources(int bus, struct list_head *resources);
extern bool x86_topology_update;
+
+#ifdef CONFIG_SCHED_ITMT
+#include <asm/percpu.h>
+
+DECLARE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
+
+/* 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(bool itmt_supported);
+
+#else /* CONFIG_SCHED_ITMT */
+
+static inline void sched_set_itmt_core_prio(int prio, int core_cpu)
+{
+}
+static inline void sched_set_itmt_support(bool itmt_supported)
+{
+}
+#endif /* CONFIG_SCHED_ITMT */
+
#endif /* _ASM_X86_TOPOLOGY_H */
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0503f5b..2008335 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -124,6 +124,7 @@ obj-$(CONFIG_EFI) += sysfb_efi.o
obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
obj-$(CONFIG_TRACING) += tracepoint.o
+obj-$(CONFIG_SCHED_ITMT) += itmt.o
###
# 64 bit specific files
diff --git a/arch/x86/kernel/itmt.c b/arch/x86/kernel/itmt.c
new file mode 100644
index 0000000..f485b49
--- /dev/null
+++ b/arch/x86/kernel/itmt.c
@@ -0,0 +1,95 @@
+/*
+ * itmt.c: Support Intel Turbo Boost Max Technology 3.0
+ *
+ * (C) Copyright 2016 Intel Corporation
+ * Author: Tim Chen <tim.c.chen@linux.intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ *
+ * On platforms supporting Intel Turbo Boost Max Technology 3.0, (ITMT),
+ * the maximum turbo frequencies of some cores in a CPU package may be
+ * higher than for the other cores in the same package. In that case,
+ * better performance can be achieved by making the scheduler prefer
+ * to run tasks on the CPUs with higher max turbo frequencies.
+ *
+ * This file provides functions and data structures for enabling the
+ * scheduler to favor scheduling on cores can be boosted to a higher
+ * frequency under ITMT.
+ */
+
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/cpuset.h>
+#include <asm/mutex.h>
+#include <linux/sched.h>
+#include <linux/sysctl.h>
+#include <linux/nodemask.h>
+
+static DEFINE_MUTEX(itmt_update_mutex);
+
+/* Boolean to track if system has ITMT capabilities */
+static bool __read_mostly sched_itmt_capable;
+
+/**
+ * sched_set_itmt_support - Indicate platform support ITMT
+ * @itmt_supported: indicate platform's CPU has ITMT capability
+ *
+ * This function is used by the OS to indicate to scheduler if the platform
+ * is capable of supporting the ITMT feature.
+ *
+ * The current scheme has the pstate driver detects if the system
+ * is ITMT capable and call set_sched_itmt.
+ *
+ * This must be done only after sched_set_itmt_core_prio
+ * has been called to set the cpus' priorities.
+ */
+void sched_set_itmt_support(bool itmt_supported)
+{
+ mutex_lock(&itmt_update_mutex);
+
+ if (itmt_supported != sched_itmt_capable)
+ sched_itmt_capable = itmt_supported;
+
+ mutex_unlock(&itmt_update_mutex);
+}
+
+DEFINE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
+int arch_asym_cpu_priority(int cpu)
+{
+ return per_cpu(sched_core_priority, cpu);
+}
+
+/**
+ * sched_set_itmt_core_prio - Set CPU priority based on ITMT
+ * @prio: Priority of cpu core
+ * @core_cpu: The cpu number associated with the core
+ *
+ * The pstate driver will find out the max boost frequency
+ * and call this function to set a priority proportional
+ * to the max boost frequency. CPU with higher boost
+ * frequency will receive higher priority.
+ *
+ * No need to rebuild sched domain after updating
+ * the CPU priorities. The sched domains have no
+ * dependency on CPU priorities.
+ */
+void sched_set_itmt_core_prio(int prio, int core_cpu)
+{
+ int cpu, i = 1;
+
+ for_each_cpu(cpu, topology_sibling_cpumask(core_cpu)) {
+ int smt_prio;
+
+ /*
+ * Ensure that the siblings are moved to the end
+ * of the priority chain and only used when
+ * all other high priority cpus are out of capacity.
+ */
+ smt_prio = prio * smp_num_siblings / i;
+ i++;
+ per_cpu(sched_core_priority, cpu) = smt_prio;
+ }
+}
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Thomas Gleixner <tglx@linutronix.de> |
|---|---|
| Date | 2016-10-05 16:30 +0200 |
| Subject | Re: [PATCH v5 4/9] x86: Enable Intel Turbo Boost Max Technology 3.0 |
| Message-ID | <soVmO-271-5@gated-at.bofh.it> |
| In reply to | #1494400 |
On Sat, 1 Oct 2016, Srinivas Pandruvada wrote:
> +void sched_set_itmt_support(bool itmt_supported)
> +{
> + mutex_lock(&itmt_update_mutex);
> +
> + if (itmt_supported != sched_itmt_capable)
> + sched_itmt_capable = itmt_supported;
Yikes. What is this conditional for? The only value it has is to confuse
the reader.
> +
> + mutex_unlock(&itmt_update_mutex);
> +}
> +
> +DEFINE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
Darn. Do not stick variable definitiions in the middle of the code and
especially not glued to the function w/o a newline in between. Move it to
the top of the file.
> +int arch_asym_cpu_priority(int cpu)
> +{
> + return per_cpu(sched_core_priority, cpu);
> +}
> +void sched_set_itmt_core_prio(int prio, int core_cpu)
> +{
> + int cpu, i = 1;
> +
> + for_each_cpu(cpu, topology_sibling_cpumask(core_cpu)) {
> + int smt_prio;
> +
> + /*
> + * Ensure that the siblings are moved to the end
> + * of the priority chain and only used when
> + * all other high priority cpus are out of capacity.
> + */
> + smt_prio = prio * smp_num_siblings / i;
> + i++;
Your code ordering is really random. What has this i++ to do with the
store? Nothing. It just makes reading the code harder. Just move it below
the store.
> + per_cpu(sched_core_priority, cpu) = smt_prio;
Thanks,
tglx
[toc] | [prev] | [next] | [standalone]
| From | Tim Chen <tim.c.chen@linux.intel.com> |
|---|---|
| Date | 2016-10-05 18:10 +0200 |
| Subject | Re: [PATCH v5 4/9] x86: Enable Intel Turbo Boost Max Technology 3.0 |
| Message-ID | <soWVz-3as-15@gated-at.bofh.it> |
| In reply to | #1495897 |
On Wed, 2016-10-05 at 16:23 +0200, Thomas Gleixner wrote:
> On Sat, 1 Oct 2016, Srinivas Pandruvada wrote:
> >
> > +void sched_set_itmt_support(bool itmt_supported)
> > +{
> > + mutex_lock(&itmt_update_mutex);
> > +
> > + if (itmt_supported != sched_itmt_capable)
> > + sched_itmt_capable = itmt_supported;
> Yikes. What is this conditional for? The only value it has is to confuse
> the reader.
Will remove the check.
>
> >
> > +
> > + mutex_unlock(&itmt_update_mutex);
> > +}
> > +
> > +DEFINE_PER_CPU_READ_MOSTLY(int, sched_core_priority);
> Darn. Do not stick variable definitiions in the middle of the code and
> especially not glued to the function w/o a newline in between. Move it to
> the top of the file.
Will move to top of file.
>
> >
> > +int arch_asym_cpu_priority(int cpu)
> > +{
> > + return per_cpu(sched_core_priority, cpu);
> > +}
>
> >
> > +void sched_set_itmt_core_prio(int prio, int core_cpu)
> > +{
> > + int cpu, i = 1;
> > +
> > + for_each_cpu(cpu, topology_sibling_cpumask(core_cpu)) {
> > + int smt_prio;
> > +
> > + /*
> > + * Ensure that the siblings are moved to the end
> > + * of the priority chain and only used when
> > + * all other high priority cpus are out of capacity.
> > + */
> > + smt_prio = prio * smp_num_siblings / i;
> > + i++;
> Your code ordering is really random. What has this i++ to do with the
> store? Nothing. It just makes reading the code harder. Just move it below
> the store.
Will move it to the end of for loop.
>
> >
> > + per_cpu(sched_core_priority, cpu) = smt_prio;
Thanks.
Tim
[toc] | [prev] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-10-01 13:50 +0200 |
| Subject | [PATCH v5 6/9] x86/sched: Add SD_ASYM_PACKING flags to x86 ITMT CPU |
| Message-ID | <snqXM-7RK-35@gated-at.bofh.it> |
| In reply to | #1494397 |
From: Tim Chen <tim.c.chen@linux.intel.com>
Some Intel cores in a package can be boosted to a higher turbo frequency
with ITMT 3.0 technology. The scheduler can use the asymmetric packing
feature to move tasks to the more capable cores.
If ITMT is enabled, add SD_ASYM_PACKING flag to the thread and core
sched domains to enable asymmetric packing.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
arch/x86/kernel/smpboot.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 38901b3..607cbe6 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -487,22 +487,42 @@ static bool match_die(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
return false;
}
+#if defined(CONFIG_SCHED_SMT) || defined(CONFIG_SCHED_MC)
+static inline int x86_sched_itmt_flags(void)
+{
+ return sysctl_sched_itmt_enabled ? SD_ASYM_PACKING : 0;
+}
+
+#ifdef CONFIG_SCHED_MC
+static int x86_core_flags(void)
+{
+ return cpu_core_flags() | x86_sched_itmt_flags();
+}
+#endif
+#ifdef CONFIG_SCHED_SMT
+static int x86_smt_flags(void)
+{
+ return cpu_smt_flags() | x86_sched_itmt_flags();
+}
+#endif
+#endif
+
static struct sched_domain_topology_level x86_numa_in_package_topology[] = {
#ifdef CONFIG_SCHED_SMT
- { cpu_smt_mask, cpu_smt_flags, SD_INIT_NAME(SMT) },
+ { cpu_smt_mask, x86_smt_flags, SD_INIT_NAME(SMT) },
#endif
#ifdef CONFIG_SCHED_MC
- { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
+ { cpu_coregroup_mask, x86_core_flags, SD_INIT_NAME(MC) },
#endif
{ NULL, },
};
static struct sched_domain_topology_level x86_topology[] = {
#ifdef CONFIG_SCHED_SMT
- { cpu_smt_mask, cpu_smt_flags, SD_INIT_NAME(SMT) },
+ { cpu_smt_mask, x86_smt_flags, SD_INIT_NAME(SMT) },
#endif
#ifdef CONFIG_SCHED_MC
- { cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
+ { cpu_coregroup_mask, x86_core_flags, SD_INIT_NAME(MC) },
#endif
{ cpu_cpu_mask, SD_INIT_NAME(DIE) },
{ NULL, },
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-10-01 13:50 +0200 |
| Subject | [PATCH v5 2/9] x86/topology: Provide topology_num_packages() |
| Message-ID | <snqXM-7RK-37@gated-at.bofh.it> |
| In reply to | #1494397 |
From: Tim Chen <tim.c.chen@linux.intel.com>
Returns number of cpu packages discovered.
This information is needed to determine the size of the platform and
decide if the Intel Turbo Boost Max Technology 3.0 (ITMT) feature
should be turned on by default. The ITMT feature is more effective on
single socket client like system that uses small number of cores most
of the time.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
arch/x86/include/asm/topology.h | 3 +++
arch/x86/kernel/smpboot.c | 5 +++++
2 files changed, 8 insertions(+)
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index cf75871..3e95dfc 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -129,10 +129,13 @@ static inline int topology_max_smt_threads(void)
}
int topology_update_package_map(unsigned int apicid, unsigned int cpu);
+extern int topology_num_packages(void);
extern int topology_phys_to_logical_pkg(unsigned int pkg);
#else
#define topology_max_packages() (1)
static inline int
+topology_num_packages(void) { return 1; }
+static inline int
topology_update_package_map(unsigned int apicid, unsigned int cpu) { return 0; }
static inline int topology_phys_to_logical_pkg(unsigned int pkg) { return 0; }
static inline int topology_max_smt_threads(void) { return 1; }
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 7137ec4..6a763a2 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -295,6 +295,11 @@ found:
return 0;
}
+int topology_num_packages(void)
+{
+ return logical_packages;
+}
+
/**
* topology_phys_to_logical_pkg - Map a physical package id to a logical
*
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-10-01 13:50 +0200 |
| Subject | [PATCH v5 1/9] sched: Extend scheduler's asym packing |
| Message-ID | <snqXM-7RK-39@gated-at.bofh.it> |
| In reply to | #1494397 |
From: Tim Chen <tim.c.chen@linux.intel.com>
We generalize the scheduler's asym packing to provide an ordering
of the cpu beyond just the cpu number. This allows the use of the
ASYM_PACKING scheduler machinery to move loads to preferred CPU in a
sched domain. The preference is defined with the cpu priority
given by arch_asym_cpu_priority(cpu).
We also record the most preferred cpu in a sched group when
we build the cpu's capacity for fast lookup of preferred cpu
during load balancing.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
include/linux/sched.h | 2 ++
kernel/sched/core.c | 18 ++++++++++++++++++
kernel/sched/fair.c | 35 ++++++++++++++++++++++++-----------
kernel/sched/sched.h | 6 ++++++
4 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 98fe95f..82ca1e4 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1052,6 +1052,8 @@ static inline int cpu_numa_flags(void)
}
#endif
+int arch_asym_cpu_priority(int cpu);
+
struct sched_domain_attr {
int relax_domain_level;
};
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e86c4a5..08135ca 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6237,7 +6237,25 @@ static void init_sched_groups_capacity(int cpu, struct sched_domain *sd)
WARN_ON(!sg);
do {
+ int cpu, max_cpu = -1, prev_cpu = -1;
+
sg->group_weight = cpumask_weight(sched_group_cpus(sg));
+
+ if (!(sd->flags & SD_ASYM_PACKING))
+ goto next;
+
+ for_each_cpu(cpu, sched_group_cpus(sg)) {
+ if (prev_cpu < 0) {
+ prev_cpu = cpu;
+ max_cpu = cpu;
+ } else {
+ if (sched_asym_prefer(cpu, max_cpu))
+ max_cpu = cpu;
+ }
+ }
+ sg->asym_prefer_cpu = max_cpu;
+
+next:
sg = sg->next;
} while (sg != sd->groups);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index a5cd07b..bb96e1a 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -100,6 +100,16 @@ const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
*/
unsigned int __read_mostly sysctl_sched_shares_window = 10000000UL;
+#ifdef CONFIG_SMP
+/*
+ * For asym packing, by default the lower numbered cpu has higher priority.
+ */
+int __weak arch_asym_cpu_priority(int cpu)
+{
+ return -cpu;
+}
+#endif
+
#ifdef CONFIG_CFS_BANDWIDTH
/*
* Amount of runtime to allocate from global (tg) to local (per-cfs_rq) pool
@@ -6861,16 +6871,18 @@ static bool update_sd_pick_busiest(struct lb_env *env,
if (env->idle == CPU_NOT_IDLE)
return true;
/*
- * ASYM_PACKING needs to move all the work to the lowest
- * numbered CPUs in the group, therefore mark all groups
- * higher than ourself as busy.
+ * ASYM_PACKING needs to move all the work to the highest
+ * prority CPUs in the group, therefore mark all groups
+ * of lower priority than ourself as busy.
*/
- if (sgs->sum_nr_running && env->dst_cpu < group_first_cpu(sg)) {
+ if (sgs->sum_nr_running &&
+ sched_asym_prefer(env->dst_cpu, sg->asym_prefer_cpu)) {
if (!sds->busiest)
return true;
- /* Prefer to move from highest possible cpu's work */
- if (group_first_cpu(sds->busiest) < group_first_cpu(sg))
+ /* Prefer to move from lowest priority cpu's work */
+ if (sched_asym_prefer(sds->busiest->asym_prefer_cpu,
+ sg->asym_prefer_cpu))
return true;
}
@@ -7022,8 +7034,8 @@ static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds)
if (!sds->busiest)
return 0;
- busiest_cpu = group_first_cpu(sds->busiest);
- if (env->dst_cpu > busiest_cpu)
+ busiest_cpu = sds->busiest->asym_prefer_cpu;
+ if (sched_asym_prefer(busiest_cpu, env->dst_cpu))
return 0;
env->imbalance = DIV_ROUND_CLOSEST(
@@ -7364,10 +7376,11 @@ static int need_active_balance(struct lb_env *env)
/*
* ASYM_PACKING needs to force migrate tasks from busy but
- * higher numbered CPUs in order to pack all tasks in the
- * lowest numbered CPUs.
+ * lower priority CPUs in order to pack all tasks in the
+ * highest priority CPUs.
*/
- if ((sd->flags & SD_ASYM_PACKING) && env->src_cpu > env->dst_cpu)
+ if ((sd->flags & SD_ASYM_PACKING) &&
+ sched_asym_prefer(env->dst_cpu, env->src_cpu))
return 1;
}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index b7fc1ce..3f3d04a 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -532,6 +532,11 @@ struct dl_rq {
#ifdef CONFIG_SMP
+static inline bool sched_asym_prefer(int a, int b)
+{
+ return arch_asym_cpu_priority(a) > arch_asym_cpu_priority(b);
+}
+
/*
* We add the notion of a root-domain which will be used to define per-domain
* variables. Each exclusive cpuset essentially defines an island domain by
@@ -884,6 +889,7 @@ struct sched_group {
unsigned int group_weight;
struct sched_group_capacity *sgc;
+ int asym_prefer_cpu; /* cpu of highest priority in group */
/*
* The CPUs this group covers.
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Nilay Vaish <nilayvaish@gmail.com> |
|---|---|
| Date | 2016-10-01 18:40 +0200 |
| Subject | Re: [PATCH v5 1/9] sched: Extend scheduler's asym packing |
| Message-ID | <snvur-2DD-91@gated-at.bofh.it> |
| In reply to | #1494403 |
On 1 October 2016 at 06:45, Srinivas Pandruvada
<srinivas.pandruvada@linux.intel.com> wrote:
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index e86c4a5..08135ca 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -6237,7 +6237,25 @@ static void init_sched_groups_capacity(int cpu, struct sched_domain *sd)
> WARN_ON(!sg);
>
> do {
> + int cpu, max_cpu = -1, prev_cpu = -1;
> +
> sg->group_weight = cpumask_weight(sched_group_cpus(sg));
> +
> + if (!(sd->flags & SD_ASYM_PACKING))
> + goto next;
> +
> + for_each_cpu(cpu, sched_group_cpus(sg)) {
> + if (prev_cpu < 0) {
> + prev_cpu = cpu;
> + max_cpu = cpu;
It seems that you can drop prev_cpu and put the check on max_cpu instead.
--
Nilay
[toc] | [prev] | [next] | [standalone]
| From | Tim Chen <tim.c.chen@linux.intel.com> |
|---|---|
| Date | 2016-10-03 18:50 +0200 |
| Subject | Re: [PATCH v5 1/9] sched: Extend scheduler's asym packing |
| Message-ID | <soeBb-7qE-21@gated-at.bofh.it> |
| In reply to | #1494438 |
On Sat, Oct 01, 2016 at 11:38:04AM -0500, Nilay Vaish wrote:
> On 1 October 2016 at 06:45, Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com> wrote:
> > diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> > index e86c4a5..08135ca 100644
> > --- a/kernel/sched/core.c
> > +++ b/kernel/sched/core.c
> > @@ -6237,7 +6237,25 @@ static void init_sched_groups_capacity(int cpu, struct sched_domain *sd)
> > WARN_ON(!sg);
> >
> > do {
> > + int cpu, max_cpu = -1, prev_cpu = -1;
> > +
> > sg->group_weight = cpumask_weight(sched_group_cpus(sg));
> > +
> > + if (!(sd->flags & SD_ASYM_PACKING))
> > + goto next;
> > +
> > + for_each_cpu(cpu, sched_group_cpus(sg)) {
> > + if (prev_cpu < 0) {
> > + prev_cpu = cpu;
> > + max_cpu = cpu;
>
> It seems that you can drop prev_cpu and put the check on max_cpu instead.
>
The usage of prev_cpu was an artifact of the evolution of this patch.
It can indeed be dropped and I've updated this change in the patch below.
Thanks.
Tim
--->8---
commit 90955f87f228ee2fe7eeffcab851eb3141a783b4
Author: Tim Chen <tim.c.chen@linux.intel.com>
Subject: [PATCH v5 1/9 update] sched: Extend scheduler's asym packing
sched: Extend scheduler's asym packing
We generalize the scheduler's asym packing to provide an ordering
of the cpu beyond just the cpu number. This allows the use of the
ASYM_PACKING scheduler machinery to move loads to preferred CPU in a
sched domain. The preference is defined with the cpu priority
given by arch_asym_cpu_priority(cpu).
We also record the most preferred cpu in a sched group when
we build the cpu's capacity for fast lookup of preferred cpu
during load balancing.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 62c68e5..aeea288 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1052,6 +1052,8 @@ static inline int cpu_numa_flags(void)
}
#endif
+int arch_asym_cpu_priority(int cpu);
+
struct sched_domain_attr {
int relax_domain_level;
};
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e86c4a5..b2e22de 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6237,7 +6237,22 @@ static void init_sched_groups_capacity(int cpu, struct sched_domain *sd)
WARN_ON(!sg);
do {
+ int cpu, max_cpu = -1;
+
sg->group_weight = cpumask_weight(sched_group_cpus(sg));
+
+ if (!(sd->flags & SD_ASYM_PACKING))
+ goto next;
+
+ for_each_cpu(cpu, sched_group_cpus(sg)) {
+ if (max_cpu < 0)
+ max_cpu = cpu;
+ else if (sched_asym_prefer(cpu, max_cpu))
+ max_cpu = cpu;
+ }
+ sg->asym_prefer_cpu = max_cpu;
+
+next:
sg = sg->next;
} while (sg != sd->groups);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 039de34..8e2a078 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -100,6 +100,16 @@ const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
*/
unsigned int __read_mostly sysctl_sched_shares_window = 10000000UL;
+#ifdef CONFIG_SMP
+/*
+ * For asym packing, by default the lower numbered cpu has higher priority.
+ */
+int __weak arch_asym_cpu_priority(int cpu)
+{
+ return -cpu;
+}
+#endif
+
#ifdef CONFIG_CFS_BANDWIDTH
/*
* Amount of runtime to allocate from global (tg) to local (per-cfs_rq) pool
@@ -6862,16 +6872,18 @@ static bool update_sd_pick_busiest(struct lb_env *env,
if (env->idle == CPU_NOT_IDLE)
return true;
/*
- * ASYM_PACKING needs to move all the work to the lowest
- * numbered CPUs in the group, therefore mark all groups
- * higher than ourself as busy.
+ * ASYM_PACKING needs to move all the work to the highest
+ * prority CPUs in the group, therefore mark all groups
+ * of lower priority than ourself as busy.
*/
- if (sgs->sum_nr_running && env->dst_cpu < group_first_cpu(sg)) {
+ if (sgs->sum_nr_running &&
+ sched_asym_prefer(env->dst_cpu, sg->asym_prefer_cpu)) {
if (!sds->busiest)
return true;
- /* Prefer to move from highest possible cpu's work */
- if (group_first_cpu(sds->busiest) < group_first_cpu(sg))
+ /* Prefer to move from lowest priority cpu's work */
+ if (sched_asym_prefer(sds->busiest->asym_prefer_cpu,
+ sg->asym_prefer_cpu))
return true;
}
@@ -7023,8 +7035,8 @@ static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds)
if (!sds->busiest)
return 0;
- busiest_cpu = group_first_cpu(sds->busiest);
- if (env->dst_cpu > busiest_cpu)
+ busiest_cpu = sds->busiest->asym_prefer_cpu;
+ if (sched_asym_prefer(busiest_cpu, env->dst_cpu))
return 0;
env->imbalance = DIV_ROUND_CLOSEST(
@@ -7365,10 +7377,11 @@ static int need_active_balance(struct lb_env *env)
/*
* ASYM_PACKING needs to force migrate tasks from busy but
- * higher numbered CPUs in order to pack all tasks in the
- * lowest numbered CPUs.
+ * lower priority CPUs in order to pack all tasks in the
+ * highest priority CPUs.
*/
- if ((sd->flags & SD_ASYM_PACKING) && env->src_cpu > env->dst_cpu)
+ if ((sd->flags & SD_ASYM_PACKING) &&
+ sched_asym_prefer(env->dst_cpu, env->src_cpu))
return 1;
}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index c64fc51..b6f449d 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -532,6 +532,11 @@ struct dl_rq {
#ifdef CONFIG_SMP
+static inline bool sched_asym_prefer(int a, int b)
+{
+ return arch_asym_cpu_priority(a) > arch_asym_cpu_priority(b);
+}
+
/*
* We add the notion of a root-domain which will be used to define per-domain
* variables. Each exclusive cpuset essentially defines an island domain by
@@ -884,6 +889,7 @@ struct sched_group {
unsigned int group_weight;
struct sched_group_capacity *sgc;
+ int asym_prefer_cpu; /* cpu of highest priority in group */
/*
* The CPUs this group covers.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web