diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2006-11-08 22:46:09 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-12-01 17:52:01 -0500 |
commit | 06a4bcae1ff2cd5f6f42bd74add85ec785a26343 (patch) | |
tree | 666cba3de43b602125df3b143a08d22f4188b13b /drivers/base/topology.c | |
parent | 289535334646796fe41f199718e4a731f7411a92 (diff) |
cpu topology: consider sysfs_create_group return value
Take return value of sysfs_create_group() into account. That function got
called in case of CPU_ONLINE notification. Since callbacks are not allowed
to fail on CPU_ONLINE notification do the sysfs group creation on
CPU_UP_PREPARE notification.
Also remember if creation succeeded in a bitmask. So it's possible to know
whether it's legal to call sysfs_remove_group or not.
In addition some other minor stuff:
- since CPU_UP_PREPARE might fail add CPU_UP_CANCELED handling as well.
- use hotcpu_notifier instead of register_hotcpu_notifier.
- #ifdef code that isn't needed in the !CONFIG_HOTPLUG_CPU case.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base/topology.c')
-rw-r--r-- | drivers/base/topology.c | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 28dccb730af9..3d12b85b0962 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -94,54 +94,63 @@ static struct attribute_group topology_attr_group = { | |||
94 | .name = "topology" | 94 | .name = "topology" |
95 | }; | 95 | }; |
96 | 96 | ||
97 | static cpumask_t topology_dev_map = CPU_MASK_NONE; | ||
98 | |||
97 | /* Add/Remove cpu_topology interface for CPU device */ | 99 | /* Add/Remove cpu_topology interface for CPU device */ |
98 | static int __cpuinit topology_add_dev(struct sys_device * sys_dev) | 100 | static int __cpuinit topology_add_dev(unsigned int cpu) |
99 | { | 101 | { |
100 | return sysfs_create_group(&sys_dev->kobj, &topology_attr_group); | 102 | int rc; |
103 | struct sys_device *sys_dev = get_cpu_sysdev(cpu); | ||
104 | |||
105 | rc = sysfs_create_group(&sys_dev->kobj, &topology_attr_group); | ||
106 | if (!rc) | ||
107 | cpu_set(cpu, topology_dev_map); | ||
108 | return rc; | ||
101 | } | 109 | } |
102 | 110 | ||
103 | static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) | 111 | #ifdef CONFIG_HOTPLUG_CPU |
112 | static void __cpuinit topology_remove_dev(unsigned int cpu) | ||
104 | { | 113 | { |
114 | struct sys_device *sys_dev = get_cpu_sysdev(cpu); | ||
115 | |||
116 | if (!cpu_isset(cpu, topology_dev_map)) | ||
117 | return; | ||
118 | cpu_clear(cpu, topology_dev_map); | ||
105 | sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); | 119 | sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); |
106 | return 0; | ||
107 | } | 120 | } |
108 | 121 | ||
109 | static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, | 122 | static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, |
110 | unsigned long action, void *hcpu) | 123 | unsigned long action, void *hcpu) |
111 | { | 124 | { |
112 | unsigned int cpu = (unsigned long)hcpu; | 125 | unsigned int cpu = (unsigned long)hcpu; |
113 | struct sys_device *sys_dev; | 126 | int rc = 0; |
114 | 127 | ||
115 | sys_dev = get_cpu_sysdev(cpu); | ||
116 | switch (action) { | 128 | switch (action) { |
117 | case CPU_ONLINE: | 129 | case CPU_UP_PREPARE: |
118 | topology_add_dev(sys_dev); | 130 | rc = topology_add_dev(cpu); |
119 | break; | 131 | break; |
132 | case CPU_UP_CANCELED: | ||
120 | case CPU_DEAD: | 133 | case CPU_DEAD: |
121 | topology_remove_dev(sys_dev); | 134 | topology_remove_dev(cpu); |
122 | break; | 135 | break; |
123 | } | 136 | } |
124 | return NOTIFY_OK; | 137 | return rc ? NOTIFY_BAD : NOTIFY_OK; |
125 | } | 138 | } |
126 | 139 | #endif | |
127 | static struct notifier_block __cpuinitdata topology_cpu_notifier = | ||
128 | { | ||
129 | .notifier_call = topology_cpu_callback, | ||
130 | }; | ||
131 | 140 | ||
132 | static int __cpuinit topology_sysfs_init(void) | 141 | static int __cpuinit topology_sysfs_init(void) |
133 | { | 142 | { |
134 | int i; | 143 | int cpu; |
144 | int rc; | ||
135 | 145 | ||
136 | for_each_online_cpu(i) { | 146 | for_each_online_cpu(cpu) { |
137 | topology_cpu_callback(&topology_cpu_notifier, CPU_ONLINE, | 147 | rc = topology_add_dev(cpu); |
138 | (void *)(long)i); | 148 | if (rc) |
149 | return rc; | ||
139 | } | 150 | } |
140 | 151 | hotcpu_notifier(topology_cpu_callback, 0); | |
141 | register_hotcpu_notifier(&topology_cpu_notifier); | ||
142 | 152 | ||
143 | return 0; | 153 | return 0; |
144 | } | 154 | } |
145 | 155 | ||
146 | device_initcall(topology_sysfs_init); | 156 | device_initcall(topology_sysfs_init); |
147 | |||