lkml.org 
[lkml]   [2013]   [Jan]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 15/15] memory-hotplug: Do not allocate pdgat if it was not freed when offline.
    Date
    Since there is no way to guarentee the address of pgdat/zone is not
    on stack of any kernel threads or used by other kernel objects
    without reference counting or other symchronizing method, we cannot
    reset node_data and free pgdat when offlining a node. Just reset pgdat
    to 0 and reuse the memory when the node is online again.

    The problem is suggested by Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
    The idea is from Wen Congyang <wency@cn.fujitsu.com>

    NOTE: If we don't reset pgdat to 0, the WARN_ON in free_area_init_node()
    will be triggered.

    Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
    Reviewed-by: Wen Congyang <wency@cn.fujitsu.com>
    ---
    mm/memory_hotplug.c | 20 ++++++++++++--------
    1 files changed, 12 insertions(+), 8 deletions(-)

    diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
    index 8b67752..8aa2b56 100644
    --- a/mm/memory_hotplug.c
    +++ b/mm/memory_hotplug.c
    @@ -1015,11 +1015,14 @@ static pg_data_t __ref *hotadd_new_pgdat(int nid, u64 start)
    unsigned long zholes_size[MAX_NR_ZONES] = {0};
    unsigned long start_pfn = start >> PAGE_SHIFT;

    - pgdat = arch_alloc_nodedata(nid);
    - if (!pgdat)
    - return NULL;
    + pgdat = NODE_DATA(nid);
    + if (!pgdat) {
    + pgdat = arch_alloc_nodedata(nid);
    + if (!pgdat)
    + return NULL;

    - arch_refresh_nodedata(nid, pgdat);
    + arch_refresh_nodedata(nid, pgdat);
    + }

    /* we can use NODE_DATA(nid) from here */

    @@ -1072,7 +1075,7 @@ out:
    int __ref add_memory(int nid, u64 start, u64 size)
    {
    pg_data_t *pgdat = NULL;
    - int new_pgdat = 0;
    + int new_pgdat = 0, new_node = 0;
    struct resource *res;
    int ret;

    @@ -1083,12 +1086,13 @@ int __ref add_memory(int nid, u64 start, u64 size)
    if (!res)
    goto out;

    - if (!node_online(nid)) {
    + new_pgdat = NODE_DATA(nid) ? 0 : 1;
    + new_node = node_online(nid) ? 0 : 1;
    + if (new_node) {
    pgdat = hotadd_new_pgdat(nid, start);
    ret = -ENOMEM;
    if (!pgdat)
    goto error;
    - new_pgdat = 1;
    }

    /* call arch's memory hotadd */
    @@ -1100,7 +1104,7 @@ int __ref add_memory(int nid, u64 start, u64 size)
    /* we online node here. we can't roll back from here. */
    node_set_online(nid);

    - if (new_pgdat) {
    + if (new_node) {
    ret = register_one_node(nid);
    /*
    * If sysfs file of new node can't create, cpu on the node
    --
    1.7.1


    \
     
     \ /
      Last update: 2013-01-09 11:43    [W:3.275 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site