cpufreq: add sysfs interface
PATCH 1/1 cpufreq: add sysfs interface
rediffed for 2.5.57
This patch adds a sysfs interface to the cpufreq core, and marks the previous /proc/cpufreq interface as deprecated.
As in drivers/base/cpu.c a "CPU driver" is registered, cpufreq acts as "interface" to this, offering the following files for each CPU (in /system/devices/sys/cpu.../) where CPUfreq support is present
cpuinfo_min_freq (ro) - minimum frequency (in kHz) the CPU supportscpuinfo_max_freq (ro) - maximum frequency (in kHz) the CPU supportsscaling_min_freq (rw) - minimum frequency (in kHz) cpufreq may scale
the CPU core toscaling_max_freq (rw) - maximum frequency (in kHz) cpufreq may scale
the CPU core toscaling_governor (rw) - governor == "A feedback device on a machine
or engine that is used to provide automatic control, as of speed, pressure, or temperature" [1, as noted by David Kimdon]. Decides what frequency is used. Currently, only "performance" and "powersave" are supported, more may be added later.
(In future, a file scaling_driver (ro) which shows what CPUfreq driver is used (arm-sa1100, gx-suspmod, speedstep, longrun, powernow-k6, ...) might be added, and this driver will be allowed to add files scaling_driver_* for driver-specific settings like "prefer fast FSB". And scaling_governor_* files might offer settings for the governor.)
To implement this sysfs interface, the driver model "interface" code is used. Unfortunately, it has a non-trivial locking bug in drivers/base/intf.c: there's a down_write call for cls->subsys.rwsem in add_intf(), which then calls add(), which may call intf->add_device(), which may call interface_add_data(), which calls kobject_register(), which calls kobject_add(), which then tries to down_write cls->subsys.rwsem. Remember, that was already locked writable in add_intf().
Because of that, interface_add_data() is commented out; this means that no link in /system/class/cpu/cpufreq is added, and that the dev-removal code isn't called. This shouldn't be a problem yet, though; as no cpufreq driver I know of is capable of CPU hotplugging.
Dominik
[1] http://dictionary.reference.com/search?q=governor
arch/i386/Kconfig +15 -3
@@ -949,15 +949,27 @@ If in doubt, say N. +config CPU_FREQ_PROC_INTF + bool "/proc/cpufreq interface (DEPRECATED)" + depends on CPU_FREQ && PROC_FS + help + This enables the /proc/cpufreq interface for controlling + CPUFreq. Please note that it is recommended to use the sysfs + interface instead (which is built automatically). + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + config CPU_FREQ_24_API bool "/proc/sys/cpu/ interface (2.4. / OLD)" depends on CPU_FREQ help This enables the /proc/sys/cpu/ sysctl interface for controlling CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. 2.5 - uses /proc/cpufreq instead. Please note that some drivers do not - work well with the 2.4. /proc/sys/cpu sysctl interface, so if in - doubt, say N here. + uses a sysfs interface instead. Please note that some drivers do + not work well with the 2.4. /proc/sys/cpu sysctl interface, + so if in doubt, say N here. For details, take a look at linux/Documentation/cpufreq.
include/linux/cpufreq.h +2 -0
@@ -17,6 +17,7 @@#include <linux/config.h> #include <linux/notifier.h> #include <linux/threads.h> +#include <linux/device.h> /*********************************************************************
@@ -57,6 +58,7 @@unsigned int max;/* in kHz */ unsigned int policy;/* see above */ struct cpufreq_cpuinfo cpuinfo;/* see above */ +struct intf_data intf;/* interface data */ };#define CPUFREQ_ADJUST (0)
kernel/cpufreq.c +265 -43
395 lines not on this page · raw message
Quoted 4 lines · Dominik Brodowski
rediffed for 2.5.57
This patch adds a sysfs interface to the cpufreq core, and marks the previous
/proc/cpufreqinterface as deprecated.
The following updates the patch to reflect the sysfs changes currently in Linus's BK tree (reinstating the count parameter to sysfs store() methods).
-pat
===== arch/i386/Kconfig 1.30 vs edited =====
arch/i386/Kconfig +15 -3
@@ -949,15 +949,27 @@ If in doubt, say N. +config CPU_FREQ_PROC_INTF + bool "/proc/cpufreq interface (DEPRECATED)" + depends on CPU_FREQ && PROC_FS + help + This enables the /proc/cpufreq interface for controlling + CPUFreq. Please note that it is recommended to use the sysfs + interface instead (which is built automatically). + + For details, take a look at linux/Documentation/cpufreq. + + If in doubt, say N. + config CPU_FREQ_24_API bool "/proc/sys/cpu/ interface (2.4. / OLD)" depends on CPU_FREQ help This enables the /proc/sys/cpu/ sysctl interface for controlling CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. 2.5 - uses /proc/cpufreq instead. Please note that some drivers do not - work well with the 2.4. /proc/sys/cpu sysctl interface, so if in - doubt, say N here. + uses a sysfs interface instead. Please note that some drivers do + not work well with the 2.4. /proc/sys/cpu sysctl interface, + so if in doubt, say N here. For details, take a look at linux/Documentation/cpufreq.
===== include/linux/cpufreq.h 1.9 vs edited =====
include/linux/cpufreq.h +2 -0
@@ -17,6 +17,7 @@#include <linux/config.h> #include <linux/notifier.h> #include <linux/threads.h> +#include <linux/device.h> /*********************************************************************
@@ -57,6 +58,7 @@unsigned int max;/* in kHz */ unsigned int policy;/* see above */ struct cpufreq_cpuinfo cpuinfo;/* see above */ +struct intf_data intf;/* interface data */ };#define CPUFREQ_ADJUST (0)
===== kernel/cpufreq.c 1.10 vs edited =====
kernel/cpufreq.c +266 -43
396 lines not on this page · raw message
PATCH 1/1 work around deadlock in add_intf
hi :)
the note for cpufreq sysfs support regarding locking in add_intf has bitten me, too
i don't have a really good idea how to change the locking so that it just works, so i wrote a workaround
the following patch allows to add interfaces again for me, it just deferres the actual device additions:
linux-rc/drivers/base/intf.c Thu Jan 16 11:13:19 2003 renamed from linux-2.5/drivers/base/intf.c Mon Jan 13 09:49:02 2003 +30 -2
@@ -132,6 +132,22 @@ /** + * delayed_add - version of add() called via schedule_work + * @_data: pointer to arguments + */ +static void delayed_add(void *_data) +{ + struct { + struct device_interface *intf; + struct device *dev; + struct work_struct work; + } *data = _data; + + add(data->intf, data->dev); + kfree(data); +} + +/** * add_intf - add class's devices to interface. * @intf: interface. *
@@ -142,12 +158,24 @@ */ static void add_intf(struct device_interface * intf) { + struct { + struct device_interface *intf; + struct device *dev; + struct work_struct work; + } *data; struct device_class * cls = intf->devclass; struct list_head * entry; down_write(&cls->subsys.rwsem); - list_for_each(entry,&cls->devices.list) - add(intf,to_dev(entry)); + list_for_each(entry,&cls->devices.list) { + /* add will lock subsys.rwsem via interface_add_data, */ + /* do it after lock is released */ + data = kmalloc(sizeof(*data), GFP_KERNEL); + INIT_WORK(&data->work, delayed_add, data); + data->intf = intf; + data->dev = to_dev(entry); + schedule_work(&data->work); + } up_write(&cls->subsys.rwsem); }
Signature · 9 lines
CU, / Friedrich-Alexander University Erlangen, Germany Martin Waitz // [Tali on IRCnet] [tali.home.pages.de] _________ ______________/// - - - - - - - - - - - - - - - - - - - - /// dies ist eine manuell generierte mail, sie beinhaltet // tippfehler und ist auch ohne grossbuchstaben gueltig. / - Wer bereit ist, grundlegende Freiheiten aufzugeben, um sich kurzfristige Sicherheit zu verschaffen, der hat weder Freiheit noch Sicherheit verdient. Benjamin Franklin (1706 - 1790)