aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory_hotplug.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/memory_hotplug.c')
-rw-r--r--mm/memory_hotplug.c87
1 files changed, 72 insertions, 15 deletions
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index de9cb14ae753..eca4aac1a83b 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -595,13 +595,15 @@ static void node_states_check_changes_online(unsigned long nr_pages,
595 enum zone_type zone_last = ZONE_NORMAL; 595 enum zone_type zone_last = ZONE_NORMAL;
596 596
597 /* 597 /*
598 * If we have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes 598 * If we have HIGHMEM or movable node, node_states[N_NORMAL_MEMORY]
599 * which have 0...ZONE_NORMAL, set zone_last to ZONE_NORMAL. 599 * contains nodes which have zones of 0...ZONE_NORMAL,
600 * set zone_last to ZONE_NORMAL.
600 * 601 *
601 * If we don't have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes 602 * If we don't have HIGHMEM nor movable node,
602 * which have 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE. 603 * node_states[N_NORMAL_MEMORY] contains nodes which have zones of
604 * 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE.
603 */ 605 */
604 if (N_HIGH_MEMORY == N_NORMAL_MEMORY) 606 if (N_MEMORY == N_NORMAL_MEMORY)
605 zone_last = ZONE_MOVABLE; 607 zone_last = ZONE_MOVABLE;
606 608
607 /* 609 /*
@@ -615,12 +617,34 @@ static void node_states_check_changes_online(unsigned long nr_pages,
615 else 617 else
616 arg->status_change_nid_normal = -1; 618 arg->status_change_nid_normal = -1;
617 619
620#ifdef CONFIG_HIGHMEM
621 /*
622 * If we have movable node, node_states[N_HIGH_MEMORY]
623 * contains nodes which have zones of 0...ZONE_HIGHMEM,
624 * set zone_last to ZONE_HIGHMEM.
625 *
626 * If we don't have movable node, node_states[N_NORMAL_MEMORY]
627 * contains nodes which have zones of 0...ZONE_MOVABLE,
628 * set zone_last to ZONE_MOVABLE.
629 */
630 zone_last = ZONE_HIGHMEM;
631 if (N_MEMORY == N_HIGH_MEMORY)
632 zone_last = ZONE_MOVABLE;
633
634 if (zone_idx(zone) <= zone_last && !node_state(nid, N_HIGH_MEMORY))
635 arg->status_change_nid_high = nid;
636 else
637 arg->status_change_nid_high = -1;
638#else
639 arg->status_change_nid_high = arg->status_change_nid_normal;
640#endif
641
618 /* 642 /*
619 * if the node don't have memory befor online, we will need to 643 * if the node don't have memory befor online, we will need to
620 * set the node to node_states[N_HIGH_MEMORY] after the memory 644 * set the node to node_states[N_MEMORY] after the memory
621 * is online. 645 * is online.
622 */ 646 */
623 if (!node_state(nid, N_HIGH_MEMORY)) 647 if (!node_state(nid, N_MEMORY))
624 arg->status_change_nid = nid; 648 arg->status_change_nid = nid;
625 else 649 else
626 arg->status_change_nid = -1; 650 arg->status_change_nid = -1;
@@ -631,7 +655,10 @@ static void node_states_set_node(int node, struct memory_notify *arg)
631 if (arg->status_change_nid_normal >= 0) 655 if (arg->status_change_nid_normal >= 0)
632 node_set_state(node, N_NORMAL_MEMORY); 656 node_set_state(node, N_NORMAL_MEMORY);
633 657
634 node_set_state(node, N_HIGH_MEMORY); 658 if (arg->status_change_nid_high >= 0)
659 node_set_state(node, N_HIGH_MEMORY);
660
661 node_set_state(node, N_MEMORY);
635} 662}
636 663
637 664
@@ -1099,13 +1126,15 @@ static void node_states_check_changes_offline(unsigned long nr_pages,
1099 enum zone_type zt, zone_last = ZONE_NORMAL; 1126 enum zone_type zt, zone_last = ZONE_NORMAL;
1100 1127
1101 /* 1128 /*
1102 * If we have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes 1129 * If we have HIGHMEM or movable node, node_states[N_NORMAL_MEMORY]
1103 * which have 0...ZONE_NORMAL, set zone_last to ZONE_NORMAL. 1130 * contains nodes which have zones of 0...ZONE_NORMAL,
1131 * set zone_last to ZONE_NORMAL.
1104 * 1132 *
1105 * If we don't have HIGHMEM, node_states[N_NORMAL_MEMORY] contains nodes 1133 * If we don't have HIGHMEM nor movable node,
1106 * which have 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE. 1134 * node_states[N_NORMAL_MEMORY] contains nodes which have zones of
1135 * 0...ZONE_MOVABLE, set zone_last to ZONE_MOVABLE.
1107 */ 1136 */
1108 if (N_HIGH_MEMORY == N_NORMAL_MEMORY) 1137 if (N_MEMORY == N_NORMAL_MEMORY)
1109 zone_last = ZONE_MOVABLE; 1138 zone_last = ZONE_MOVABLE;
1110 1139
1111 /* 1140 /*
@@ -1122,6 +1151,30 @@ static void node_states_check_changes_offline(unsigned long nr_pages,
1122 else 1151 else
1123 arg->status_change_nid_normal = -1; 1152 arg->status_change_nid_normal = -1;
1124 1153
1154#ifdef CONFIG_HIGHMEM
1155 /*
1156 * If we have movable node, node_states[N_HIGH_MEMORY]
1157 * contains nodes which have zones of 0...ZONE_HIGHMEM,
1158 * set zone_last to ZONE_HIGHMEM.
1159 *
1160 * If we don't have movable node, node_states[N_NORMAL_MEMORY]
1161 * contains nodes which have zones of 0...ZONE_MOVABLE,
1162 * set zone_last to ZONE_MOVABLE.
1163 */
1164 zone_last = ZONE_HIGHMEM;
1165 if (N_MEMORY == N_HIGH_MEMORY)
1166 zone_last = ZONE_MOVABLE;
1167
1168 for (; zt <= zone_last; zt++)
1169 present_pages += pgdat->node_zones[zt].present_pages;
1170 if (zone_idx(zone) <= zone_last && nr_pages >= present_pages)
1171 arg->status_change_nid_high = zone_to_nid(zone);
1172 else
1173 arg->status_change_nid_high = -1;
1174#else
1175 arg->status_change_nid_high = arg->status_change_nid_normal;
1176#endif
1177
1125 /* 1178 /*
1126 * node_states[N_HIGH_MEMORY] contains nodes which have 0...ZONE_MOVABLE 1179 * node_states[N_HIGH_MEMORY] contains nodes which have 0...ZONE_MOVABLE
1127 */ 1180 */
@@ -1146,9 +1199,13 @@ static void node_states_clear_node(int node, struct memory_notify *arg)
1146 if (arg->status_change_nid_normal >= 0) 1199 if (arg->status_change_nid_normal >= 0)
1147 node_clear_state(node, N_NORMAL_MEMORY); 1200 node_clear_state(node, N_NORMAL_MEMORY);
1148 1201
1149 if ((N_HIGH_MEMORY != N_NORMAL_MEMORY) && 1202 if ((N_MEMORY != N_NORMAL_MEMORY) &&
1150 (arg->status_change_nid >= 0)) 1203 (arg->status_change_nid_high >= 0))
1151 node_clear_state(node, N_HIGH_MEMORY); 1204 node_clear_state(node, N_HIGH_MEMORY);
1205
1206 if ((N_MEMORY != N_HIGH_MEMORY) &&
1207 (arg->status_change_nid >= 0))
1208 node_clear_state(node, N_MEMORY);
1152} 1209}
1153 1210
1154static int __ref __offline_pages(unsigned long start_pfn, 1211static int __ref __offline_pages(unsigned long start_pfn,