diff options
Diffstat (limited to 'drivers/base/memory.c')
-rw-r--r-- | drivers/base/memory.c | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 3da6a43b7756..9f9b2359f718 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -48,7 +48,8 @@ static const char *memory_uevent_name(struct kset *kset, struct kobject *kobj) | |||
48 | return MEMORY_CLASS_NAME; | 48 | return MEMORY_CLASS_NAME; |
49 | } | 49 | } |
50 | 50 | ||
51 | static int memory_uevent(struct kset *kset, struct kobject *obj, struct kobj_uevent_env *env) | 51 | static int memory_uevent(struct kset *kset, struct kobject *obj, |
52 | struct kobj_uevent_env *env) | ||
52 | { | 53 | { |
53 | int retval = 0; | 54 | int retval = 0; |
54 | 55 | ||
@@ -228,10 +229,11 @@ int memory_isolate_notify(unsigned long val, void *v) | |||
228 | * OK to have direct references to sparsemem variables in here. | 229 | * OK to have direct references to sparsemem variables in here. |
229 | */ | 230 | */ |
230 | static int | 231 | static int |
231 | memory_section_action(unsigned long phys_index, unsigned long action) | 232 | memory_block_action(unsigned long phys_index, unsigned long action) |
232 | { | 233 | { |
233 | int i; | 234 | int i; |
234 | unsigned long start_pfn, start_paddr; | 235 | unsigned long start_pfn, start_paddr; |
236 | unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; | ||
235 | struct page *first_page; | 237 | struct page *first_page; |
236 | int ret; | 238 | int ret; |
237 | 239 | ||
@@ -243,7 +245,7 @@ memory_section_action(unsigned long phys_index, unsigned long action) | |||
243 | * that way. | 245 | * that way. |
244 | */ | 246 | */ |
245 | if (action == MEM_ONLINE) { | 247 | if (action == MEM_ONLINE) { |
246 | for (i = 0; i < PAGES_PER_SECTION; i++) { | 248 | for (i = 0; i < nr_pages; i++) { |
247 | if (PageReserved(first_page+i)) | 249 | if (PageReserved(first_page+i)) |
248 | continue; | 250 | continue; |
249 | 251 | ||
@@ -257,12 +259,12 @@ memory_section_action(unsigned long phys_index, unsigned long action) | |||
257 | switch (action) { | 259 | switch (action) { |
258 | case MEM_ONLINE: | 260 | case MEM_ONLINE: |
259 | start_pfn = page_to_pfn(first_page); | 261 | start_pfn = page_to_pfn(first_page); |
260 | ret = online_pages(start_pfn, PAGES_PER_SECTION); | 262 | ret = online_pages(start_pfn, nr_pages); |
261 | break; | 263 | break; |
262 | case MEM_OFFLINE: | 264 | case MEM_OFFLINE: |
263 | start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; | 265 | start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; |
264 | ret = remove_memory(start_paddr, | 266 | ret = remove_memory(start_paddr, |
265 | PAGES_PER_SECTION << PAGE_SHIFT); | 267 | nr_pages << PAGE_SHIFT); |
266 | break; | 268 | break; |
267 | default: | 269 | default: |
268 | WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " | 270 | WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " |
@@ -276,7 +278,7 @@ memory_section_action(unsigned long phys_index, unsigned long action) | |||
276 | static int memory_block_change_state(struct memory_block *mem, | 278 | static int memory_block_change_state(struct memory_block *mem, |
277 | unsigned long to_state, unsigned long from_state_req) | 279 | unsigned long to_state, unsigned long from_state_req) |
278 | { | 280 | { |
279 | int i, ret = 0; | 281 | int ret = 0; |
280 | 282 | ||
281 | mutex_lock(&mem->state_mutex); | 283 | mutex_lock(&mem->state_mutex); |
282 | 284 | ||
@@ -288,20 +290,11 @@ static int memory_block_change_state(struct memory_block *mem, | |||
288 | if (to_state == MEM_OFFLINE) | 290 | if (to_state == MEM_OFFLINE) |
289 | mem->state = MEM_GOING_OFFLINE; | 291 | mem->state = MEM_GOING_OFFLINE; |
290 | 292 | ||
291 | for (i = 0; i < sections_per_block; i++) { | 293 | ret = memory_block_action(mem->start_section_nr, to_state); |
292 | ret = memory_section_action(mem->start_section_nr + i, | ||
293 | to_state); | ||
294 | if (ret) | ||
295 | break; | ||
296 | } | ||
297 | |||
298 | if (ret) { | ||
299 | for (i = 0; i < sections_per_block; i++) | ||
300 | memory_section_action(mem->start_section_nr + i, | ||
301 | from_state_req); | ||
302 | 294 | ||
295 | if (ret) | ||
303 | mem->state = from_state_req; | 296 | mem->state = from_state_req; |
304 | } else | 297 | else |
305 | mem->state = to_state; | 298 | mem->state = to_state; |
306 | 299 | ||
307 | out: | 300 | out: |
@@ -396,15 +389,14 @@ memory_probe_store(struct class *class, struct class_attribute *attr, | |||
396 | ret = add_memory(nid, phys_addr, | 389 | ret = add_memory(nid, phys_addr, |
397 | PAGES_PER_SECTION << PAGE_SHIFT); | 390 | PAGES_PER_SECTION << PAGE_SHIFT); |
398 | if (ret) | 391 | if (ret) |
399 | break; | 392 | goto out; |
400 | 393 | ||
401 | phys_addr += MIN_MEMORY_BLOCK_SIZE; | 394 | phys_addr += MIN_MEMORY_BLOCK_SIZE; |
402 | } | 395 | } |
403 | 396 | ||
404 | if (ret) | 397 | ret = count; |
405 | count = ret; | 398 | out: |
406 | 399 | return ret; | |
407 | return count; | ||
408 | } | 400 | } |
409 | static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store); | 401 | static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store); |
410 | 402 | ||