linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Stephane Eranian <eranian@google.com>
To: linux-kernel@vger.kernel.org
Cc: acme@redhat.com, peterz@infradead.org, mingo@elte.hu,
	ak@linux.intel.com, kan.liang@intel.com
Subject: [PATCH] perf/x86/msr: add support for MSR_IA32_THERM_STATUS
Date: Fri,  5 Jan 2018 08:18:52 -0800	[thread overview]
Message-ID: <1515169132-3980-1-git-send-email-eranian@google.com> (raw)

This patch adds support for the Digital Readout provided by the
IA32_THERM_STATUS MSR (0x19C) on Intel X86 processors. The readout
shows the number of degrees Celcius to the TCC (critical temperature)
supported by the processor. Thus, the larger, the better.

The perf_event support is provided via the msr PMU. The new
logical event is called cpu_thermal_margin. It comes with a unit and
snapshot files. The event shows the current temprature distance (margin).
It is not an accumulating event. The unit is degree C. The event
is provided per logical CPU to make things simpler but it is the
same for both hyper-threads sharing a physical core.

$ perf stat -I 1000 -a -A -e msr/cpu_thermal_margin/

This will print the temperature for all logical CPUs.
             time CPU                counts unit events
     1.000123741 CPU0                    38 C    msr/cpu_thermal_margin/
     1.000161837 CPU1                    37 C    msr/cpu_thermal_margin/
     1.000187906 CPU2                    36 C    msr/cpu_thermal_margin/
     1.000189046 CPU3                    39 C    msr/cpu_thermal_margin/
     1.000283044 CPU4                    40 C    msr/cpu_thermal_margin/
     1.000344297 CPU5                    40 C    msr/cpu_thermal_margin/
     1.000365832 CPU6                    39 C    msr/cpu_thermal_margin/
     ...

In case the temperature margin cannot be read, the reported value would be -1.

Works on all processors supporting the Digital Readout (dtherm in cpuinfo)

Signed-off-by: Stephane Eranian <eranian@google.com>

---
 arch/x86/events/msr.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/arch/x86/events/msr.c b/arch/x86/events/msr.c
index 14efaa0e8684..0be15b9b2376 100644
--- a/arch/x86/events/msr.c
+++ b/arch/x86/events/msr.c
@@ -10,7 +10,9 @@ enum perf_msr_id {
 	PERF_MSR_SMI			= 4,
 	PERF_MSR_PTSC			= 5,
 	PERF_MSR_IRPERF			= 6,
-
+	PERF_MSR_THERM			= 7,
+	PERF_MSR_THERM_SNAP		= 8,
+	PERF_MSR_THERM_UNIT		= 9,
 	PERF_MSR_EVENT_MAX,
 };
 
@@ -29,6 +31,12 @@ static bool test_irperf(int idx)
 	return boot_cpu_has(X86_FEATURE_IRPERF);
 }
 
+static bool test_therm_status(int idx)
+{
+	return boot_cpu_has(X86_FEATURE_DTHERM);
+}
+
+
 static bool test_intel(int idx)
 {
 	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
@@ -102,6 +110,9 @@ PMU_EVENT_ATTR_STRING(pperf,  evattr_pperf,  "event=0x03");
 PMU_EVENT_ATTR_STRING(smi,    evattr_smi,    "event=0x04");
 PMU_EVENT_ATTR_STRING(ptsc,   evattr_ptsc,   "event=0x05");
 PMU_EVENT_ATTR_STRING(irperf, evattr_irperf, "event=0x06");
+PMU_EVENT_ATTR_STRING(cpu_thermal_margin, evattr_therm, "event=0x07");
+PMU_EVENT_ATTR_STRING(cpu_thermal_margin.snapshot, evattr_therm_snap, "1");
+PMU_EVENT_ATTR_STRING(cpu_thermal_margin.unit, evattr_therm_unit, "C");
 
 static struct perf_msr msr[] = {
 	[PERF_MSR_TSC]    = { 0,		&evattr_tsc,	NULL,		 },
@@ -111,6 +122,9 @@ static struct perf_msr msr[] = {
 	[PERF_MSR_SMI]    = { MSR_SMI_COUNT,	&evattr_smi,	test_intel,	 },
 	[PERF_MSR_PTSC]   = { MSR_F15H_PTSC,	&evattr_ptsc,	test_ptsc,	 },
 	[PERF_MSR_IRPERF] = { MSR_F17H_IRPERF,	&evattr_irperf,	test_irperf,	 },
+	[PERF_MSR_THERM] = { MSR_IA32_THERM_STATUS, &evattr_therm,	     test_therm_status, },
+	[PERF_MSR_THERM_SNAP] = { MSR_IA32_THERM_STATUS, &evattr_therm_snap, test_therm_status, },
+	[PERF_MSR_THERM_UNIT] = { MSR_IA32_THERM_STATUS, &evattr_therm_unit, test_therm_status, },
 };
 
 static struct attribute *events_attrs[PERF_MSR_EVENT_MAX + 1] = {
@@ -193,10 +207,15 @@ static void msr_event_update(struct perf_event *event)
 		goto again;
 
 	delta = now - prev;
-	if (unlikely(event->hw.event_base == MSR_SMI_COUNT))
+	if (unlikely(event->hw.event_base == MSR_SMI_COUNT)) {
 		delta = sign_extend64(delta, 31);
-
-	local64_add(delta, &event->count);
+		local64_add(delta, &event->count);
+	} else if (unlikely(event->hw.event_base == MSR_IA32_THERM_STATUS)) {
+		/* if valid, extract digital readout, other set to -1 */
+		now = now & (1ULL << 31) ? (now >> 16) & 0x3f :  -1;
+		local64_set(&event->count, now);
+	} else
+		local64_add(delta, &event->count);
 }
 
 static void msr_event_start(struct perf_event *event, int flags)
-- 
2.7.4

             reply	other threads:[~2018-01-05 16:19 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-05 16:18 Stephane Eranian [this message]
2018-01-06 11:53 ` [tip:perf/core] perf/x86/msr: Add support for MSR_IA32_THERM_STATUS tip-bot for Stephane Eranian
2018-01-06 11:54 ` [tip:perf/core] perf/x86/msr: Clean up the code tip-bot for Ingo Molnar

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=1515169132-3980-1-git-send-email-eranian@google.com \
    --to=eranian@google.com \
    --cc=acme@redhat.com \
    --cc=ak@linux.intel.com \
    --cc=kan.liang@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=peterz@infradead.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;
as well as URLs for NNTP newsgroup(s).