linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] CPU Package temperarure thermal driver (v02)
@ 2013-05-17 23:42 Srinivas Pandruvada
  2013-05-17 23:42 ` [PATCH 1/3] x86, mcheck, therm_throt: Process package thresholds Srinivas Pandruvada
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Srinivas Pandruvada @ 2013-05-17 23:42 UTC (permalink / raw)
  To: linux-pm
  Cc: eduardo.valentin, rui.zhang, tony.luck, linux-edac, Srinivas Pandruvada

This driver register CPU digital temperature package level sensor as a
thermal zone with two user mode configurable trip points. Once
the trip point is violated, user mode can receive notification via thermal
notification mechanism and can take any action to control temperature.

Changes:
v02:
Did majority of changes suggested by Eduardo Valentin. Main changes are:
- Module parameters for rate control delay
- Removed user space gov parameter in thermal_zone_register
- Changes related to returning of errors values
- Error code return values

v01:
First version for review

Background:
This set of changes were done to coretemp driver and posted to lm_sensors
mailing list on 04/04/2013. This was reviewed by Guenter Roeck from lm-sensors
and Zhang Rui (thermal maintainer). They were in agreement not to add notification
mechanism to coretemp driver but use thermal sysfs.
Guenter Roeck suggested to use approach like "db8500_thermal driver in drivers/thermal".
So resubmitting the driver as a thermal zone driver.
Previous discussion link:
http://comments.gmane.org/gmane.linux.drivers.sensors/32182
" 
This is clear that there is reluctance in adding thresholds in coretemp sysfs,
during previous attempts. Probably because of lake of use cases.
But this time use case may be more compelling.

We have many small form factor devices like ultrabooks, slate PCs in the market.
Unfortunately these devices reach maximum temperature with relatively less
workloads, causing BIOS to do thermal throttling. There are real performance
issues due to aggressive BIOS action to control thermals and also thermal breakdown
in some cases.

Even the most expensive laptops, don't have correct ACPI thermal configuration,
so that kernel thermal driver can act. In some case even the trip point is higher
than critical temperature setting.

Intel has developed several drivers, which can be used to cool the system very efficiently.
They include RAPL based cooling driver, Powerclamp driver and P state driver.
To utilize these cooling device a closed loop user mode program is required, which
will utilize these method and dynamically compensate for high CPU temperatures,
without relying on any configuration data.
One such solution is developed is "Linux thermal daemon". More details can be
obtained from 
"https://github.com/01org/thermal_daemon/blob/master/ThermalDaemon_Introduction.pdf".
This daemon polls for cpu temperature and apply compensation once the CPU reach target
temperature. 

This polling can be mostly avoided, by getting notification for the temperature, where
it needs to wake up and get ready for apply compensation. In most of the normal use 
cases, there may not be any threshold events. So very minimal number of user space
notification for thermal thresholds.

Srinivas Pandruvada (3):
  x86, mcheck, therm_throt: Process package thresholds
  Thermal: CPU Package temperature thermal
  Thermal: Documentation for x86 package temperature thermal driver

 Documentation/thermal/x86_pkg_temperature_thermal |  47 ++
 arch/x86/include/asm/mce.h                        |   7 +
 arch/x86/kernel/cpu/mcheck/therm_throt.c          |  63 ++-
 drivers/thermal/Kconfig                           |  12 +
 drivers/thermal/Makefile                          |   2 +-
 drivers/thermal/x86_pkg_temp_thermal.c            | 642 ++++++++++++++++++++++
 6 files changed, 768 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/thermal/x86_pkg_temperature_thermal
 create mode 100644 drivers/thermal/x86_pkg_temp_thermal.c

-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/3] x86, mcheck, therm_throt: Process package thresholds
  2013-05-17 23:42 [PATCH 0/3] CPU Package temperarure thermal driver (v02) Srinivas Pandruvada
@ 2013-05-17 23:42 ` Srinivas Pandruvada
  2013-05-17 23:42 ` [PATCH 2/3] Thermal: CPU Package temperature thermal Srinivas Pandruvada
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Srinivas Pandruvada @ 2013-05-17 23:42 UTC (permalink / raw)
  To: linux-pm
  Cc: eduardo.valentin, rui.zhang, tony.luck, linux-edac, Srinivas Pandruvada

Added callback registration for package threshold reports. Also added
a callback to check the rate control implemented in callback or not.
If there is no rate control implemented, then there is a default rate
control similar to core threshold notification by delaying for
CHECK_INTERVAL (5 minutes) between reports.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 arch/x86/include/asm/mce.h               |  7 ++++
 arch/x86/kernel/cpu/mcheck/therm_throt.c | 63 ++++++++++++++++++++++++++++++--
 2 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h
index f4076af..4c619bf 100644
--- a/arch/x86/include/asm/mce.h
+++ b/arch/x86/include/asm/mce.h
@@ -214,6 +214,13 @@ void mce_log_therm_throt_event(__u64 status);
 /* Interrupt Handler for core thermal thresholds */
 extern int (*platform_thermal_notify)(__u64 msr_val);
 
+/* Interrupt Handler for package thermal thresholds */
+extern int (*platform_thermal_package_notify)(__u64 msr_val);
+
+/* Callback support of rate control, return true, if
+ * callback has rate control */
+extern bool (*platform_thermal_package_rate_control)(void);
+
 #ifdef CONFIG_X86_THERMAL_VECTOR
 extern void mcheck_intel_therm_init(void);
 #else
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
index 47a1870..4131c03 100644
--- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
@@ -54,12 +54,24 @@ struct thermal_state {
 	struct _thermal_state package_power_limit;
 	struct _thermal_state core_thresh0;
 	struct _thermal_state core_thresh1;
+	struct _thermal_state pkg_thresh0;
+	struct _thermal_state pkg_thresh1;
 };
 
 /* Callback to handle core threshold interrupts */
 int (*platform_thermal_notify)(__u64 msr_val);
 EXPORT_SYMBOL(platform_thermal_notify);
 
+/* Callback to handle core package threshold_interrupts */
+int (*platform_thermal_package_notify)(__u64 msr_val);
+EXPORT_SYMBOL_GPL(platform_thermal_package_notify);
+
+/* Callback support of rate control, return true, if
+ * callback has rate control */
+bool (*platform_thermal_package_rate_control)(void);
+EXPORT_SYMBOL_GPL(platform_thermal_package_rate_control);
+
+
 static DEFINE_PER_CPU(struct thermal_state, thermal_state);
 
 static atomic_t therm_throt_en	= ATOMIC_INIT(0);
@@ -203,19 +215,25 @@ static int therm_throt_process(bool new_event, int event, int level)
 	return 0;
 }
 
-static int thresh_event_valid(int event)
+static int thresh_event_valid(int level, int event)
 {
 	struct _thermal_state *state;
 	unsigned int this_cpu = smp_processor_id();
 	struct thermal_state *pstate = &per_cpu(thermal_state, this_cpu);
 	u64 now = get_jiffies_64();
 
-	state = (event == 0) ? &pstate->core_thresh0 : &pstate->core_thresh1;
+	if (level == PACKAGE_LEVEL)
+		state = (event == 0) ? &pstate->pkg_thresh0 :
+						&pstate->pkg_thresh1;
+	else
+		state = (event == 0) ? &pstate->core_thresh0 :
+						&pstate->core_thresh1;
 
 	if (time_before64(now, state->next_check))
 		return 0;
 
 	state->next_check = now + CHECK_INTERVAL;
+
 	return 1;
 }
 
@@ -321,6 +339,39 @@ device_initcall(thermal_throttle_init_device);
 
 #endif /* CONFIG_SYSFS */
 
+static void notify_package_thresholds(__u64 msr_val)
+{
+	bool notify_thres_0 = false;
+	bool notify_thres_1 = false;
+
+	if (!platform_thermal_package_notify)
+		return;
+
+	/* lower threshold check */
+	if (msr_val & THERM_LOG_THRESHOLD0)
+		notify_thres_0 = true;
+	/* higher threshold check */
+	if (msr_val & THERM_LOG_THRESHOLD1)
+		notify_thres_1 = true;
+
+	if (!notify_thres_0 && !notify_thres_1)
+		return;
+
+	if (platform_thermal_package_rate_control &&
+		platform_thermal_package_rate_control()) {
+		/* Rate control is implemented in callback */
+		platform_thermal_package_notify(msr_val);
+		return;
+	}
+
+	/* lower threshold reached */
+	if (notify_thres_0 && thresh_event_valid(PACKAGE_LEVEL, 0))
+		platform_thermal_package_notify(msr_val);
+	/* higher threshold reached */
+	if (notify_thres_1 && thresh_event_valid(PACKAGE_LEVEL, 1))
+		platform_thermal_package_notify(msr_val);
+}
+
 static void notify_thresholds(__u64 msr_val)
 {
 	/* check whether the interrupt handler is defined;
@@ -330,10 +381,12 @@ static void notify_thresholds(__u64 msr_val)
 		return;
 
 	/* lower threshold reached */
-	if ((msr_val & THERM_LOG_THRESHOLD0) &&	thresh_event_valid(0))
+	if ((msr_val & THERM_LOG_THRESHOLD0) &&
+			thresh_event_valid(CORE_LEVEL, 0))
 		platform_thermal_notify(msr_val);
 	/* higher threshold reached */
-	if ((msr_val & THERM_LOG_THRESHOLD1) && thresh_event_valid(1))
+	if ((msr_val & THERM_LOG_THRESHOLD1) &&
+			thresh_event_valid(CORE_LEVEL, 1))
 		platform_thermal_notify(msr_val);
 }
 
@@ -359,6 +412,8 @@ static void intel_thermal_interrupt(void)
 
 	if (this_cpu_has(X86_FEATURE_PTS)) {
 		rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
+		/* check violations of package thermal thresholds */
+		notify_package_thresholds(msr_val);
 		therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT,
 					THERMAL_THROTTLING_EVENT,
 					PACKAGE_LEVEL);
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/3] Thermal: CPU Package temperature thermal
  2013-05-17 23:42 [PATCH 0/3] CPU Package temperarure thermal driver (v02) Srinivas Pandruvada
  2013-05-17 23:42 ` [PATCH 1/3] x86, mcheck, therm_throt: Process package thresholds Srinivas Pandruvada
