[V5 PATCH 18/26] hotplug: update nodemasks management
update nodemasks management for N_MEMORY Signed-off-by: Lai Jiangshan --- Documentation/memory-hotplug.txt |5 ++- include/linux/memory.h |1 + mm/memory_hotplug.c | 87 +++--- 3 files changed, 77 insertions(+), 16 deletions(-) diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt index c6f993d..8e5eacb 100644 --- a/Documentation/memory-hotplug.txt +++ b/Documentation/memory-hotplug.txt @@ -390,6 +390,7 @@ struct memory_notify { unsigned long start_pfn; unsigned long nr_pages; int status_change_nid_normal; + int status_change_nid_high; int status_change_nid; } @@ -397,7 +398,9 @@ start_pfn is start_pfn of online/offline memory. nr_pages is # of pages of online/offline memory. status_change_nid_normal is set node id when N_NORMAL_MEMORY of nodemask is (will be) set/clear, if this is -1, then nodemask status is not changed. -status_change_nid is set node id when N_HIGH_MEMORY of nodemask is (will be) +status_change_nid_high is set node id when N_HIGH_MEMORY of nodemask +is (will be) set/clear, if this is -1, then nodemask status is not changed. +status_change_nid is set node id when N_MEMORY of nodemask is (will be) set/clear. It means a new(memoryless) node gets new memory by online and a node loses all memory. If this is -1, then nodemask status is not changed. If status_changed_nid* >= 0, callback should create/discard structures for the diff --git a/include/linux/memory.h b/include/linux/memory.h index a09216d..45e93b4 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -54,6 +54,7 @@ struct memory_notify { unsigned long start_pfn; unsigned long nr_pages; int status_change_nid_normal; + int status_change_nid_high; int status_change_nid; }; diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 9af9641..a55b547 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -603,13 +603,15 @@ static void node_states_check_changes_online(unsigned long nr_pages, enum zone_type zone_last = ZONE_NORMAL; /* -* If we have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes -* which have 0...ZONE_NORMAL, set zone_last to ZONE_NORMAL. +* If we have HIGHMEM or movable node, node_states[N_NORMAL_MEMORY] +* contains nodes which have zones of 0...ZONE_NORMAL, +* set zone_last to ZONE_NORMAL. * -* If we don't have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes -* which have 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE. +* If we don't have HIGHMEM nor movable node, +* node_states[N_NORMAL_MEMORY] contains nodes which have zones of +* 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE. */ - if (N_HIGH_MEMORY == N_NORMAL_MEMORY) + if (N_MEMORY == N_NORMAL_MEMORY) zone_last = ZONE_MOVABLE; /* @@ -623,12 +625,34 @@ static void node_states_check_changes_online(unsigned long nr_pages, else arg->status_change_nid_normal = -1; +#ifdef CONFIG_HIGHMEM + /* +* If we have movable node, node_states[N_HIGH_MEMORY] +* contains nodes which have zones of 0...ZONE_HIGH, +* set zone_last to ZONE_HIGH. +* +* If we don't have movable node, node_states[N_NORMAL_MEMORY] +* contains nodes which have zones of 0...ZONE_MOVABLE, +* set zone_last to ZONE_MOVABLE. +*/ + zone_last = ZONE_HIGH; + if (N_MEMORY == N_HIGH_MEMORY) + zone_last = ZONE_MOVABLE; + + if (zone_idx(zone) <= zone_last && !node_state(nid, N_HIGH_MEMORY)) + arg->status_change_nid_high = nid; + else + arg->status_change_nid_high = -1; +#else + arg->status_change_nid_high = arg->status_change_nid_normal; +#endif + /* * if the node don't have memory befor online, we will need to -* set the node to node_states[N_HIGH_MEMORY] after the memory +* set the node to node_states[N_MEMORY] after the memory * is online. */ - if (!node_state(nid, N_HIGH_MEMORY)) + if (!node_state(nid, N_MEMORY)) arg->status_change_nid = nid; else arg->status_change_nid = -1; @@ -639,7 +663,10 @@ static void node_states_set_node(int node, struct memory_notify *arg) if (arg->status_change_nid_normal >= 0) node_set_state(node, N_NORMAL_MEMORY); - node_set_state(node, N_HIGH_MEMORY); + if (arg->status_change_nid_high >= 0) + node_set_state(node, N_HIGH_MEMORY); + + node_set_state(node, N_MEMORY); } @@ -1103,13 +1130,15 @@ static void node_states_check_changes_offline(unsigned long nr_pages, enum zone_type zt, zone_last = ZONE_NORMAL; /* -* If we have HIGHMEM, node_states[N_NORMAL_MEMORY] contains
[V5 PATCH 18/26] hotplug: update nodemasks management
update nodemasks management for N_MEMORY Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com --- Documentation/memory-hotplug.txt |5 ++- include/linux/memory.h |1 + mm/memory_hotplug.c | 87 +++--- 3 files changed, 77 insertions(+), 16 deletions(-) diff --git a/Documentation/memory-hotplug.txt b/Documentation/memory-hotplug.txt index c6f993d..8e5eacb 100644 --- a/Documentation/memory-hotplug.txt +++ b/Documentation/memory-hotplug.txt @@ -390,6 +390,7 @@ struct memory_notify { unsigned long start_pfn; unsigned long nr_pages; int status_change_nid_normal; + int status_change_nid_high; int status_change_nid; } @@ -397,7 +398,9 @@ start_pfn is start_pfn of online/offline memory. nr_pages is # of pages of online/offline memory. status_change_nid_normal is set node id when N_NORMAL_MEMORY of nodemask is (will be) set/clear, if this is -1, then nodemask status is not changed. -status_change_nid is set node id when N_HIGH_MEMORY of nodemask is (will be) +status_change_nid_high is set node id when N_HIGH_MEMORY of nodemask +is (will be) set/clear, if this is -1, then nodemask status is not changed. +status_change_nid is set node id when N_MEMORY of nodemask is (will be) set/clear. It means a new(memoryless) node gets new memory by online and a node loses all memory. If this is -1, then nodemask status is not changed. If status_changed_nid* = 0, callback should create/discard structures for the diff --git a/include/linux/memory.h b/include/linux/memory.h index a09216d..45e93b4 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -54,6 +54,7 @@ struct memory_notify { unsigned long start_pfn; unsigned long nr_pages; int status_change_nid_normal; + int status_change_nid_high; int status_change_nid; }; diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index 9af9641..a55b547 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -603,13 +603,15 @@ static void node_states_check_changes_online(unsigned long nr_pages, enum zone_type zone_last = ZONE_NORMAL; /* -* If we have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes -* which have 0...ZONE_NORMAL, set zone_last to ZONE_NORMAL. +* If we have HIGHMEM or movable node, node_states[N_NORMAL_MEMORY] +* contains nodes which have zones of 0...ZONE_NORMAL, +* set zone_last to ZONE_NORMAL. * -* If we don't have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes -* which have 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE. +* If we don't have HIGHMEM nor movable node, +* node_states[N_NORMAL_MEMORY] contains nodes which have zones of +* 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE. */ - if (N_HIGH_MEMORY == N_NORMAL_MEMORY) + if (N_MEMORY == N_NORMAL_MEMORY) zone_last = ZONE_MOVABLE; /* @@ -623,12 +625,34 @@ static void node_states_check_changes_online(unsigned long nr_pages, else arg-status_change_nid_normal = -1; +#ifdef CONFIG_HIGHMEM + /* +* If we have movable node, node_states[N_HIGH_MEMORY] +* contains nodes which have zones of 0...ZONE_HIGH, +* set zone_last to ZONE_HIGH. +* +* If we don't have movable node, node_states[N_NORMAL_MEMORY] +* contains nodes which have zones of 0...ZONE_MOVABLE, +* set zone_last to ZONE_MOVABLE. +*/ + zone_last = ZONE_HIGH; + if (N_MEMORY == N_HIGH_MEMORY) + zone_last = ZONE_MOVABLE; + + if (zone_idx(zone) = zone_last !node_state(nid, N_HIGH_MEMORY)) + arg-status_change_nid_high = nid; + else + arg-status_change_nid_high = -1; +#else + arg-status_change_nid_high = arg-status_change_nid_normal; +#endif + /* * if the node don't have memory befor online, we will need to -* set the node to node_states[N_HIGH_MEMORY] after the memory +* set the node to node_states[N_MEMORY] after the memory * is online. */ - if (!node_state(nid, N_HIGH_MEMORY)) + if (!node_state(nid, N_MEMORY)) arg-status_change_nid = nid; else arg-status_change_nid = -1; @@ -639,7 +663,10 @@ static void node_states_set_node(int node, struct memory_notify *arg) if (arg-status_change_nid_normal = 0) node_set_state(node, N_NORMAL_MEMORY); - node_set_state(node, N_HIGH_MEMORY); + if (arg-status_change_nid_high = 0) + node_set_state(node, N_HIGH_MEMORY); + + node_set_state(node, N_MEMORY); } @@ -1103,13 +1130,15 @@ static void node_states_check_changes_offline(unsigned long nr_pages, enum zone_type zt, zone_last = ZONE_NORMAL; /* -* If we have HIGHMEM, node_states[N_NORMAL_MEMORY]