diff options
author | Paul Mackerras <paulus@samba.org> | 2005-10-30 21:37:12 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-10-30 21:37:12 -0500 |
commit | 23fd07750a789a66fe88cf173d52a18f1a387da4 (patch) | |
tree | 06fdd6df35fdb835abdaa9b754d62f6b84b97250 /arch/powerpc/mm/mem.c | |
parent | bd787d438a59266af3c9f6351644c85ef1dd21fe (diff) | |
parent | ed28f96ac1960f30f818374d65be71d2fdf811b0 (diff) |
Merge ../linux-2.6 by hand
Diffstat (limited to 'arch/powerpc/mm/mem.c')
-rw-r--r-- | arch/powerpc/mm/mem.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index e43e8ef70088..117b00012e14 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
@@ -102,6 +102,83 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, | |||
102 | } | 102 | } |
103 | EXPORT_SYMBOL(phys_mem_access_prot); | 103 | EXPORT_SYMBOL(phys_mem_access_prot); |
104 | 104 | ||
105 | #ifdef CONFIG_MEMORY_HOTPLUG | ||
106 | |||
107 | void online_page(struct page *page) | ||
108 | { | ||
109 | ClearPageReserved(page); | ||
110 | free_cold_page(page); | ||
111 | totalram_pages++; | ||
112 | num_physpages++; | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * This works only for the non-NUMA case. Later, we'll need a lookup | ||
117 | * to convert from real physical addresses to nid, that doesn't use | ||
118 | * pfn_to_nid(). | ||
119 | */ | ||
120 | int __devinit add_memory(u64 start, u64 size) | ||
121 | { | ||
122 | struct pglist_data *pgdata = NODE_DATA(0); | ||
123 | struct zone *zone; | ||
124 | unsigned long start_pfn = start >> PAGE_SHIFT; | ||
125 | unsigned long nr_pages = size >> PAGE_SHIFT; | ||
126 | |||
127 | /* this should work for most non-highmem platforms */ | ||
128 | zone = pgdata->node_zones; | ||
129 | |||
130 | return __add_pages(zone, start_pfn, nr_pages); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * First pass at this code will check to determine if the remove | ||
137 | * request is within the RMO. Do not allow removal within the RMO. | ||
138 | */ | ||
139 | int __devinit remove_memory(u64 start, u64 size) | ||
140 | { | ||
141 | struct zone *zone; | ||
142 | unsigned long start_pfn, end_pfn, nr_pages; | ||
143 | |||
144 | start_pfn = start >> PAGE_SHIFT; | ||
145 | nr_pages = size >> PAGE_SHIFT; | ||
146 | end_pfn = start_pfn + nr_pages; | ||
147 | |||
148 | printk("%s(): Attempting to remove memoy in range " | ||
149 | "%lx to %lx\n", __func__, start, start+size); | ||
150 | /* | ||
151 | * check for range within RMO | ||
152 | */ | ||
153 | zone = page_zone(pfn_to_page(start_pfn)); | ||
154 | |||
155 | printk("%s(): memory will be removed from " | ||
156 | "the %s zone\n", __func__, zone->name); | ||
157 | |||
158 | /* | ||
159 | * not handling removing memory ranges that | ||
160 | * overlap multiple zones yet | ||
161 | */ | ||
162 | if (end_pfn > (zone->zone_start_pfn + zone->spanned_pages)) | ||
163 | goto overlap; | ||
164 | |||
165 | /* make sure it is NOT in RMO */ | ||
166 | if ((start < lmb.rmo_size) || ((start+size) < lmb.rmo_size)) { | ||
167 | printk("%s(): range to be removed must NOT be in RMO!\n", | ||
168 | __func__); | ||
169 | goto in_rmo; | ||
170 | } | ||
171 | |||
172 | return __remove_pages(zone, start_pfn, nr_pages); | ||
173 | |||
174 | overlap: | ||
175 | printk("%s(): memory range to be removed overlaps " | ||
176 | "multiple zones!!!\n", __func__); | ||
177 | in_rmo: | ||
178 | return -1; | ||
179 | } | ||
180 | #endif /* CONFIG_MEMORY_HOTPLUG */ | ||
181 | |||
105 | void show_mem(void) | 182 | void show_mem(void) |
106 | { | 183 | { |
107 | unsigned long total = 0, reserved = 0; | 184 | unsigned long total = 0, reserved = 0; |
@@ -115,6 +192,8 @@ void show_mem(void) | |||
115 | show_free_areas(); | 192 | show_free_areas(); |
116 | printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); | 193 | printk("Free swap: %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); |
117 | for_each_pgdat(pgdat) { | 194 | for_each_pgdat(pgdat) { |
195 | unsigned long flags; | ||
196 | pgdat_resize_lock(pgdat, &flags); | ||
118 | for (i = 0; i < pgdat->node_spanned_pages; i++) { | 197 | for (i = 0; i < pgdat->node_spanned_pages; i++) { |
119 | page = pgdat_page_nr(pgdat, i); | 198 | page = pgdat_page_nr(pgdat, i); |
120 | total++; | 199 | total++; |
@@ -127,6 +206,7 @@ void show_mem(void) | |||
127 | else if (page_count(page)) | 206 | else if (page_count(page)) |
128 | shared += page_count(page) - 1; | 207 | shared += page_count(page) - 1; |
129 | } | 208 | } |
209 | pgdat_resize_unlock(pgdat, &flags); | ||
130 | } | 210 | } |
131 | printk("%ld pages of RAM\n", total); | 211 | printk("%ld pages of RAM\n", total); |
132 | #ifdef CONFIG_HIGHMEM | 212 | #ifdef CONFIG_HIGHMEM |