@ 2013-05-17 23:42 ` Srinivas Pandruvada
  2013-05-17 23:42 ` [PATCH 3/3] Thermal: Documentation for x86 package temperature thermal driver Srinivas Pandruvada
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 9+ messages in thread
From: Srinivas Pandruvada @ 2013-05-17 23:42 UTC (permalink / raw)
  To: linux-pm
  Cc: eduardo.valentin, rui.zhang, tony.luck, linux-edac, Srinivas Pandruvada

This driver register CPU digital temperature sensor as a thermal
zone at package level.
Each package will show up as one zone with at max two trip points.
These trip points can be both read and updated. Once a non zero
value is set in the trip point, if the package package temperature
goes above or below this setting, a thermal notification is
generated.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 drivers/thermal/Kconfig                |  12 +
 drivers/thermal/Makefile               |   2 +-
 drivers/thermal/x86_pkg_temp_thermal.c | 642 +++++++++++++++++++++++++++++++++
 3 files changed, 655 insertions(+), 1 deletion(-)
 create mode 100644 drivers/thermal/x86_pkg_temp_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index a764f16..ed9b983 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -165,4 +165,16 @@ config INTEL_POWERCLAMP
 	  enforce idle time which results in more package C-state residency. The
 	  user interface is exposed via generic thermal framework.
 
+config X86_PKG_TEMP_THERMAL
+	tristate "X86 package temperature thermal driver"
+	depends on THERMAL
+	depends on X86
+	select THERMAL_GOV_USER_SPACE
+	default m
+	help
+	  Enable this to register CPU digital sensor for package temperature as
+	  thermal zone. Each package will have its own thermal zone. There are
+	  two trip points which can be set by user to get notifications via thermal
+	  notification methods.
+
 endif
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index d3a2b38..fd137ce 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -21,4 +21,4 @@ obj-$(CONFIG_DOVE_THERMAL)  	+= dove_thermal.o
 obj-$(CONFIG_DB8500_THERMAL)	+= db8500_thermal.o
 obj-$(CONFIG_DB8500_CPUFREQ_COOLING)	+= db8500_cpufreq_cooling.o
 obj-$(CONFIG_INTEL_POWERCLAMP)	+= intel_powerclamp.o
