summaryrefslogtreecommitdiff
path: root/arch/s390/mm/init.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2012-03-14 08:48:16 (GMT)
committerIngo Molnar <mingo@elte.hu>2012-03-14 08:48:16 (GMT)
commitc96a9876696d30783ad54399351a0bf3660db53f (patch)
tree74daba0ed1fd2838e8eb527c4f7fe5262ee979bd /arch/s390/mm/init.c
parentd1f42e314c9c50541c79a6edf2b4cab63fe02ee3 (diff)
parentfde7d9049e55ab85a390be7f415d74c9f62dd0f9 (diff)
downloadlinux-fsl-qoriq-c96a9876696d30783ad54399351a0bf3660db53f.tar.xz
Merge tag 'v3.3-rc7' into x86/platform
Merge reason: Update to the almost-final v3.3 kernel. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/s390/mm/init.c')
-rw-r--r--arch/s390/mm/init.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 5d63301..5023661 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -223,16 +223,38 @@ void free_initrd_mem(unsigned long start, unsigned long end)
#ifdef CONFIG_MEMORY_HOTPLUG
int arch_add_memory(int nid, u64 start, u64 size)
{
- struct pglist_data *pgdat;
+ unsigned long zone_start_pfn, zone_end_pfn, nr_pages;
+ unsigned long start_pfn = PFN_DOWN(start);
+ unsigned long size_pages = PFN_DOWN(size);
struct zone *zone;
int rc;
- pgdat = NODE_DATA(nid);
- zone = pgdat->node_zones + ZONE_MOVABLE;
rc = vmem_add_mapping(start, size);
if (rc)
return rc;
- rc = __add_pages(nid, zone, PFN_DOWN(start), PFN_DOWN(size));
+ for_each_zone(zone) {
+ if (zone_idx(zone) != ZONE_MOVABLE) {
+ /* Add range within existing zone limits */
+ zone_start_pfn = zone->zone_start_pfn;
+ zone_end_pfn = zone->zone_start_pfn +
+ zone->spanned_pages;
+ } else {
+ /* Add remaining range to ZONE_MOVABLE */
+ zone_start_pfn = start_pfn;
+ zone_end_pfn = start_pfn + size_pages;
+ }
+ if (start_pfn < zone_start_pfn || start_pfn >= zone_end_pfn)
+ continue;
+ nr_pages = (start_pfn + size_pages > zone_end_pfn) ?
+ zone_end_pfn - start_pfn : size_pages;
+ rc = __add_pages(nid, zone, start_pfn, nr_pages);
+ if (rc)
+ break;
+ start_pfn += nr_pages;
+ size_pages -= nr_pages;
+ if (!size_pages)
+ break;
+ }
if (rc)
vmem_remove_mapping(start, size);
return rc;