All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kyung Min Park <kyung.min.park@intel.com>
To: x86@kernel.org, linux-kernel@vger.kernel.org
Cc: tglx@linutronix.de, mingo@redhat.com, hpa@zytor.com,
	gregkh@linuxfoundation.org, ak@linux.intel.com,
	tony.luck@intel.com, ashok.raj@intel.com,
	ravi.v.shankar@intel.com, fenghua.yu@intel.com,
	kyung.min.park@intel.com
Subject: [PATCH v2 2/2] x86/delay: Introduce TPAUSE delay
Date: Thu, 19 Mar 2020 21:13:24 -0700	[thread overview]
Message-ID: <1584677604-32707-3-git-send-email-kyung.min.park@intel.com> (raw)
In-Reply-To: <1584677604-32707-1-git-send-email-kyung.min.park@intel.com>

TPAUSE instructs the processor to enter an implementation-dependent
optimized state. The instruction execution wakes up when the time-stamp
counter reaches or exceeds the implicit EDX:EAX 64-bit input value.
The instruction execution also wakes up due to the expiration of
the operating system time-limit or by an external interrupt
or exceptions such as a debug exception or a machine check exception.

TPAUSE offers a choice of two lower power states:
 1. Light-weight power/performance optimized state C0.1
 2. Improved power/performance optimized state C0.2
This way, it can save power with low wake-up latency in comparison to
spinloop based delay. The selection between the two is governed by the
input register.

TPAUSE is available on processors with X86_FEATURE_WAITPKG.

Reviewed-by: Tony Luck <tony.luck@intel.com>
Co-developed-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Kyung Min Park <kyung.min.park@intel.com>
---
 arch/x86/include/asm/mwait.h | 17 +++++++++++++++++
 arch/x86/lib/delay.c         | 27 ++++++++++++++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h
index aaf6643..fd59db0 100644
--- a/arch/x86/include/asm/mwait.h
+++ b/arch/x86/include/asm/mwait.h
@@ -22,6 +22,8 @@
 #define MWAITX_ECX_TIMER_ENABLE		BIT(1)
 #define MWAITX_MAX_WAIT_CYCLES		UINT_MAX
 #define MWAITX_DISABLE_CSTATES		0xf0
+#define TPAUSE_C01_STATE		1
+#define TPAUSE_C02_STATE		0
 
 static inline void __monitor(const void *eax, unsigned long ecx,
 			     unsigned long edx)
@@ -120,4 +122,19 @@ static inline void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
 	current_clr_polling();
 }
 
+/*
+ * Caller can specify whether to enter C0.1 (low latency, less
+ * power saving) or C0.2 state (saves more power, but longer wakeup
+ * latency). This may be overridden by the IA32_UMWAIT_CONTROL MSR
+ * which can force requests for C0.2 to be downgraded to C0.1.
+ */
+static inline void __tpause(unsigned int ecx, unsigned int edx,
+			    unsigned int eax)
+{
+	/* "tpause %ecx, %edx, %eax;" */
+	asm volatile(".byte 0x66, 0x0f, 0xae, 0xf1\t\n"
+		     :
+		     : "c"(ecx), "d"(edx), "a"(eax));
+}
+
 #endif /* _ASM_X86_MWAIT_H */
diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c
index e6db855..5f11f0a 100644
--- a/arch/x86/lib/delay.c
+++ b/arch/x86/lib/delay.c
@@ -97,6 +97,27 @@ static void delay_tsc(u64 cycles)
 }
 
 /*
+ * On Intel the TPAUSE instruction waits until any of:
+ * 1) the TSC counter exceeds the value provided in EAX:EDX
+ * 2) global timeout in IA32_UMWAIT_CONTROL is exceeded
+ * 3) an external interrupt occurs
+ */
+static void delay_halt_tpause(u64 start, u64 cycles)
+{
+	u64 until = start + cycles;
+	unsigned int eax, edx;
+
+	eax = (unsigned int)(until & 0xffffffff);
+	edx = (unsigned int)(until >> 32);
+
+	/*
+	 * Hard code the deeper (C0.2) sleep state because exit latency is
+	 * small compared to the "microseconds" that usleep() will delay.
+	 */
+	__tpause(TPAUSE_C02_STATE, edx, eax);
+}
+
+/*
  * On some AMD platforms, MWAITX has a configurable 32-bit timer, that
  * counts with TSC frequency. The input value is the number of TSC cycles
  * to wait. MWAITX will also exit when the timer expires.
@@ -152,8 +173,12 @@ static void delay_halt(u64 __cycles)
 
 void use_tsc_delay(void)
 {
-	if (delay_fn == delay_loop)
+	if (static_cpu_has(X86_FEATURE_WAITPKG)) {
+		delay_halt_fn = delay_halt_tpause;
+		delay_fn = delay_halt;
+	} else if (delay_fn == delay_loop) {
 		delay_fn = delay_tsc;
+	}
 }
 
 void use_mwaitx_delay(void)
-- 
2.7.4


  parent reply	other threads:[~2020-03-20  4:13 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-20  4:13 [PATCH v2 0/2] x86/delay: Introduce TPAUSE instruction Kyung Min Park
2020-03-20  4:13 ` [PATCH v2 1/2] x86/delay: Refactor delay_mwaitx() for TPAUSE support Kyung Min Park
2020-03-20  4:13 ` Kyung Min Park [this message]
2020-03-20  4:23   ` [PATCH v2 2/2] x86/delay: Introduce TPAUSE delay Andy Lutomirski
2020-03-20 10:00     ` Thomas Gleixner
2020-03-20 21:51       ` Andy Lutomirski
2020-03-20 23:23         ` Thomas Gleixner
2020-03-20 23:57           ` Andy Lutomirski
2020-03-30 23:42             ` Park, Kyung Min
2020-03-20 10:07   ` Joe Perches
2020-03-23  5:18     ` Park, Kyung Min
2020-03-20  9:57 ` [PATCH v2 0/2] x86/delay: Introduce TPAUSE instruction Thomas Gleixner
2020-03-20 23:43   ` Park, Kyung Min

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=1584677604-32707-3-git-send-email-kyung.min.park@intel.com \
    --to=kyung.min.park@intel.com \
    --cc=ak@linux.intel.com \
    --cc=ashok.raj@intel.com \
    --cc=fenghua.yu@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --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=tony.luck@intel.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.