-
+obj-$(CONFIG_X86_PKG_TEMP_THERMAL)	+= x86_pkg_temp_thermal.o
diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c
new file mode 100644
index 0000000..5de56f6
--- /dev/null
+++ b/drivers/thermal/x86_pkg_temp_thermal.c
@@ -0,0 +1,642 @@
+/*
+ * x86_pkg_temp_thermal driver
+ * Copyright (c) 2013, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.
+ *
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/param.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/thermal.h>
+#include <linux/debugfs.h>
+#include <asm/cpu_device_id.h>
+#include <asm/mce.h>
+
+/*
+* Rate control delay: Idea is to introduce denounce effect
+* This should be long enough to avoid reduce events, when
+* threshold is set to a temperature, which is constantly
+* violated, but at the short enough to take any action.
+* The action can be remove threshold or change it to next
+* interesting setting. Based on experiments, in around
+* every 5 seconds under load will give us a significant
+* temperature change.
+*/
+#define PKG_TEMP_THERMAL_NOTIFY_DELAY	5000
+static int notify_delay_ms = PKG_TEMP_THERMAL_NOTIFY_DELAY;
+module_param(notify_delay_ms, int, 0644);
+MODULE_PARM_DESC(notify_delay_ms,
+	"User space notification delay in milli seconds.");
+
+/* Number of trip points in thermal zone. Currently it can't
+* be more than 2. MSR can allow setting and getting notifications
+* for only 2 thresholds. This define enforces this, if there
+* is some wrong values returned by cpuid for number of thresholds.
+*/
+#define MAX_NUMBER_OF_TRIPS	2
+
+struct phy_dev_entry {
+	struct list_head list;
+	u16 phys_proc_id;
+	u16 first_cpu;
+	u32 tj_max;
+	int ref_cnt;
+	u32 start_pkg_therm_low;
+	u32 start_pkg_therm_high;
+	struct thermal_zone_device *tzone;
+};
+
+/* List maintaining number of package instances */
+static LIST_HEAD(phy_dev_list);
+static DEFINE_MUTEX(phy_dev_list_mutex);
+
+/* Interrupt to work function schedule queue */
+static DEFINE_PER_CPU(struct delayed_work, pkg_temp_thermal_threshold_work);
+
+/* To track if the work is already scheduled on a package */
+static u8 *pkg_work_scheduled;
+
+/* Spin lock to prevent races with pkg_work_scheduled */
+static spinlock_t pkg_work_lock;
+static u16 max_phy_id;
+
+/* Debug counters to show using debugfs */
+static struct dentry *debugfs;
+static unsigned int pkg_interrupt_cnt;
+static unsigned int pkg_work_cnt;
+
+static int pkg_temp_debugfs_init(void)
+{
+	struct dentry *d;
+
+	debugfs = debugfs_create_dir("pkg_temp_thermal", NULL);
+	if (!debugfs)
+		return -ENOENT;
+
+	d = debugfs_create_u32("pkg_thres_interrupt", S_IRUGO, debugfs,
+				(u32 *)&pkg_interrupt_cnt);
+	if (!d)
+		goto err_out;
+
+	d = debugfs_create_u32("pkg_thres_work", S_IRUGO, debugfs,
+				(u32 *)&pkg_work_cnt);
+	if (!d)
+		goto err_out;
+
+	return 0;
+
+err_out:
+	debugfs_remove_recursive(debugfs);
+	return -ENOENT;
+}
+
+static struct phy_dev_entry
+			*pkg_temp_thermal_get_phy_entry(unsigned int cpu)
+{
+	u16 phys_proc_id = topology_physical_package_id(cpu);
+	struct phy_dev_entry *phy_ptr;
+
+	mutex_lock(&phy_dev_list_mutex);
+
+	list_for_each_entry(phy_ptr, &phy_dev_list, list)
+		if (phy_ptr->phys_proc_id == phys_proc_id) {
+			mutex_unlock(&phy_dev_list_mutex);
+			return phy_ptr;
+		}
+
+	mutex_unlock(&phy_dev_list_mutex);
+
+	return NULL;
+}
+
+/*
+* tj-max is is interesting because threshold is set relative to this
+* temperature.
+*/
+static int get_tj_max(int cpu, u32 *tj_max)
+{
+	u32 eax, edx;
+	u32 val;
+	int err;
+
+	err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
+	if (err)
+		goto err_ret;
+	else {
+		val = (eax >> 16) & 0xff;
+		if (val)
+			*tj_max = val * 1000;
+		else {
+			err = -EINVAL;
+			goto err_ret;
+		}
+	}
+
+	return 0;
+err_ret:
+	*tj_max = 0;
+	return err;
+}
+
+static int sys_get_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp)
+{
+	u32 eax, edx;
+	struct phy_dev_entry *phy_dev_entry;
+
+	phy_dev_entry = tzd->devdata;
+	rdmsr_on_cpu(phy_dev_entry->first_cpu, MSR_IA32_PACKAGE_THERM_STATUS,
+			&eax, &edx);
+	if (eax & 0x80000000) {
+		*temp = phy_dev_entry->tj_max -
+				((eax >> 16) & 0x7f) * 1000;
+		pr_debug("sys_get_curr_temp %ld\n", *temp);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static int sys_get_trip_temp(struct thermal_zone_device *tzd,
+		int trip, unsigned long *temp)
+{
+	u32 eax, edx;
+	struct phy_dev_entry *phy_dev_entry;
+	u32 mask, shift;
+	unsigned long thres_reg_value;
+	int ret;
+
+	if (trip >= MAX_NUMBER_OF_TRIPS)
+		return -EINVAL;
+
+	phy_dev_entry = tzd->devdata;
+
+	if (trip) {
+		mask = THERM_MASK_THRESHOLD1;
+		shift = THERM_SHIFT_THRESHOLD1;
+	} else {
+		mask = THERM_MASK_THRESHOLD0;
+		shift = THERM_SHIFT_THRESHOLD0;
+	}
+
+	ret = rdmsr_on_cpu(phy_dev_entry->first_cpu,
+				MSR_IA32_PACKAGE_THERM_INTERRUPT, &eax, &edx);
+	if (ret < 0)
+		return -EINVAL;
+
+	thres_reg_value = (eax & mask) >> shift;
+	if (thres_reg_value)
+		*temp = phy_dev_entry->tj_max - thres_reg_value * 1000;
+	else
+		*temp = 0;
+	pr_debug("sys_get_trip_temp %ld\n", *temp);
+
+	return 0;
+}
+
+int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip,
+							unsigned long temp)
+{
+	u32 l, h;
+	struct phy_dev_entry *phy_dev_entry;
+	u32 mask, shift, intr;
+	int ret;
+
+	phy_dev_entry = tzd->devdata;
+
+	if (trip >= MAX_NUMBER_OF_TRIPS || temp >= phy_dev_entry->tj_max)
+		return -EINVAL;
+
+	ret = rdmsr_on_cpu(phy_dev_entry->first_cpu,
+					MSR_IA32_PACKAGE_THERM_INTERRUPT,
+					&l, &h);
+	if (ret < 0)
+		return -EINVAL;
+
+	if (trip) {
+		mask = THERM_MASK_THRESHOLD1;
+		shift = THERM_SHIFT_THRESHOLD1;
+		intr = THERM_INT_THRESHOLD1_ENABLE;
+	} else {
+		mask = THERM_MASK_THRESHOLD0;
+		shift = THERM_SHIFT_THRESHOLD0;
+		intr = THERM_INT_THRESHOLD0_ENABLE;
+	}
+	l &= ~mask;
+	/*
+	* When users space sets a trip temperature == 0, which is indication
+	* that, it is no longer interested in receiving notifications.
+	*/
+	if (!temp)
+		l &= ~intr;
+	else {
+		l |= (phy_dev_entry->tj_max - temp)/1000 << shift;
+		l |= intr;
+	}
+
+	return wrmsr_on_cpu(phy_dev_entry->first_cpu,
+					MSR_IA32_PACKAGE_THERM_INTERRUPT,
+					l, h);
+}
+
+static int sys_get_trip_type(struct thermal_zone_device *thermal,
+		int trip, enum thermal_trip_type *type)
+{
+
+	*type = THERMAL_TRIP_PASSIVE;
+
+	return 0;
+}
+
+/* Thermal zone callback registry */
+static struct thermal_zone_device_ops tzone_ops = {
+	.get_temp = sys_get_curr_temp,
+	.get_trip_temp = sys_get_trip_temp,
+	.get_trip_type = sys_get_trip_type,
+	.set_trip_temp = sys_set_trip_temp,
+};
+
+static bool pkg_temp_thermal_platform_thermal_rate_control(void)
+{
+	return true;
+}
+
+/* Enable threshold interrupt on local package/cpu */
+static inline void enable_pkg_thres_interrupt(void)
+{
+	u32 l, h;
+	u8 thres_0, thres_1;
+
+	rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
+	/* only enable/disable if it had valid threshold value */
+	thres_0 = (l & THERM_MASK_THRESHOLD0) >> THERM_SHIFT_THRESHOLD0;
+	thres_1 = (l & THERM_MASK_THRESHOLD1) >> THERM_SHIFT_THRESHOLD1;
+	if (thres_0)
+		l |= THERM_INT_THRESHOLD0_ENABLE;
+	if (thres_1)
+		l |= THERM_INT_THRESHOLD1_ENABLE;
+	wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
+}
+
+/* Disable threshold interrupt on local package/cpu */
+static inline void disable_pkg_thres_interrupt(void)
+{
+	u32 l, h;
+	rdmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h);
+	wrmsr(MSR_IA32_PACKAGE_THERM_INTERRUPT,
+			l & (~THERM_INT_THRESHOLD0_ENABLE) &
+				(~THERM_INT_THRESHOLD1_ENABLE), h);
+}
+
+static void pkg_temp_thermal_threshold_work_fn(struct work_struct *work)
+{
+	__u64 msr_val;
+	int cpu = smp_processor_id();
+	int phy_id = topology_physical_package_id(cpu);
+	struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
+	bool notify = false;
+
+	if (!phdev)
+		return;
+
+	spin_lock(&pkg_work_lock);
+	++pkg_work_cnt;
+	if (unlikely(phy_id > max_phy_id)) {
+		spin_unlock(&pkg_work_lock);
+		return;
+	}
+	pkg_work_scheduled[phy_id] = 0;
+	spin_unlock(&pkg_work_lock);
+
+	enable_pkg_thres_interrupt();
+	rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
+	if (msr_val & THERM_LOG_THRESHOLD0) {
+		wrmsrl(MSR_IA32_PACKAGE_THERM_STATUS,
+				msr_val & ~THERM_LOG_THRESHOLD0);
+		notify = true;
+	}
+	if (msr_val & THERM_LOG_THRESHOLD1) {
+		wrmsrl(MSR_IA32_PACKAGE_THERM_STATUS,
+				msr_val & ~THERM_LOG_THRESHOLD1);
+		notify = true;
+	}
+	if (notify) {
+		pr_debug("thermal_zone_device_update\n");
+		thermal_zone_device_update(phdev->tzone);
+	}
+}
+
+static int pkg_temp_thermal_platform_thermal_notify(__u64 msr_val)
+{
+	unsigned long flags;
+	int cpu = smp_processor_id();
+	int phy_id = topology_physical_package_id(cpu);
+
+	/*
+	* When a package is in interrupted state, all CPU's in that package
+	* are in the same interrupt state. So scheduling on any one CPU in
+	* the package is enough and simply return for others.
+	*/
+	spin_lock_irqsave(&pkg_work_lock, flags);
+	++pkg_interrupt_cnt;
+	if (unlikely(phy_id > max_phy_id) || unlikely(!pkg_work_scheduled) ||
+			pkg_work_scheduled[phy_id]) {
+		disable_pkg_thres_interrupt();
+		spin_unlock_irqrestore(&pkg_work_lock, flags);
+		return -EINVAL;
+	}
+	pkg_work_scheduled[phy_id] = 1;
+	spin_unlock_irqrestore(&pkg_work_lock, flags);
+
+	disable_pkg_thres_interrupt();
+	schedule_delayed_work_on(cpu,
+				&per_cpu(pkg_temp_thermal_threshold_work, cpu),
+				msecs_to_jiffies(notify_delay_ms));
+	return 0;
+}
+
+static int find_siblings_cpu(int cpu)
+{
+	int i;
+	int id = topology_physical_package_id(cpu);
+
+	for_each_online_cpu(i)
+		if (i != cpu && topology_physical_package_id(i) == id)
+			return i;
+
+	return 0;
+}
+
+static int pkg_temp_thermal_device_add(unsigned int cpu)
+{
+	int err;
+	u32 tj_max;
+	struct phy_dev_entry *phy_dev_entry;
+	char buffer[30];
+	int thres_count;
+	u32 eax, ebx, ecx, edx;
+
+	cpuid(6, &eax, &ebx, &ecx, &edx);
+	thres_count = ebx & 0x07;
+	if (!thres_count)
+		return -ENODEV;
+
+	thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS);
+
+	err = get_tj_max(cpu, &tj_max);
+	if (err)
+		goto err_ret;
+
+	mutex_lock(&phy_dev_list_mutex);
+
+	phy_dev_entry = kzalloc(sizeof(*phy_dev_entry), GFP_KERNEL);
+	if (!phy_dev_entry) {
+		err = -ENOMEM;
+		goto err_ret_unlock;
+	}
+
+	spin_lock(&pkg_work_lock);
+	if (topology_physical_package_id(cpu) > max_phy_id)
+		max_phy_id = topology_physical_package_id(cpu);
+	pkg_work_scheduled = krealloc(pkg_work_scheduled,
+				(max_phy_id+1) * sizeof(u8), GFP_ATOMIC);
+	if (!pkg_work_scheduled) {
+		spin_unlock(&pkg_work_lock);
+		err = -ENOMEM;
+		goto err_ret_free;
+	}
+	pkg_work_scheduled[topology_physical_package_id(cpu)] = 0;
+	spin_unlock(&pkg_work_lock);
+
+	phy_dev_entry->phys_proc_id = topology_physical_package_id(cpu);
+	phy_dev_entry->first_cpu = cpu;
+	phy_dev_entry->tj_max = tj_max;
+	phy_dev_entry->ref_cnt = 1;
+	snprintf(buffer, sizeof(buffer), "pkg-temp-%d\n",
+					phy_dev_entry->phys_proc_id);
+	phy_dev_entry->tzone = thermal_zone_device_register(buffer,
+			thres_count,
+			(thres_count == MAX_NUMBER_OF_TRIPS) ?
+				0x03 : 0x01,
+			phy_dev_entry, &tzone_ops, NULL, 0, 0);
+	if (IS_ERR(phy_dev_entry->tzone)) {
+		err = PTR_ERR(phy_dev_entry->tzone);
+		goto err_ret_free;
+	}
+	/* Store MSR value for package thermal interrupt, to restore at exit */
+	rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
+				&phy_dev_entry->start_pkg_therm_low,
+				&phy_dev_entry->start_pkg_therm_high);
+
+	list_add_tail(&phy_dev_entry->list, &phy_dev_list);
+	pr_debug("pkg_temp_thermal_device_add :phy_id %d cpu %d\n",
+			phy_dev_entry->phys_proc_id, cpu);
+
+	mutex_unlock(&phy_dev_list_mutex);
+
+	return 0;
+
+err_ret_free:
+	kfree(phy_dev_entry);
+err_ret_unlock:
+	mutex_unlock(&phy_dev_list_mutex);
+
+err_ret:
+	return err;
+}
+
+static int pkg_temp_thermal_device_remove(unsigned int cpu)
+{
+	struct phy_dev_entry *n;
+	u16 phys_proc_id = topology_physical_package_id(cpu);
+	struct phy_dev_entry *phdev =
+			pkg_temp_thermal_get_phy_entry(cpu);
+
+	if (!phdev)
+		return -ENODEV;
+
+	mutex_lock(&phy_dev_list_mutex);
+	/* If we are loosing the first cpu for this package, we need change */
+	if (phdev->first_cpu == cpu) {
+		phdev->first_cpu = find_siblings_cpu(cpu);
+		pr_debug("thermal_device_remove: first cpu switched %d\n",
+					phdev->first_cpu);
+	}
+	/*
+	* It is possible that no siblings left as this was the last cpu
+	* going offline. We don't need to worry about this assignment
+	* as the phydev entry will be removed in this case and
+	* thermal zone is removed.
+	*/
+	--phdev->ref_cnt;
+	pr_debug("thermal_device_remove: pkg: %d cpu %d ref_cnt %d\n",
+					phys_proc_id, cpu, phdev->ref_cnt);
+	if (!phdev->ref_cnt)
+		list_for_each_entry_safe(phdev, n, &phy_dev_list, list) {
+			if (phdev->phys_proc_id == phys_proc_id) {
+				thermal_zone_device_unregister(phdev->tzone);
+				list_del(&phdev->list);
+				kfree(phdev);
+				break;
+			}
+		}
+	mutex_unlock(&phy_dev_list_mutex);
+
+	return 0;
+}
+
+static int get_core_online(unsigned int cpu)
+{
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+	struct phy_dev_entry *phdev = pkg_temp_thermal_get_phy_entry(cpu);
+
+	/* Check if there is already an instance for this package */
+	if (!phdev) {
+		if (!cpu_has(c, X86_FEATURE_DTHERM) &&
+					!cpu_has(c, X86_FEATURE_PTS))
+			return -ENODEV;
+		if (pkg_temp_thermal_device_add(cpu))
+			return -ENODEV;
+	} else {
+		mutex_lock(&phy_dev_list_mutex);
+		++phdev->ref_cnt;
+		pr_debug("get_core_online: cpu %d ref_cnt %d\n",
+						cpu, phdev->ref_cnt);
+		mutex_unlock(&phy_dev_list_mutex);
+	}
+	INIT_DELAYED_WORK(&per_cpu(pkg_temp_thermal_threshold_work, cpu),
+			pkg_temp_thermal_threshold_work_fn);
+
+	pr_debug("get_core_online: cpu %d successful\n", cpu);
+
+	return 0;
+}
+
+static void put_core_offline(unsigned int cpu)
+{
+	if (!pkg_temp_thermal_device_remove(cpu))
+		cancel_delayed_work_sync(
+			&per_cpu(pkg_temp_thermal_threshold_work, cpu));
+
+	pr_debug("put_core_offline: cpu %d\n", cpu);
+}
+
+static int pkg_temp_thermal_cpu_callback(struct notifier_block *nfb,
+				 unsigned long action, void *hcpu)
+{
+	unsigned int cpu = (unsigned long) hcpu;
+
+	switch (action) {
+	case CPU_ONLINE:
+	case CPU_DOWN_FAILED:
+		get_core_online(cpu);
+		break;
+	case CPU_DOWN_PREPARE:
+		put_core_offline(cpu);
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block pkg_temp_thermal_notifier __refdata = {
+	.notifier_call = pkg_temp_thermal_cpu_callback,
+};
+
+static const struct x86_cpu_id __initconst pkg_temp_thermal_ids[] = {
+	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM },
+	{}
+};
+MODULE_DEVICE_TABLE(x86cpu, pkg_temp_thermal_ids);
+
+static int __init pkg_temp_thermal_init(void)
+{
+	int i;
+
+	if (!x86_match_cpu(pkg_temp_thermal_ids))
+		return -ENODEV;
+
+	spin_lock_init(&pkg_work_lock);
+	platform_thermal_package_notify =
+			pkg_temp_thermal_platform_thermal_notify;
+	platform_thermal_package_rate_control =
+			pkg_temp_thermal_platform_thermal_rate_control;
+
+	get_online_cpus();
+	for_each_online_cpu(i)
+		if (get_core_online(i))
+			goto err_ret;
+	register_hotcpu_notifier(&pkg_temp_thermal_notifier);
+	put_online_cpus();
+
+	pkg_temp_debugfs_init(); /* Don't care if fails */
+
+	return 0;
+
+err_ret:
+	get_online_cpus();
+	for_each_online_cpu(i)
+		put_core_offline(i);
+	put_online_cpus();
+	kfree(pkg_work_scheduled);
+	platform_thermal_package_notify = NULL;
+	platform_thermal_package_rate_control = NULL;
+
+	return -ENODEV;
+}
+
+static void __exit pkg_temp_thermal_exit(void)
+{
+	struct phy_dev_entry *phdev, *n;
+	int i;
+
+	get_online_cpus();
+	unregister_hotcpu_notifier(&pkg_temp_thermal_notifier);
+	mutex_lock(&phy_dev_list_mutex);
+	list_for_each_entry_safe(phdev, n, &phy_dev_list, list) {
+		/* Retore old MSR value for package thermal interrupt */
+		wrmsr_on_cpu(phdev->first_cpu,
+			MSR_IA32_PACKAGE_THERM_INTERRUPT,
+			phdev->start_pkg_therm_low,
+			phdev->start_pkg_therm_high);
+		thermal_zone_device_unregister(phdev->tzone);
+		list_del(&phdev->list);
+		kfree(phdev);
+	}
+	mutex_unlock(&phy_dev_list_mutex);
+	platform_thermal_package_notify = NULL;
+	platform_thermal_package_rate_control = NULL;
+	for_each_online_cpu(i)
+		cancel_delayed_work_sync(
+			&per_cpu(pkg_temp_thermal_threshold_work, i));
+	put_online_cpus();
+
+	kfree(pkg_work_scheduled);
+
+	debugfs_remove_recursive(debugfs);
+}
+
+module_init(pkg_temp_thermal_init)
+module_exit(pkg_temp_thermal_exit)
+
+MODULE_DESCRIPTION("X86 PKG TEMP Thermal Driver");
+MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>");
+MODULE_LICENSE("GPL v2");
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/3] Thermal: Documentation for x86 package temperature thermal driver
  2013-05-17 23:42 [PATCH 0/3] CPU Package temperarure thermal driver (v02) Srinivas Pandruvada
  2013-05-17 23:42 ` [PATCH 1/3] x86, mcheck, therm_throt: Process package thresholds Srinivas Pandruvada
  2013-05-17 23:42 ` [PATCH 2/3] Thermal: CPU Package temperature thermal Srinivas Pandruvada
