Skip to content

Commit

Permalink
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…rzhang/linux

Pull thermal management updates from Zhang Rui:
 "This time we only have a few changes as there are no soc thermal
  changes from Eduardo.  The only big change is the introduction of
  TMON, a tool to help visualize, tune, and test the thermal subsystem.
  The rest is mostly cleanups and fixes all over.

  Specifics:

   - introduce TMON, a tool base on thermal sysfs I/F.  It can be used
     to visualize, tune and test the thermal subsystem.

   - fix a zone/cooling device binding problem, when both thermal zone
     bind parameters and .bind() callback are available"

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux:
  tools/thermal: Introduce tmon, a tool for thermal subsystem
  thermal: Fix binding problem when there is thermal zone params
  thermal: cpu_cooling: fix return value check in cpufreq_cooling_register()
  Thermal: Check for validity before doing kfree
  thermal/intel_powerclamp: Add newer CPU models
  Thermal: Tidy up error handling in powerclamp_init
  thermal: Kconfig: cosmetic fixes
  ACPI/thermal : Remove zone disabled warning
  typo in drivers/thermal/Kconfig: lpatform instead of platform
  • Loading branch information
Linus Torvalds committed Nov 14, 2013
2 parents 2f466d3 + 86e0a0b commit 549608e
Show file tree
Hide file tree
Showing 14 changed files with 2,216 additions and 19 deletions.
10 changes: 5 additions & 5 deletions drivers/acpi/thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,10 +514,9 @@ static void acpi_thermal_check(void *data)
{
struct acpi_thermal *tz = data;

if (!tz->tz_enabled) {
pr_warn("thermal zone is disabled \n");
if (!tz->tz_enabled)
return;
}

thermal_zone_device_update(tz->thermal_zone);
}

Expand Down Expand Up @@ -569,9 +568,10 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
*/
if (mode == THERMAL_DEVICE_ENABLED)
enable = 1;
else if (mode == THERMAL_DEVICE_DISABLED)
else if (mode == THERMAL_DEVICE_DISABLED) {
enable = 0;
else
pr_warn("thermal zone will be disabled\n");
} else
return -EINVAL;

