mm: use a dedicated lock to protect totalram_pages and zone->managed_pages
[linux-2.6-block.git] / mm / memory_hotplug.c
index 1ad92b46753edfe8d9f54fae81c5f3aa15b34110..6096cb91873505c29a0917f1ce9cbe4ff6d80c74 100644 (file)
@@ -75,7 +75,7 @@ static struct resource *register_memory_resource(u64 start, u64 size)
        res->end = start + size - 1;
        res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
        if (request_resource(&iomem_resource, res) < 0) {
-               printk("System RAM resource %pR cannot be added\n", res);
+               pr_debug("System RAM resource %pR cannot be added\n", res);
                kfree(res);
                res = NULL;
        }
@@ -309,7 +309,7 @@ static int __meminit move_pfn_range_left(struct zone *z1, struct zone *z2,
        /* can't move pfns which are higher than @z2 */
        if (end_pfn > zone_end_pfn(z2))
                goto out_fail;
-       /* the move out part mast at the left most of @z2 */
+       /* the move out part must be at the left most of @z2 */
        if (start_pfn > z2->zone_start_pfn)
                goto out_fail;
        /* must included/overlap */
@@ -918,6 +918,7 @@ static void node_states_set_node(int node, struct memory_notify *arg)
 
 int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_type)
 {
+       unsigned long flags;
        unsigned long onlined_pages = 0;
        struct zone *zone;
        int need_zonelists_rebuild = 0;
@@ -996,7 +997,11 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
 
        zone->managed_pages += onlined_pages;
        zone->present_pages += onlined_pages;
+
+       pgdat_resize_lock(zone->zone_pgdat, &flags);
        zone->zone_pgdat->node_present_pages += onlined_pages;
+       pgdat_resize_unlock(zone->zone_pgdat, &flags);
+
        if (onlined_pages) {
                node_states_set_node(zone_to_nid(zone), &arg);
                if (need_zonelists_rebuild)
@@ -1487,6 +1492,7 @@ static int __ref __offline_pages(unsigned long start_pfn,
        unsigned long pfn, nr_pages, expire;
        long offlined_pages;
        int ret, drain, retry_max, node;
+       unsigned long flags;
        struct zone *zone;
        struct memory_notify arg;
 
@@ -1580,7 +1586,11 @@ repeat:
        /* removal success */
        zone->managed_pages -= offlined_pages;
        zone->present_pages -= offlined_pages;
+
+       pgdat_resize_lock(zone->zone_pgdat, &flags);
        zone->zone_pgdat->node_present_pages -= offlined_pages;
+       pgdat_resize_unlock(zone->zone_pgdat, &flags);
+
        totalram_pages -= offlined_pages;
 
        init_per_zone_wmark_min();