@ 2013-05-17 23:42 ` Srinivas Pandruvada
  2013-05-28  2:38 ` [PATCH 0/3] CPU Package temperarure thermal driver (v02) Zhang Rui
  2013-06-13  2:17 ` Zhang Rui
  4 siblings, 0 replies; 9+ messages in thread
From: Srinivas Pandruvada @ 2013-05-17 23:42 UTC (permalink / raw)
  To: linux-pm
  Cc: eduardo.valentin, rui.zhang, tony.luck, linux-edac, Srinivas Pandruvada

Added documentation describing details of the x86 package temperature
thermal driver.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
 Documentation/thermal/x86_pkg_temperature_thermal | 47 +++++++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/thermal/x86_pkg_temperature_thermal

diff --git a/Documentation/thermal/x86_pkg_temperature_thermal b/Documentation/thermal/x86_pkg_temperature_thermal
new file mode 100644
index 0000000..17a3a4c
--- /dev/null
+++ b/Documentation/thermal/x86_pkg_temperature_thermal
@@ -0,0 +1,47 @@
+Kernel driver: x86_pkg_temp_thermal
+===================
+
+Supported chips:
+* x86: with package level thermal management
+(Verify using: CPUID.06H:EAX[bit 6] =1)
+
+Authors: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+
+Reference
+---
+Intel® 64 and IA-32 Architectures Software Developer’s Manual (Jan, 2013):
+Chapter 14.6: PACKAGE LEVEL THERMAL MANAGEMENT
+
+Description
+---------
+
+This driver register CPU digital temperature package level sensor as a thermal
+zone with maximum two user mode configurable trip points. Number of trip points
+depends on the capability of the package. Once the trip point is violated,
+user mode can receive notification via thermal notification mechanism and can
+take any action to control temperature.
+
+
+Threshold management
+--------------------
+Each package will register as a thermal zone under /sys/class/thermal.
+Example:
+/sys/class/thermal/thermal_zone1
+
+This contains two trip points:
+- trip_point_0_temp
+- trip_point_1_temp
+
+User can set any temperature between 0 to TJ-Max temperature. Temperature units
+are in milli-degree Celsius. Refer to "Documentation/thermal/sysfs-api.txt" for
+thermal sys-fs details.
+
+Any value other than 0 in these trip points, can trigger thermal notifications.
+Setting 0, stops sending thermal notifications.
+
+Thermal notifications: To get kobject-uevent notifications, set the thermal zone
+policy to "user_space". For example: echo -n "user_space" > policy
+
+
+
+
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] CPU Package temperarure thermal driver (v02)
  2013-05-17 23:42 [PATCH 0/3] CPU Package temperarure thermal driver (v02) Srinivas Pandruvada
                   ` (2 preceding siblings ...)
  2013-05-17 23:42 ` [PATCH 3/3] Thermal: Documentation for x86 package temperature thermal driver Srinivas Pandruvada
@ 2013-05-28  2:38 ` Zhang Rui
  2013-05-28 15:17   ` Srinivas Pandruvada
  2013-06-13  2:17 ` Zhang Rui
  4 siblings, 1 reply; 9+ messages in thread
