aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/memory.c9
-rw-r--r--include/linux/memory_hotplug.h1
-rw-r--r--mm/memory_hotplug.c13
3 files changed, 15 insertions, 8 deletions
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 7dda4f790f00..44e7de6ce694 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -248,26 +248,23 @@ static bool pages_correctly_reserved(unsigned long start_pfn,
248static int 248static int
249memory_block_action(unsigned long phys_index, unsigned long action) 249memory_block_action(unsigned long phys_index, unsigned long action)
250{ 250{
251 unsigned long start_pfn, start_paddr; 251 unsigned long start_pfn;
252 unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block; 252 unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
253 struct page *first_page; 253 struct page *first_page;
254 int ret; 254 int ret;
255 255
256 first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT); 256 first_page = pfn_to_page(phys_index << PFN_SECTION_SHIFT);
257 start_pfn = page_to_pfn(first_page);
257 258
258 switch (action) { 259 switch (action) {
259 case MEM_ONLINE: 260 case MEM_ONLINE:
260 start_pfn = page_to_pfn(first_page);
261
262 if (!pages_correctly_reserved(start_pfn, nr_pages)) 261 if (!pages_correctly_reserved(start_pfn, nr_pages))
263 return -EBUSY; 262 return -EBUSY;
264 263
265 ret = online_pages(start_pfn, nr_pages); 264 ret = online_pages(start_pfn, nr_pages);
266 break; 265 break;
267 case MEM_OFFLINE: 266 case MEM_OFFLINE:
268 start_paddr = page_to_pfn(first_page) << PAGE_SHIFT; 267 ret = offline_pages(start_pfn, nr_pages);
269 ret = remove_memory(start_paddr,
270 nr_pages << PAGE_SHIFT);
271 break; 268 break;
272 default: 269 default:
273 WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: " 270 WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: "
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 910550f3b70e..e64fe80eba96 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -233,6 +233,7 @@ static inline int is_mem_section_removable(unsigned long pfn,
233extern int mem_online_node(int nid); 233extern int mem_online_node(int nid);
234extern int add_memory(int nid, u64 start, u64 size); 234extern int add_memory(int nid, u64 start, u64 size);
235extern int arch_add_memory(int nid, u64 start, u64 size); 235extern int arch_add_memory(int nid, u64 start, u64 size);
236extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
236extern int remove_memory(u64 start, u64 size); 237extern int remove_memory(u64 start, u64 size);
237extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn, 238extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
238 int nr_pages); 239 int nr_pages);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index ce690a911f1b..dfc0a6134c7c 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -874,7 +874,7 @@ check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
874 return offlined; 874 return offlined;
875} 875}
876 876
877static int __ref offline_pages(unsigned long start_pfn, 877static int __ref __offline_pages(unsigned long start_pfn,
878 unsigned long end_pfn, unsigned long timeout) 878 unsigned long end_pfn, unsigned long timeout)
879{ 879{
880 unsigned long pfn, nr_pages, expire; 880 unsigned long pfn, nr_pages, expire;
@@ -1007,15 +1007,24 @@ out:
1007 return ret; 1007 return ret;
1008} 1008}
1009 1009
1010int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
1011{
1012 return __offline_pages(start_pfn, start_pfn + nr_pages, 120 * HZ);
1013}
1014
1010int remove_memory(u64 start, u64 size) 1015int remove_memory(u64 start, u64 size)
1011{ 1016{
1012 unsigned long start_pfn, end_pfn; 1017 unsigned long start_pfn, end_pfn;
1013 1018
1014 start_pfn = PFN_DOWN(start); 1019 start_pfn = PFN_DOWN(start);
1015 end_pfn = start_pfn + PFN_DOWN(size); 1020 end_pfn = start_pfn + PFN_DOWN(size);
1016 return offline_pages(start_pfn, end_pfn, 120 * HZ); 1021 return __offline_pages(start_pfn, end_pfn, 120 * HZ);
1017} 1022}
1018#else 1023#else
1024int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
1025{
1026 return -EINVAL;
1027}
1019int remove_memory(u64 start, u64 size) 1028int remove_memory(u64 start, u64 size)
1020{ 1029{
1021 return -EINVAL; 1030 return -EINVAL;