if (enable != tz->tz_enabled) {
Expand Down
7 changes: 4 additions & 3 deletions drivers/thermal/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ config THERMAL_DEFAULT_GOV_USER_SPACE
select THERMAL_GOV_USER_SPACE
help
Select this if you want to let the user space manage the
lpatform thermals.
platform thermals.

endchoice

Expand All @@ -69,6 +69,7 @@ config THERMAL_GOV_STEP_WISE
bool "Step_wise thermal governor"
help
Enable this to manage platform thermals using a simple linear
governor.

config THERMAL_GOV_USER_SPACE
bool "User_space thermal governor"
Expand Down Expand Up @@ -116,14 +117,14 @@ config SPEAR_THERMAL
depends on OF
help
Enable this to plug the SPEAr thermal sensor driver into the Linux
thermal framework
thermal framework.

config RCAR_THERMAL
tristate "Renesas R-Car thermal driver"
depends on ARCH_SHMOBILE
help
Enable this to plug the R-Car thermal sensor driver into the Linux
thermal framework
thermal framework.

config KIRKWOOD_THERMAL
tristate "Temperature sensor on Marvell Kirkwood SoCs"
Expand Down
4 changes: 2 additions & 2 deletions drivers/thermal/cpu_cooling.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,10 +469,10 @@ cpufreq_cooling_register(const struct cpumask *clip_cpus)

cool_dev = thermal_cooling_device_register(dev_name, cpufreq_dev,
&cpufreq_cooling_ops);
if (!cool_dev) {
if (IS_ERR(cool_dev)) {
release_idr(&cpufreq_idr, cpufreq_dev->id);
kfree(cpufreq_dev);
return ERR_PTR(-EINVAL);
return cool_dev;
}
cpufreq_dev->cool_dev = cool_dev;
cpufreq_dev->cpufreq_state = 0;
Expand Down
29 changes: 26 additions & 3 deletions drivers/thermal/intel_powerclamp.c
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,11 @@ static const struct x86_cpu_id intel_powerclamp_ids[] = {
{ X86_VENDOR_INTEL, 6, 0x2e},
{ X86_VENDOR_INTEL, 6, 0x2f},
{ X86_VENDOR_INTEL, 6, 0x3a},
{ X86_VENDOR_INTEL, 6, 0x3c},
{ X86_VENDOR_INTEL, 6, 0x3e},
{ X86_VENDOR_INTEL, 6, 0x3f},
{ X86_VENDOR_INTEL, 6, 0x45},
{ X86_VENDOR_INTEL, 6, 0x46},
{}
};
MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
Expand Down Expand Up @@ -758,21 +763,39 @@ static int powerclamp_init(void)
/* probe cpu features and ids here */
retval = powerclamp_probe();
if (retval)
return retval;
goto exit_free;

/* set default limit, maybe adjusted during runtime based on feedback */
window_size = 2;
register_hotcpu_notifier(&powerclamp_cpu_notifier);

powerclamp_thread = alloc_percpu(struct task_struct *);
if (!powerclamp_thread) {
retval = -ENOMEM;
goto exit_unregister;
}

cooling_dev = thermal_cooling_device_register("intel_powerclamp", NULL,
&powerclamp_cooling_ops);
if (IS_ERR(cooling_dev))
return -ENODEV;
if (IS_ERR(cooling_dev)) {
retval = -ENODEV;
goto exit_free_thread;
}

if (!duration)
duration = jiffies_to_msecs(DEFAULT_DURATION_JIFFIES);

powerclamp_create_debug_files();

return 0;

exit_free_thread:
free_percpu(powerclamp_thread);
exit_unregister:
unregister_hotcpu_notifier(&powerclamp_cpu_notifier);
exit_free:
kfree(cpu_clamping_mask);
return retval;
}
module_init(powerclamp_init);

Expand Down
10 changes: 6 additions & 4 deletions drivers/thermal/thermal_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,11 @@ static void bind_cdev(struct thermal_cooling_device *cdev)
if (!pos->tzp && !pos->ops->bind)
continue;

if (!pos->tzp && pos->ops->bind) {
if (pos->ops->bind) {
ret = pos->ops->bind(pos, cdev);
if (ret)
print_bind_err_msg(pos, cdev, ret);
continue;
}

tzp = pos->tzp;
Expand Down Expand Up @@ -282,8 +283,8 @@ static void bind_tz(struct thermal_zone_device *tz)

mutex_lock(&thermal_list_lock);

/* If there is no platform data, try to use ops->bind */
if (!tzp && tz->ops->bind) {
/* If there is ops->bind, try to use ops->bind */
if (tz->ops->bind) {
list_for_each_entry(pos, &thermal_cdev_list, node) {
ret = tz->ops->bind(tz, pos);
if (ret)
Expand Down Expand Up @@ -1038,7 +1039,8 @@ static void thermal_release(struct device *dev)
sizeof("thermal_zone") - 1)) {
tz = to_thermal_zone(dev);
kfree(tz);
} else {
} else if(!strncmp(dev_name(dev), "cooling_device",
sizeof("cooling_device") - 1)){
cdev = to_cooling_device(dev);
kfree(cdev);
}
Expand Down
15 changes: 13 additions & 2 deletions tools/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ help:
@echo ' net - misc networking tools'
@echo ' vm - misc vm tools'
@echo ' x86_energy_perf_policy - Intel energy policy tool'
@echo ' tmon - thermal monitoring and tuning tool'
@echo ''
@echo 'You can do:'
@echo ' $$ make -C tools/ <tool>_install'
Expand Down Expand Up @@ -50,6 +51,9 @@ selftests: FORCE
turbostat x86_energy_perf_policy: FORCE
$(call descend,power/x86/$@)

tmon: FORCE
$(call descend,thermal/$@)

cpupower_install:
$(call descend,power/$(@:_install=),install)

Expand All @@ -62,9 +66,13 @@ selftests_install:
turbostat_install x86_energy_perf_policy_install:
$(call descend,power/x86/$(@:_install=),install)

tmon_install:
$(call descend,thermal/$(@:_install=),install)

install: cgroup_install cpupower_install firewire_install lguest_install \
perf_install selftests_install turbostat_install usb_install \
virtio_install vm_install net_install x86_energy_perf_policy_install
virtio_install vm_install net_install x86_energy_perf_policy_install \
tmon

cpupower_clean:
$(call descend,power/cpupower,clean)
Expand All @@ -84,8 +92,11 @@ selftests_clean:
turbostat_clean x86_energy_perf_policy_clean:
$(call descend,power/x86/$(@:_clean=),clean)

tmon_clean:
$(call descend,thermal/tmon,clean)

clean: cgroup_clean cpupower_clean firewire_clean lguest_clean perf_clean \
selftests_clean turbostat_clean usb_clean virtio_clean \
vm_clean net_clean x86_energy_perf_policy_clean
vm_clean net_clean x86_energy_perf_policy_clean tmon_clean

.PHONY: FORCE
47 changes: 47 additions & 0 deletions tools/thermal/tmon/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
VERSION = 1.0

BINDIR=usr/bin
WARNFLAGS=-Wall -Wshadow -W -Wformat -Wimplicit-function-declaration -Wimplicit-int
CFLAGS= -O1 ${WARNFLAGS} -fstack-protector
CC=gcc

CFLAGS+=-D VERSION=\"$(VERSION)\"
LDFLAGS+=
TARGET=tmon

INSTALL_PROGRAM=install -m 755 -p
DEL_FILE=rm -f

INSTALL_CONFIGFILE=install -m 644 -p
CONFIG_FILE=
CONFIG_PATH=


OBJS = tmon.o tui.o sysfs.o pid.o
OBJS +=

tmon: $(OBJS) Makefile tmon.h
$(CC) ${CFLAGS} $(LDFLAGS) $(OBJS) -o $(TARGET) -lm -lpanel -lncursesw -lpthread

valgrind: tmon
sudo valgrind -v --track-origins=yes --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./$(TARGET) 1> /dev/null

install:
- mkdir -p $(INSTALL_ROOT)/$(BINDIR)
- $(INSTALL_PROGRAM) "$(TARGET)" "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)"
- mkdir -p $(INSTALL_ROOT)/$(CONFIG_PATH)
- $(INSTALL_CONFIGFILE) "$(CONFIG_FILE)" "$(INSTALL_ROOT)/$(CONFIG_PATH)"

uninstall:
$(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/$(TARGET)"
$(CONFIG_FILE) "$(CONFIG_PATH)"


clean:
find . -name "*.o" | xargs $(DEL_FILE)
rm -f $(TARGET)

dist:
git tag v$(VERSION)
git archive --format=tar --prefix="$(TARGET)-$(VERSION)/" v$(VERSION) | \
gzip > $(TARGET)-$(VERSION).tar.gz
50 changes: 50 additions & 0 deletions tools/thermal/tmon/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
TMON - A Monitoring and Testing Tool for Linux kernel thermal subsystem

Why TMON?
==========
Increasingly, Linux is running on thermally constrained devices. The simple
thermal relationship between processor and fan has become past for modern
computers.

As hardware vendors cope with the thermal constraints on their products, more
and more sensors are added, new cooling capabilities are introduced. The
complexity of the thermal relationship can grow exponentially among cooling
devices, zones, sensors, and trip points. They can also change dynamically.

To expose such relationship to the userspace, Linux generic thermal layer
introduced sysfs entry at /sys/class/thermal with a matrix of symbolic
links, trip point bindings, and device instances. To traverse such
matrix by hand is not a trivial task. Testing is also difficult in that
thermal conditions are often exception cases that hard to reach in
normal operations.

TMON is conceived as a tool to help visualize, tune, and test the
complex thermal subsystem.

Files
=====
tmon.c : main function for set up and configurations.
tui.c : handles ncurses based user interface
sysfs.c : access to the generic thermal sysfs
pid.c : a proportional-integral-derivative (PID) controller
that can be used for thermal relationship training.

Requirements
============
Depends on ncurses

Build
=========
$ make
$ sudo ./tmon -h
Usage: tmon [OPTION...]
-c, --control cooling device in control
-d, --daemon run as daemon, no TUI
-l, --log log data to /var/tmp/tmon.log
-h, --help show this help message
-t, --time-interval set time interval for sampling
-v, --version show version
-g, --debug debug message in syslog

1. For monitoring only:
$ sudo ./tmon
Loading

0 comments on commit 549608e

Please sign in to comment.