From: Zhang Rui @ 2013-05-28  2:38 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: linux-pm, eduardo.valentin, tony.luck, linux-edac

On Fri, 2013-05-17 at 16:42 -0700, Srinivas Pandruvada wrote:
> This driver register CPU digital temperature package level sensor as a
> thermal zone with two user mode configurable trip points. Once
> the trip point is violated, user mode can receive notification via thermal
> notification mechanism and can take any action to control temperature.
> 
I'm okay with this patch set.
But I'm wondering who should take patch 1/3?

thanks,
rui
> Changes:
> v02:
> Did majority of changes suggested by Eduardo Valentin. Main changes are:
> - Module parameters for rate control delay
> - Removed user space gov parameter in thermal_zone_register
> - Changes related to returning of errors values
> - Error code return values
> 
> v01:
> First version for review
> 
> Background:
> This set of changes were done to coretemp driver and posted to lm_sensors
> mailing list on 04/04/2013. This was reviewed by Guenter Roeck from lm-sensors
> and Zhang Rui (thermal maintainer). They were in agreement not to add notification
> mechanism to coretemp driver but use thermal sysfs.
> Guenter Roeck suggested to use approach like "db8500_thermal driver in drivers/thermal".
> So resubmitting the driver as a thermal zone driver.
> Previous discussion link:
> http://comments.gmane.org/gmane.linux.drivers.sensors/32182
> " 
> This is clear that there is reluctance in adding thresholds in coretemp sysfs,
> during previous attempts. Probably because of lake of use cases.
> But this time use case may be more compelling.
> 
> We have many small form factor devices like ultrabooks, slate PCs in the market.
> Unfortunately these devices reach maximum temperature with relatively less
> workloads, causing BIOS to do thermal throttling. There are real performance
> issues due to aggressive BIOS action to control thermals and also thermal breakdown
> in some cases.
> 
> Even the most expensive laptops, don't have correct ACPI thermal configuration,
> so that kernel thermal driver can act. In some case even the trip point is higher
> than critical temperature setting.
> 
> Intel has developed several drivers, which can be used to cool the system very efficiently.
> They include RAPL based cooling driver, Powerclamp driver and P state driver.
> To utilize these cooling device a closed loop user mode program is required, which
> will utilize these method and dynamically compensate for high CPU temperatures,
> without relying on any configuration data.
> One such solution is developed is "Linux thermal daemon". More details can be
> obtained from 
> "https://github.com/01org/thermal_daemon/blob/master/ThermalDaemon_Introduction.pdf".
> This daemon polls for cpu temperature and apply compensation once the CPU reach target
> temperature. 
> 
> This polling can be mostly avoided, by getting notification for the temperature, where
> it needs to wake up and get ready for apply compensation. In most of the normal use 
> cases, there may not be any threshold events. So very minimal number of user space
> notification for thermal thresholds.
> 
> Srinivas Pandruvada (3):
>   x86, mcheck, therm_throt: Process package thresholds
>   Thermal: CPU Package temperature thermal
>   Thermal: Documentation for x86 package temperature thermal driver
> 
>  Documentation/thermal/x86_pkg_temperature_thermal |  47 ++
>  arch/x86/include/asm/mce.h                        |   7 +
>  arch/x86/kernel/cpu/mcheck/therm_throt.c          |  63 ++-
>  drivers/thermal/Kconfig                           |  12 +
>  drivers/thermal/Makefile                          |   2 +-
>  drivers/thermal/x86_pkg_temp_thermal.c            | 642 ++++++++++++++++++++++
>  6 files changed, 768 insertions(+), 5 deletions(-)
>  create mode 100644 Documentation/thermal/x86_pkg_temperature_thermal
>  create mode 100644 drivers/thermal/x86_pkg_temp_thermal.c
> 



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] CPU Package temperarure thermal driver (v02)
  2013-05-28  2:38 ` [PATCH 0/3] CPU Package temperarure thermal driver (v02) Zhang Rui
@ 2013-05-28 15:17   ` Srinivas Pandruvada
  2013-05-28 15:56     ` Tony Luck
  0 siblings, 1 reply; 9+ messages in thread
From: Srinivas Pandruvada @ 2013-05-28 15:17 UTC (permalink / raw)
  To: Zhang Rui, tony.luck; +Cc: linux-pm, eduardo.valentin, linux-edac

Tony Luck is the maintainer and he did review once and gave comments.

Hi Tony,

Do you have further comments?

Thanks,
Srinivas

On 05/27/2013 07:38 PM, Zhang Rui wrote:
> On Fri, 2013-05-17 at 16:42 -0700, Srinivas Pandruvada wrote:
>> This driver register CPU digital temperature package level sensor as a
>> thermal zone with two user mode configurable trip points. Once
>> the trip point is violated, user mode can receive notification via thermal
>> notification mechanism and can take any action to control temperature.
>>
> I'm okay with this patch set.
> But I'm wondering who should take patch 1/3?
>
> thanks,
> rui
>> Changes:
>> v02:
>> Did majority of changes suggested by Eduardo Valentin. Main changes are:
>> - Module parameters for rate control delay
>> - Removed user space gov parameter in thermal_zone_register
>> - Changes related to returning of errors values
>> - Error code return values
>>
>> v01:
>> First version for review
>>
>> Background:
>> This set of changes were done to coretemp driver and posted to lm_sensors
>> mailing list on 04/04/2013. This was reviewed by Guenter Roeck from lm-sensors
>> and Zhang Rui (thermal maintainer). They were in agreement not to add notification
>> mechanism to coretemp driver but use thermal sysfs.
>> Guenter Roeck suggested to use approach like "db8500_thermal driver in drivers/thermal".
>> So resubmitting the driver as a thermal zone driver.
>> Previous discussion link:
>> http://comments.gmane.org/gmane.linux.drivers.sensors/32182
>> "
>> This is clear that there is reluctance in adding thresholds in coretemp sysfs,
>> during previous attempts. Probably because of lake of use cases.
>> But this time use case may be more compelling.
>>
>> We have many small form factor devices like ultrabooks, slate PCs in the market.
>> Unfortunately these devices reach maximum temperature with relatively less
>> workloads, causing BIOS to do thermal throttling. There are real performance
>> issues due to aggressive BIOS action to control thermals and also thermal breakdown
>> in some cases.
>>
>> Even the most expensive laptops, don't have correct ACPI thermal configuration,
>> so that kernel thermal driver can act. In some case even the trip point is higher
>> than critical temperature setting.
>>
>> Intel has developed several drivers, which can be used to cool the system very efficiently.
>> They include RAPL based cooling driver, Powerclamp driver and P state driver.
>> To utilize these cooling device a closed loop user mode program is required, which
>> will utilize these method and dynamically compensate for high CPU temperatures,
>> without relying on any configuration data.
>> One such solution is developed is "Linux thermal daemon". More details can be
>> obtained from
>> "https://github.com/01org/thermal_daemon/blob/master/ThermalDaemon_Introduction.pdf".
>> This daemon polls for cpu temperature and apply compensation once the CPU reach target
>> temperature.
>>
>> This polling can be mostly avoided, by getting notification for the temperature, where
>> it needs to wake up and get ready for apply compensation. In most of the normal use
>> cases, there may not be any threshold events. So very minimal number of user space
>> notification for thermal thresholds.
>>
>> Srinivas Pandruvada (3):
>>    x86, mcheck, therm_throt: Process package thresholds
>>    Thermal: CPU Package temperature thermal
>>    Thermal: Documentation for x86 package temperature thermal driver
>>
>>   Documentation/thermal/x86_pkg_temperature_thermal |  47 ++
>>   arch/x86/include/asm/mce.h                        |   7 +
>>   arch/x86/kernel/cpu/mcheck/therm_throt.c          |  63 ++-
>>   drivers/thermal/Kconfig                           |  12 +
>>   drivers/thermal/Makefile                          |   2 +-
>>   drivers/thermal/x86_pkg_temp_thermal.c            | 642 ++++++++++++++++++++++
>>   6 files changed, 768 insertions(+), 5 deletions(-)
>>   create mode 100644 Documentation/thermal/x86_pkg_temperature_thermal
>>   create mode 100644 drivers/thermal/x86_pkg_temp_thermal.c
>>
>
> --
> 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
>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] CPU Package temperarure thermal driver (v02)
  2013-05-28 15:17   ` Srinivas Pandruvada
