]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/memory_hotplug.c
x86: section mismatch fix
[linux-2.6-omap-h63xx.git] / mm / memory_hotplug.c
index 656ad1c65422f0440a56b422b8431891e5304827..833f854eabe50ad226696667db7e49d332840bb6 100644 (file)
@@ -159,17 +159,58 @@ void register_page_bootmem_info_node(struct pglist_data *pgdat)
 }
 #endif /* !CONFIG_SPARSEMEM_VMEMMAP */
 
+static void grow_zone_span(struct zone *zone, unsigned long start_pfn,
+                          unsigned long end_pfn)
+{
+       unsigned long old_zone_end_pfn;
+
+       zone_span_writelock(zone);
+
+       old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
+       if (start_pfn < zone->zone_start_pfn)
+               zone->zone_start_pfn = start_pfn;
+
+       zone->spanned_pages = max(old_zone_end_pfn, end_pfn) -
+                               zone->zone_start_pfn;
+
+       zone_span_writeunlock(zone);
+}
+
+static void grow_pgdat_span(struct pglist_data *pgdat, unsigned long start_pfn,
+                           unsigned long end_pfn)
+{
+       unsigned long old_pgdat_end_pfn =
+               pgdat->node_start_pfn + pgdat->node_spanned_pages;
+
+       if (start_pfn < pgdat->node_start_pfn)
+               pgdat->node_start_pfn = start_pfn;
+
+       pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) -
+                                       pgdat->node_start_pfn;
+}
+
 static int __add_zone(struct zone *zone, unsigned long phys_start_pfn)
 {
        struct pglist_data *pgdat = zone->zone_pgdat;
        int nr_pages = PAGES_PER_SECTION;
        int nid = pgdat->node_id;
        int zone_type;
+       unsigned long flags;
 
        zone_type = zone - pgdat->node_zones;
-       if (!zone->wait_table)
-               return init_currently_empty_zone(zone, phys_start_pfn,
-                                                nr_pages, MEMMAP_HOTPLUG);
+       if (!zone->wait_table) {
+               int ret;
+
+               ret = init_currently_empty_zone(zone, phys_start_pfn,
+                                               nr_pages, MEMMAP_HOTPLUG);
+               if (ret)
+                       return ret;
+       }
+       pgdat_resize_lock(zone->zone_pgdat, &flags);
+       grow_zone_span(zone, phys_start_pfn, phys_start_pfn + nr_pages);
+       grow_pgdat_span(zone->zone_pgdat, phys_start_pfn,
+                       phys_start_pfn + nr_pages);
+       pgdat_resize_unlock(zone->zone_pgdat, &flags);
        memmap_init_zone(nr_pages, nid, zone_type,
                         phys_start_pfn, MEMMAP_HOTPLUG);
        return 0;
@@ -295,36 +336,6 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
 }
 EXPORT_SYMBOL_GPL(__remove_pages);
 
-static void grow_zone_span(struct zone *zone,
-               unsigned long start_pfn, unsigned long end_pfn)
-{
-       unsigned long old_zone_end_pfn;
-
-       zone_span_writelock(zone);
-
-       old_zone_end_pfn = zone->zone_start_pfn + zone->spanned_pages;
-       if (start_pfn < zone->zone_start_pfn)
-               zone->zone_start_pfn = start_pfn;
-
-       zone->spanned_pages = max(old_zone_end_pfn, end_pfn) -
-                               zone->zone_start_pfn;
-
-       zone_span_writeunlock(zone);
-}
-
-static void grow_pgdat_span(struct pglist_data *pgdat,
-               unsigned long start_pfn, unsigned long end_pfn)
-{
-       unsigned long old_pgdat_end_pfn =
-               pgdat->node_start_pfn + pgdat->node_spanned_pages;
-
-       if (start_pfn < pgdat->node_start_pfn)
-               pgdat->node_start_pfn = start_pfn;
-
-       pgdat->node_spanned_pages = max(old_pgdat_end_pfn, end_pfn) -
-                                       pgdat->node_start_pfn;
-}
-
 void online_page(struct page *page)
 {
        totalram_pages++;
@@ -363,7 +374,6 @@ static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages,
 
 int online_pages(unsigned long pfn, unsigned long nr_pages)
 {
-       unsigned long flags;
        unsigned long onlined_pages = 0;
        struct zone *zone;
        int need_zonelists_rebuild = 0;
@@ -391,11 +401,6 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
         * memory_block->state_mutex.
         */
        zone = page_zone(pfn_to_page(pfn));
-       pgdat_resize_lock(zone->zone_pgdat, &flags);
-       grow_zone_span(zone, pfn, pfn + nr_pages);
-       grow_pgdat_span(zone->zone_pgdat, pfn, pfn + nr_pages);
-       pgdat_resize_unlock(zone->zone_pgdat, &flags);
-
        /*
         * If this zone is not populated, then it is not in zonelist.
         * This means the page allocator ignores this zone.