mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Fenghua Yu <fenghua.yu@intel.com>
To: "Thomas Gleixner" <tglx@linutronix.de>,
	"Ingo Molnar" <mingo@redhat.com>, "H Peter Anvin" <hpa@zytor.com>
Cc: "Ashok Raj" <ashok.raj@intel.com>,
	"Alan Cox" <alan@linux.intel.com>,
	"Ravi V Shankar" <ravi.v.shankar@intel.com>,
	"linux-kernel" <linux-kernel@vger.kernel.org>,
	"x86" <x86@kernel.org>, Fenghua Yu <fenghua.yu@intel.com>
Subject: [RFC PATCH 4/8] cpuidle: Set up maximum umwait time and umwait states
Date: Fri, 15 Jun 2018 20:06:11 -0700	[thread overview]
Message-ID: <1529118375-90191-5-git-send-email-fenghua.yu@intel.com> (raw)
In-Reply-To: <1529118375-90191-1-git-send-email-fenghua.yu@intel.com>

UMWAIT or TPAUSE called by user process makes processor to reside in
a light-weight power/performance optimized state (C0.1 state) or an
improved power/performance optimized state (C0.2 state).

IA32_UMAIT_CONTROL MSR register control allows OS to set maximum umwait
time and disable C0.2 on the processor.

The maximum time value in IA32_UMWAIT_CONTROL[31-2] is set as zero which
means there is no global time limit for UMWAIT and TPAUSE instructions.
Each process sets its own umwait maximum time as the instructions operand.
We don't set a non-zero global umwait maximum time value to enforce user
wait timeout because we couldn't find any usage for it.

By default C0.2 is enabled so user wait can save more power but wakeup
time is slower. In some cases e.g. real time, user wants to disable C0.2
so that user wait saves less power but wakeup time is faster.

A new "/sys/devices/system/cpu/cpuidle/umwait_disable_c0_2" file is
created to allow user to check if C0.2 is enabled or disabled and also
allow user to enable or disable C0.2. Value "1" in the file means C0.2 is
disabled. Value "0" means C0.2 is enabled.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
 arch/x86/include/asm/msr-index.h |   4 ++
 arch/x86/power/Makefile          |   1 +
 arch/x86/power/umwait.c          | 106 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 111 insertions(+)
 create mode 100644 arch/x86/power/umwait.c

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 68b2c3150de1..92ef30f0f62d 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -58,6 +58,10 @@
 #define MSR_PLATFORM_INFO_CPUID_FAULT_BIT	31
 #define MSR_PLATFORM_INFO_CPUID_FAULT		BIT_ULL(MSR_PLATFORM_INFO_CPUID_FAULT_BIT)
 
+#define MSR_IA32_UMWAIT_CONTROL		0xe1
+#define UMWAIT_CONTROL_C02_BIT		0x0
+#define UMWAIT_CONTROL_C02_MASK		0x00000001
+
 #define MSR_PKG_CST_CONFIG_CONTROL	0x000000e2
 #define NHM_C3_AUTO_DEMOTE		(1UL << 25)
 #define NHM_C1_AUTO_DEMOTE		(1UL << 26)
diff --git a/arch/x86/power/Makefile b/arch/x86/power/Makefile
index a4701389562c..d3dfa8a47983 100644
--- a/arch/x86/power/Makefile
+++ b/arch/x86/power/Makefile
@@ -8,3 +8,4 @@ CFLAGS_cpu.o	:= $(nostackp)
 
 obj-$(CONFIG_PM_SLEEP)		+= cpu.o
 obj-$(CONFIG_HIBERNATION)	+= hibernate_$(BITS).o hibernate_asm_$(BITS).o