@ 2013-05-28 15:56     ` Tony Luck
  2013-05-28 18:26       ` Srinivas Pandruvada
  0 siblings, 1 reply; 9+ messages in thread
From: Tony Luck @ 2013-05-28 15:56 UTC (permalink / raw)
  To: Srinivas Pandruvada
  Cc: Zhang Rui, Linux PM mailing list, eduardo.valentin,
	Linux Edac Mailing List

On Tue, May 28, 2013 at 8:17 AM, Srinivas Pandruvada
<srinivas.pandruvada@linux.intel.com> wrote:
> Tony Luck is the maintainer and he did review once and gave comments.
>
> Hi Tony,
>
> Do you have further comments?

I think this looks OK.  Have you done any testing on the server end of the
spectrum - 2 or 4 socket Sandy Bridge or Ivy Bridge.

-Tony

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] CPU Package temperarure thermal driver (v02)
  2013-05-28 15:56     ` Tony Luck
@ 2013-05-28 18:26       ` Srinivas Pandruvada
  0 siblings, 0 replies; 9+ messages in thread
From: Srinivas Pandruvada @ 2013-05-28 18:26 UTC (permalink / raw)
  To: Tony Luck
  Cc: Zhang Rui, Linux PM mailing list, eduardo.valentin,
	Linux Edac Mailing List

