aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/cpufreq_stats.c
diff options
context:
space:
mode:
authorAshok Raj <ashok.raj@intel.com>2005-10-30 17:59:54 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-30 20:37:14 -0500
commitc32b6b8e524d2c337767d312814484d9289550cf (patch)
tree02e634b0b48db6eccc8774369366daa1893921ea /drivers/cpufreq/cpufreq_stats.c
parentd434fca737bee0862625c2377b987a7713b6b487 (diff)
[PATCH] create and destroy cpufreq sysfs entries based on cpu notifiers
cpufreq entries in sysfs should only be populated when CPU is online state. When we either boot with maxcpus=x and then boot the other cpus by echoing to sysfs online file, these entries should be created and destroyed when CPU_DEAD is notified. Same treatement as cache entries under sysfs. We place the processor in the lowest frequency, so hw managed P-State transitions can still work on the other threads to save power. Primary goal was to just make these directories appear/disapper dynamically. There is one in this patch i had to do, which i really dont like myself but probably best if someone handling the cpufreq infrastructure could give this code right treatment if this is not acceptable. I guess its probably good for the first cut. - Converting lock_cpu_hotplug()/unlock_cpu_hotplug() to disable/enable preempt. The locking was smack in the middle of the notification path, when the hotplug is already holding the lock. I tried another solution to avoid this so avoid taking locks if we know we are from notification path. The solution was getting very ugly and i decided this was probably good for this iteration until someone who understands cpufreq could do a better job than me. (akpm: export cpucontrol to GPL modules: drivers/cpufreq/cpufreq_stats.c now does lock_cpu_hotplug()) Signed-off-by: Ashok Raj <ashok.raj@intel.com> Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com> Cc: Dave Jones <davej@codemonkey.org.uk> Cc: Zwane Mwaikambo <zwane@holomorphy.com> Cc: Greg KH <greg@kroah.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/cpufreq/cpufreq_stats.c')
-rw-r--r--drivers/cpufreq/cpufreq_stats.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 741b6b191e6a..3597f25d5efa 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -19,6 +19,7 @@
19#include <linux/percpu.h> 19#include <linux/percpu.h>
20#include <linux/kobject.h> 20#include <linux/kobject.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/notifier.h>
22#include <asm/cputime.h> 23#include <asm/cputime.h>
23 24
24static spinlock_t cpufreq_stats_lock; 25static spinlock_t cpufreq_stats_lock;
@@ -298,6 +299,27 @@ cpufreq_stat_notifier_trans (struct notifier_block *nb, unsigned long val,
298 return 0; 299 return 0;
299} 300}
300 301
302static int __cpuinit cpufreq_stat_cpu_callback(struct notifier_block *nfb,
303 unsigned long action, void *hcpu)
304{
305 unsigned int cpu = (unsigned long)hcpu;
306
307 switch (action) {
308 case CPU_ONLINE:
309 cpufreq_update_policy(cpu);
310 break;
311 case CPU_DEAD:
312 cpufreq_stats_free_table(cpu);
313 break;
314 }
315 return NOTIFY_OK;
316}
317
318static struct notifier_block cpufreq_stat_cpu_notifier =
319{
320 .notifier_call = cpufreq_stat_cpu_callback,
321};
322
301static struct notifier_block notifier_policy_block = { 323static struct notifier_block notifier_policy_block = {
302 .notifier_call = cpufreq_stat_notifier_policy 324 .notifier_call = cpufreq_stat_notifier_policy
303}; 325};
@@ -311,6 +333,7 @@ __init cpufreq_stats_init(void)
311{ 333{
312 int ret; 334 int ret;
313 unsigned int cpu; 335 unsigned int cpu;
336
314 spin_lock_init(&cpufreq_stats_lock); 337 spin_lock_init(&cpufreq_stats_lock);
315 if ((ret = cpufreq_register_notifier(&notifier_policy_block, 338 if ((ret = cpufreq_register_notifier(&notifier_policy_block,
316 CPUFREQ_POLICY_NOTIFIER))) 339 CPUFREQ_POLICY_NOTIFIER)))
@@ -323,20 +346,31 @@ __init cpufreq_stats_init(void)
323 return ret; 346 return ret;
324 } 347 }
325 348
326 for_each_cpu(cpu) 349 register_cpu_notifier(&cpufreq_stat_cpu_notifier);
327 cpufreq_update_policy(cpu); 350 lock_cpu_hotplug();
351 for_each_online_cpu(cpu) {
352 cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_ONLINE,
353 (void *)(long)cpu);
354 }
355 unlock_cpu_hotplug();
328 return 0; 356 return 0;
329} 357}
330static void 358static void
331__exit cpufreq_stats_exit(void) 359__exit cpufreq_stats_exit(void)
332{ 360{
333 unsigned int cpu; 361 unsigned int cpu;
362
334 cpufreq_unregister_notifier(&notifier_policy_block, 363 cpufreq_unregister_notifier(&notifier_policy_block,
335 CPUFREQ_POLICY_NOTIFIER); 364 CPUFREQ_POLICY_NOTIFIER);
336 cpufreq_unregister_notifier(&notifier_trans_block, 365 cpufreq_unregister_notifier(&notifier_trans_block,
337 CPUFREQ_TRANSITION_NOTIFIER); 366 CPUFREQ_TRANSITION_NOTIFIER);
338 for_each_cpu(cpu) 367 unregister_cpu_notifier(&cpufreq_stat_cpu_notifier);
339 cpufreq_stats_free_table(cpu); 368 lock_cpu_hotplug();
369 for_each_online_cpu(cpu) {
370 cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier, CPU_DEAD,
371 (void *)(long)cpu);
372 }
373 unlock_cpu_hotplug();
340} 374}
341 375
342MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>"); 376MODULE_AUTHOR ("Zou Nan hai <nanhai.zou@intel.com>");