Commit 1aa1a9f9 authored by Ashok Raj's avatar Ashok Raj Committed by Linus Torvalds

[PATCH] create and destroy cache sysfs entries based on cpu notifiers

cpu cache entries should be populated only when cpu is online and removed
when they are logically offlined.

Without which entries are not removed when cpu is offlined, or dont appear
when we boot with maxcpus=1 and then kick the rest of the cpus via echo 1
to the sysfs online file.

- Changed __devinit to __cpuinit for consistency.
- Changed sysfs_driver_register to register_cpu_notifier.
Signed-off-by: default avatarAshok Raj <ashok.raj@intel.com>
Signed-off-by: default avatarVenkatesh 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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ad74557a
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* *
* Changes: * Changes:
* Venkatesh Pallipadi : Adding cache identification through cpuid(4) * Venkatesh Pallipadi : Adding cache identification through cpuid(4)
* Ashok Raj <ashok.raj@intel.com>: Work with CPU hotplug infrastructure.
*/ */
#include <linux/init.h> #include <linux/init.h>
...@@ -28,7 +29,7 @@ struct _cache_table ...@@ -28,7 +29,7 @@ struct _cache_table
}; };
/* all the cache descriptor types we care about (no TLB or trace cache entries) */ /* all the cache descriptor types we care about (no TLB or trace cache entries) */
static struct _cache_table cache_table[] __devinitdata = static struct _cache_table cache_table[] __cpuinitdata =
{ {
{ 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */
{ 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */
...@@ -119,7 +120,7 @@ struct _cpuid4_info { ...@@ -119,7 +120,7 @@ struct _cpuid4_info {
static unsigned short num_cache_leaves; static unsigned short num_cache_leaves;
static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
{ {
unsigned int eax, ebx, ecx, edx; unsigned int eax, ebx, ecx, edx;
union _cpuid4_leaf_eax cache_eax; union _cpuid4_leaf_eax cache_eax;
...@@ -154,7 +155,7 @@ static int __init find_num_cache_leaves(void) ...@@ -154,7 +155,7 @@ static int __init find_num_cache_leaves(void)
return i; return i;
} }
unsigned int __devinit init_intel_cacheinfo(struct cpuinfo_x86 *c) unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
{ {
unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */
unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */
...@@ -289,7 +290,7 @@ static struct _cpuid4_info *cpuid4_info[NR_CPUS]; ...@@ -289,7 +290,7 @@ static struct _cpuid4_info *cpuid4_info[NR_CPUS];
#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y])) #define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y]))
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index) static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
{ {
struct _cpuid4_info *this_leaf; struct _cpuid4_info *this_leaf;
unsigned long num_threads_sharing; unsigned long num_threads_sharing;
...@@ -322,7 +323,7 @@ static void free_cache_attributes(unsigned int cpu) ...@@ -322,7 +323,7 @@ static void free_cache_attributes(unsigned int cpu)
cpuid4_info[cpu] = NULL; cpuid4_info[cpu] = NULL;
} }
static int __devinit detect_cache_attributes(unsigned int cpu) static int __cpuinit detect_cache_attributes(unsigned int cpu)
{ {
struct _cpuid4_info *this_leaf; struct _cpuid4_info *this_leaf;
unsigned long j; unsigned long j;
...@@ -499,7 +500,7 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu) ...@@ -499,7 +500,7 @@ static void cpuid4_cache_sysfs_exit(unsigned int cpu)
free_cache_attributes(cpu); free_cache_attributes(cpu);
} }
static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu) static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu)
{ {
if (num_cache_leaves == 0) if (num_cache_leaves == 0)
...@@ -530,7 +531,7 @@ static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu) ...@@ -530,7 +531,7 @@ static int __devinit cpuid4_cache_sysfs_init(unsigned int cpu)
} }
/* Add/Remove cache interface for CPU device */ /* Add/Remove cache interface for CPU device */
static int __devinit cache_add_dev(struct sys_device * sys_dev) static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
{ {
unsigned int cpu = sys_dev->id; unsigned int cpu = sys_dev->id;
unsigned long i, j; unsigned long i, j;
...@@ -567,7 +568,7 @@ static int __devinit cache_add_dev(struct sys_device * sys_dev) ...@@ -567,7 +568,7 @@ static int __devinit cache_add_dev(struct sys_device * sys_dev)
return retval; return retval;
} }
static int __devexit cache_remove_dev(struct sys_device * sys_dev) static void __cpuexit cache_remove_dev(struct sys_device * sys_dev)
{ {
unsigned int cpu = sys_dev->id; unsigned int cpu = sys_dev->id;
unsigned long i; unsigned long i;
...@@ -576,24 +577,49 @@ static int __devexit cache_remove_dev(struct sys_device * sys_dev) ...@@ -576,24 +577,49 @@ static int __devexit cache_remove_dev(struct sys_device * sys_dev)
kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
kobject_unregister(cache_kobject[cpu]); kobject_unregister(cache_kobject[cpu]);
cpuid4_cache_sysfs_exit(cpu); cpuid4_cache_sysfs_exit(cpu);
return 0; return;
}
static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
struct sys_device *sys_dev;
sys_dev = get_cpu_sysdev(cpu);
switch (action) {
case CPU_ONLINE:
cache_add_dev(sys_dev);
break;
case CPU_DEAD:
cache_remove_dev(sys_dev);
break;
}
return NOTIFY_OK;
} }
static struct sysdev_driver cache_sysdev_driver = { static struct notifier_block cacheinfo_cpu_notifier =
.add = cache_add_dev, {
.remove = __devexit_p(cache_remove_dev), .notifier_call = cacheinfo_cpu_callback,
}; };
/* Register/Unregister the cpu_cache driver */ static int __cpuinit cache_sysfs_init(void)
static int __devinit cache_register_driver(void)
{ {
int i;
if (num_cache_leaves == 0) if (num_cache_leaves == 0)
return 0; return 0;
return sysdev_driver_register(&cpu_sysdev_class,&cache_sysdev_driver); register_cpu_notifier(&cacheinfo_cpu_notifier);
for_each_online_cpu(i) {
cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE,
(void *)(long)i);
}
return 0;
} }
device_initcall(cache_register_driver); device_initcall(cache_sysfs_init);
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment