Commit 925268a06dc2b1ff7bfcc37419a6827a0e739639

Authored by KAMEZAWA Hiroyuki
Committed by Pekka Enberg
1 parent 3c0eee3fe6

memory hotplug: one more lock on memory hotplug

Now, memory_hotplug_(un)lock() is used for add/remove/offline pages
for avoiding races with hibernation. But this should be held in
online_pages(), too. It seems asymmetric.

There are cases where one has to avoid a race with memory hotplug
notifier and his own local code, and hotplug v.s. hotplug.
This will add a generic solution for avoiding races. In other view,
having lock here has no big impacts. online pages is tend to be
done by udev script at el against each memory section one by one.

Then, it's better to have lock here, too.

Cc: <stable@kernel.org> # 2.6.37
Reviewed-by: Christoph Lameter <cl@linux.com>
Acked-by: David Rientjes <rientjes@google.com>
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>

Showing 2 changed files with 10 additions and 0 deletions Side-by-side Diff

include/linux/memory_hotplug.h
... ... @@ -161,6 +161,12 @@
161 161 extern void put_page_bootmem(struct page *page);
162 162 #endif
163 163  
  164 +/*
  165 + * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug
  166 + * notifier will be called under this. 2) offline/online/add/remove memory
  167 + * will not run simultaneously.
  168 + */
  169 +
164 170 void lock_memory_hotplug(void);
165 171 void unlock_memory_hotplug(void);
166 172  
... ... @@ -407,6 +407,7 @@
407 407 int ret;
408 408 struct memory_notify arg;
409 409  
  410 + lock_memory_hotplug();
410 411 arg.start_pfn = pfn;
411 412 arg.nr_pages = nr_pages;
412 413 arg.status_change_nid = -1;
... ... @@ -419,6 +420,7 @@
419 420 ret = notifier_to_errno(ret);
420 421 if (ret) {
421 422 memory_notify(MEM_CANCEL_ONLINE, &arg);
  423 + unlock_memory_hotplug();
422 424 return ret;
423 425 }
424 426 /*
... ... @@ -443,6 +445,7 @@
443 445 printk(KERN_DEBUG "online_pages %lx at %lx failed\n",
444 446 nr_pages, pfn);
445 447 memory_notify(MEM_CANCEL_ONLINE, &arg);
  448 + unlock_memory_hotplug();
446 449 return ret;
447 450 }
448 451  
... ... @@ -467,6 +470,7 @@
467 470  
468 471 if (onlined_pages)
469 472 memory_notify(MEM_ONLINE, &arg);
  473 + unlock_memory_hotplug();
470 474  
471 475 return 0;
472 476 }