On 05/28/2013 08:56 AM, Tony Luck wrote:
> On Tue, May 28, 2013 at 8:17 AM, Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com> wrote:
>> Tony Luck is the maintainer and he did review once and gave comments.
>>
>> Hi Tony,
>>
>> Do you have further comments?
> I think this looks OK.  Have you done any testing on the server end of the
> spectrum - 2 or 4 socket Sandy Bridge or Ivy Bridge.
>
> -Tony
> --
> 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
>
I tested on Romley (Sandy Bridge) with 2 sockets.

Thanks,
Srinivas


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/3] CPU Package temperarure thermal driver (v02)
  2013-05-17 23:42 [PATCH 0/3] CPU Package temperarure thermal driver (v02) Srinivas Pandruvada
                   ` (3 preceding siblings ...)
  2013-05-28  2:38 ` [PATCH 0/3] CPU Package temperarure thermal driver (v02) Zhang Rui
@ 2013-06-13  2:17 ` Zhang Rui
  4 siblings, 0 replies; 9+ messages in thread
From: Zhang Rui @ 2013-06-13  2:17 UTC (permalink / raw)
  To: Srinivas Pandruvada; +Cc: linux-pm, eduardo.valentin, tony.luck, linux-edac

On Fri, 2013-05-17 at 16:42 -0700, Srinivas Pandruvada wrote:
> This driver register CPU digital temperature package level sensor as a
> thermal zone with two user mode configurable trip points. Once
> the trip point is violated, user mode can receive notification via thermal
> notification mechanism and can take any action to control temperature.
> 
the whole patch series has been applied.

thanks,
rui

> Changes:
> v02:
> Did majority of changes suggested by Eduardo Valentin. Main changes are:
> - Module parameters for rate control delay
> - Removed user space gov parameter in thermal_zone_register
> - Changes related to returning of errors values
> - Error code return values
> 
> v01:
> First version for review
> 
> Background:
> This set of changes were done to coretemp driver and posted to lm_sensors
> mailing list on 04/04/2013. This was reviewed by Guenter Roeck from lm-sensors
> and Zhang Rui (thermal maintainer). They were in agreement not to add notification
> mechanism to coretemp driver but use thermal sysfs.
> Guenter Roeck suggested to use approach like "db8500_thermal driver in drivers/thermal".
> So resubmitting the driver as a thermal zone driver.
> Previous discussion link:
> http://comments.gmane.org/gmane.linux.drivers.sensors/32182
> " 
> This is clear that there is reluctance in adding thresholds in coretemp sysfs,
> during previous attempts. Probably because of lake of use cases.
> But this time use case may be more compelling.
> 
> We have many small form factor devices like ultrabooks, slate PCs in the market.
> Unfortunately these devices reach maximum temperature with relatively less
> workloads, causing BIOS to do thermal throttling. There are real performance
> issues due to aggressive BIOS action to control thermals and also thermal breakdown
> in some cases.
> 
> Even the most expensive laptops, don't have correct ACPI thermal configuration,
> so that kernel thermal driver can act. In some case even the trip point is higher
> than critical temperature setting.
> 
> Intel has developed several drivers, which can be used to cool the system very efficiently.
> They include RAPL based cooling driver, Powerclamp driver and P state driver.
> To utilize these cooling device a closed loop user mode program is required, which
> will utilize these method and dynamically compensate for high CPU temperatures,
> without relying on any configuration data.
> One such solution is developed is "Linux thermal daemon". More details can be
> obtained from 
> "https://github.com/01org/thermal_daemon/blob/master/ThermalDaemon_Introduction.pdf".
> This daemon polls for cpu temperature and apply compensation once the CPU reach target
> temperature. 
> 
> This polling can be mostly avoided, by getting notification for the temperature, where
> it needs to wake up and get ready for apply compensation. In most of the normal use 
> cases, there may not be any threshold events. So very minimal number of user space
> notification for thermal thresholds.
> 
> Srinivas Pandruvada (3):
>   x86, mcheck, therm_throt: Process package thresholds
>   Thermal: CPU Package temperature thermal
>   Thermal: Documentation for x86 package temperature thermal driver
> 
>  Documentation/thermal/x86_pkg_temperature_thermal |  47 ++
>  arch/x86/include/asm/mce.h                        |   7 +
>  arch/x86/kernel/cpu/mcheck/therm_throt.c          |  63 ++-
>  drivers/thermal/Kconfig                           |  12 +
>  drivers/thermal/Makefile                          |   2 +-
>  drivers/thermal/x86_pkg_temp_thermal.c            | 642 ++++++++++++++++++++++
>  6 files changed, 768 insertions(+), 5 deletions(-)
>  create mode 100644 Documentation/thermal/x86_pkg_temperature_thermal
>  create mode 100644 drivers/thermal/x86_pkg_temp_thermal.c
> 



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-06-13  2:17 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-17 23:42 [PATCH 0/3] CPU Package temperarure thermal driver (v02) Srinivas Pandruvada
2013-05-17 23:42 ` [PATCH 1/3] x86, mcheck, therm_throt: Process package thresholds Srinivas Pandruvada
2013-05-17 23:42 ` [PATCH 2/3] Thermal: CPU Package temperature thermal Srinivas Pandruvada
2013-05-17 23:42 ` [PATCH 3/3] Thermal: Documentation for x86 package temperature thermal driver Srinivas Pandruvada
2013-05-28  2:38 ` [PATCH 0/3] CPU Package temperarure thermal driver (v02) Zhang Rui
2013-05-28 15:17   ` Srinivas Pandruvada
2013-05-28 15:56     ` Tony Luck
2013-05-28 18:26       ` Srinivas Pandruvada
2013-06-13  2:17 ` Zhang Rui

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).