+obj-y				+= umwait.o
diff --git a/arch/x86/power/umwait.c b/arch/x86/power/umwait.c
new file mode 100644
index 000000000000..fd7b18d9ed02
--- /dev/null
+++ b/arch/x86/power/umwait.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * umwait.c - control user wait
+ *
+ * Copyright (c) 2018, Intel Corporation.
+ * Fenghua Yu <fenghua.yu@intel.com>
+ */
+/*
+ * umwait.c adds control of user wait states that user enters through user wait
+ * instructions umwait or tpause.
+ */
+#include <linux/cpu.h>
+#include <asm/msr.h>
+
+static int umwait_disable_c0_2;
+static DEFINE_MUTEX(umwait_lock);
+
+static ssize_t umwait_disable_c0_2_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	return sprintf(buf, "%d\n", umwait_disable_c0_2);
+}
+
+static ssize_t umwait_disable_c0_2_store(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
+{
+	int disable_c0_2, cpu, ret;
+	u32 msr_val;
+
+	ret = kstrtou32(buf, 10, &disable_c0_2);
+	if (ret)
+		return ret;
+	if (disable_c0_2 != 1 && disable_c0_2 != 0)
+		return -EINVAL;
+
+	mutex_lock(&umwait_lock);
+	umwait_disable_c0_2 = disable_c0_2;
+	/*
+	 * No global umwait maximum time limit (0 in bits 31-0).
+	 * Enable or disable C0.2 based on global setting (bit 0) on all CPUs.
+	 */
+	msr_val = umwait_disable_c0_2 & UMWAIT_CONTROL_C02_MASK;
+	for_each_online_cpu(cpu)
+		wrmsr_on_cpu(cpu, MSR_IA32_UMWAIT_CONTROL, msr_val, 0);
+	mutex_unlock(&umwait_lock);
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(umwait_disable_c0_2);
+
+static struct attribute *umwait_attrs[] = {
+	&dev_attr_umwait_disable_c0_2.attr,
+	NULL
+};
+
+static struct attribute_group umwait_attr_group = {
+	.attrs = umwait_attrs,
+	.name = "user_wait",
+};
+
+/* Keep the umwait control MSR on this CPU with the current global setting. */
+static int umwait_cpu_online(unsigned int cpu)
+{
+	u32 msr_val;
+
+	mutex_lock(&umwait_lock);
+	/*
+	 * No global umwait maximum time limit (0 in bits 31-0).
+	 * Enable or disable C0.2 based on global setting (bit 0) on this CPU.
+	 */
+	msr_val = umwait_disable_c0_2 & UMWAIT_CONTROL_C02_MASK;
+	wrmsr(MSR_IA32_UMWAIT_CONTROL, umwait_disable_c0_2, 0);
+	mutex_unlock(&umwait_lock);
+
+	return 0;
+}
+
+static int __init umwait_init(void)
+{
+	struct device *dev;
+	int ret;
+
+	if (!boot_cpu_has(X86_FEATURE_WAITPKG))
+		return -ENODEV;
+
+	/* Add CPU global user wait interface to control umwait C0.2. */
+	dev = cpu_subsys.dev_root;
+	ret = sysfs_create_group(&dev->kobj, &umwait_attr_group);
+	if (ret)
+		return ret;
+
+	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "umwait/intel:online",
+				umwait_cpu_online, NULL);
+	if (ret < 0)
+		goto out_group;
+
+	return 0;
+out_group:
+	sysfs_remove_group(&dev->kobj, &umwait_attr_group);
+
+	return ret;
+}
+device_initcall(umwait_init);
-- 
2.5.0


  parent reply	other threads:[~2018-06-16  3:09 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-16  3:06 [RFC PATCH 0/8] x86: Enable a few new instructions Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 1/8] x86/cpufeatures: Enumerate MOVDIRI instruction Fenghua Yu
2018-06-19  8:57   ` Thomas Gleixner
2018-06-19 21:36     ` Fenghua Yu
2018-06-19 22:32       ` Thomas Gleixner
2018-06-19 22:35         ` Fenghua Yu
2018-06-25 16:13       ` David Laight
2018-06-16  3:06 ` [RFC PATCH 2/8] x86/cpufeatures: Enumerate MOVDIR64B instruction Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 3/8] x86/cpufeatures: Enumerate UMONITOR, UMWAIT, and TPAUSE instructions Fenghua Yu
2018-06-16  3:06 ` Fenghua Yu [this message]
2018-06-19  9:03   ` [RFC PATCH 4/8] cpuidle: Set up maximum umwait time and umwait states Thomas Gleixner
2018-06-19 15:46     ` Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 5/8] x86/umwait.c: Add sysfs interface to show tsc_khz Fenghua Yu
2018-06-19  9:08   ` Thomas Gleixner
2018-06-19 15:11     ` Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 6/8] x86/lib_direct_store.h: Add APIs for direct store instructions Fenghua Yu
2018-06-19  8:47   ` Thomas Gleixner
2018-06-16  3:06 ` [RFC PATCH 7/8] x86/lib_user_wait.h: Add APIs for user wait instructions Fenghua Yu
2018-06-19  9:12   ` Thomas Gleixner
2018-06-19 22:27     ` Fenghua Yu
2018-06-19 22:34       ` Thomas Gleixner
2018-06-19 22:36         ` Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 8/8] selftests/x86: Self test for the APIs in lib_direct_store.h and lib_user_wait.h Fenghua Yu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1529118375-90191-5-git-send-email-fenghua.yu@intel.com \
    --to=fenghua.yu@intel.com \
    --cc=alan@linux.intel.com \
    --cc=ashok.raj@intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=ravi.v.shankar@intel.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®