lkml.org 
[lkml]   [2012]   [Oct]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[V5 PATCH 02/26] memory_hotplug: handle empty zone when online_movable/online_kernel
    Date
    make online_movable/online_kernel can empty a zone
    or can move memory to a empty zone.

    Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com>
    ---
    mm/memory_hotplug.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------
    1 files changed, 45 insertions(+), 6 deletions(-)

    diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
    index 6d3bec4..bdcdaf6 100644
    --- a/mm/memory_hotplug.c
    +++ b/mm/memory_hotplug.c
    @@ -227,8 +227,17 @@ static void resize_zone(struct zone *zone, unsigned long start_pfn,

    zone_span_writelock(zone);

    - zone->zone_start_pfn = start_pfn;
    - zone->spanned_pages = end_pfn - start_pfn;
    + if (end_pfn - start_pfn) {
    + zone->zone_start_pfn = start_pfn;
    + zone->spanned_pages = end_pfn - start_pfn;
    + } else {
    + /*
    + * make it consist as free_area_init_core(),
    + * if spanned_pages = 0, then keep start_pfn = 0
    + */
    + zone->zone_start_pfn = 0;
    + zone->spanned_pages = 0;
    + }

    zone_span_writeunlock(zone);
    }
    @@ -244,10 +253,19 @@ static void fix_zone_id(struct zone *zone, unsigned long start_pfn,
    set_page_links(pfn_to_page(pfn), zid, nid, pfn);
    }

    -static int move_pfn_range_left(struct zone *z1, struct zone *z2,
    +static int __meminit move_pfn_range_left(struct zone *z1, struct zone *z2,
    unsigned long start_pfn, unsigned long end_pfn)
    {
    + int ret;
    unsigned long flags;
    + unsigned long z1_start_pfn;
    +
    + if (!z1->wait_table) {
    + ret = init_currently_empty_zone(z1, start_pfn,
    + end_pfn - start_pfn, MEMMAP_HOTPLUG);
    + if (ret)
    + return ret;
    + }

    pgdat_resize_lock(z1->zone_pgdat, &flags);

    @@ -261,7 +279,13 @@ static int move_pfn_range_left(struct zone *z1, struct zone *z2,
    if (end_pfn <= z2->zone_start_pfn)
    goto out_fail;

    - resize_zone(z1, z1->zone_start_pfn, end_pfn);
    + /* use start_pfn for z1's start_pfn if z1 is empty */
    + if (z1->spanned_pages)
    + z1_start_pfn = z1->zone_start_pfn;
    + else
    + z1_start_pfn = start_pfn;
    +
    + resize_zone(z1, z1_start_pfn, end_pfn);
    resize_zone(z2, end_pfn, z2->zone_start_pfn + z2->spanned_pages);

    pgdat_resize_unlock(z1->zone_pgdat, &flags);
    @@ -274,10 +298,19 @@ out_fail:
    return -1;
    }

    -static int move_pfn_range_right(struct zone *z1, struct zone *z2,
    +static int __meminit move_pfn_range_right(struct zone *z1, struct zone *z2,
    unsigned long start_pfn, unsigned long end_pfn)
    {
    + int ret;
    unsigned long flags;
    + unsigned long z2_end_pfn;
    +
    + if (!z2->wait_table) {
    + ret = init_currently_empty_zone(z2, start_pfn,
    + end_pfn - start_pfn, MEMMAP_HOTPLUG);
    + if (ret)
    + return ret;
    + }

    pgdat_resize_lock(z1->zone_pgdat, &flags);

    @@ -291,8 +324,14 @@ static int move_pfn_range_right(struct zone *z1, struct zone *z2,
    if (start_pfn >= z1->zone_start_pfn + z1->spanned_pages)
    goto out_fail;

    + /* use end_pfn for z2's end_pfn if z2 is empty */
    + if (z2->spanned_pages)
    + z2_end_pfn = z2->zone_start_pfn + z2->spanned_pages;
    + else
    + z2_end_pfn = end_pfn;
    +
    resize_zone(z1, z1->zone_start_pfn, start_pfn);
    - resize_zone(z2, start_pfn, z2->zone_start_pfn + z2->spanned_pages);
    + resize_zone(z2, start_pfn, z2_end_pfn);

    pgdat_resize_unlock(z1->zone_pgdat, &flags);

    --
    1.7.4.4


    \
     
     \ /
      Last update: 2012-10-29 22:21    [W:2.918 / U:1.504 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site