aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorYasunori Goto <y-goto@jp.fujitsu.com>2008-04-28 05:13:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-28 11:58:25 -0400
commit04753278769f3b6c3b79a080edb52f21d83bf6e2 (patch)
tree0dff4088b44016b6d04930b2fc09419412821aa2 /include
parent7f2e9525ba55b1c42ad6c4a5a59d7eb7bdd9be72 (diff)
memory hotplug: register section/node id to free
This patch set is to free pages which is allocated by bootmem for memory-hotremove. Some structures of memory management are allocated by bootmem. ex) memmap, etc. To remove memory physically, some of them must be freed according to circumstance. This patch set makes basis to free those pages, and free memmaps. Basic my idea is using remain members of struct page to remember information of users of bootmem (section number or node id). When the section is removing, kernel can confirm it. By this information, some issues can be solved. 1) When the memmap of removing section is allocated on other section by bootmem, it should/can be free. 2) When the memmap of removing section is allocated on the same section, it shouldn't be freed. Because the section has to be logical memory offlined already and all pages must be isolated against page allocater. If it is freed, page allocator may use it which will be removed physically soon. 3) When removing section has other section's memmap, kernel will be able to show easily which section should be removed before it for user. (Not implemented yet) 4) When the above case 2), the page isolation will be able to check and skip memmap's page when logical memory offline (offline_pages()). Current page isolation code fails in this case because this page is just reserved page and it can't distinguish this pages can be removed or not. But, it will be able to do by this patch. (Not implemented yet.) 5) The node information like pgdat has similar issues. But, this will be able to be solved too by this. (Not implemented yet, but, remembering node id in the pages.) Fortunately, current bootmem allocator just keeps PageReserved flags, and doesn't use any other members of page struct. The users of bootmem doesn't use them too. This patch: This is to register information which is node or section's id. Kernel can distinguish which node/section uses the pages allcated by bootmem. This is basis for hot-remove sections or nodes. Signed-off-by: Yasunori Goto <y-goto@jp.fujitsu.com> Cc: Badari Pulavarty <pbadari@us.ibm.com> Cc: Yinghai Lu <yhlu.kernel@gmail.com> Cc: Yasunori Goto <y-goto@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/memory_hotplug.h27
-rw-r--r--include/linux/mmzone.h1
2 files changed, 28 insertions, 0 deletions
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index aca9c65f8d08..73e358612eaf 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -11,6 +11,15 @@ struct pglist_data;
11struct mem_section; 11struct mem_section;
12 12
13#ifdef CONFIG_MEMORY_HOTPLUG 13#ifdef CONFIG_MEMORY_HOTPLUG
14
15/*
16 * Magic number for free bootmem.
17 * The normal smallest mapcount is -1. Here is smaller value than it.
18 */
19#define SECTION_INFO 0xfffffffe
20#define MIX_INFO 0xfffffffd
21#define NODE_INFO 0xfffffffc
22
14/* 23/*
15 * pgdat resizing functions 24 * pgdat resizing functions
16 */ 25 */
@@ -145,6 +154,18 @@ static inline void arch_refresh_nodedata(int nid, pg_data_t *pgdat)
145#endif /* CONFIG_NUMA */ 154#endif /* CONFIG_NUMA */
146#endif /* CONFIG_HAVE_ARCH_NODEDATA_EXTENSION */ 155#endif /* CONFIG_HAVE_ARCH_NODEDATA_EXTENSION */
147 156
157#ifdef CONFIG_SPARSEMEM_VMEMMAP
158static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
159{
160}
161static inline void put_page_bootmem(struct page *page)
162{
163}
164#else
165extern void register_page_bootmem_info_node(struct pglist_data *pgdat);
166extern void put_page_bootmem(struct page *page);
167#endif
168
148#else /* ! CONFIG_MEMORY_HOTPLUG */ 169#else /* ! CONFIG_MEMORY_HOTPLUG */
149/* 170/*
150 * Stub functions for when hotplug is off 171 * Stub functions for when hotplug is off
@@ -172,6 +193,10 @@ static inline int mhp_notimplemented(const char *func)
172 return -ENOSYS; 193 return -ENOSYS;
173} 194}
174 195
196static inline void register_page_bootmem_info_node(struct pglist_data *pgdat)
197{
198}
199
175#endif /* ! CONFIG_MEMORY_HOTPLUG */ 200#endif /* ! CONFIG_MEMORY_HOTPLUG */
176 201
177extern int add_memory(int nid, u64 start, u64 size); 202extern int add_memory(int nid, u64 start, u64 size);
@@ -180,5 +205,7 @@ extern int remove_memory(u64 start, u64 size);
180extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn, 205extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
181 int nr_pages); 206 int nr_pages);
182extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms); 207extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms);
208extern struct page *sparse_decode_mem_map(unsigned long coded_mem_map,
209 unsigned long pnum);
183 210
184#endif /* __LINUX_MEMORY_HOTPLUG_H */ 211#endif /* __LINUX_MEMORY_HOTPLUG_H */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index c3828497f41d..aad98003176f 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -896,6 +896,7 @@ static inline struct mem_section *__nr_to_section(unsigned long nr)
896 return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK]; 896 return &mem_section[SECTION_NR_TO_ROOT(nr)][nr & SECTION_ROOT_MASK];
897} 897}
898extern int __section_nr(struct mem_section* ms); 898extern int __section_nr(struct mem_section* ms);
899extern unsigned long usemap_size(void);
899 900
900/* 901/*
901 * We use the lower bits of the mem_map pointer to store 902 * We use the lower bits of the mem_map pointer to store