Skip to content

Commit bb8965b

Browse files
Michal Hockotorvalds
authored andcommitted
mm, memory_hotplug: deobfuscate migration part of offlining
Memory migration might fail during offlining and we keep retrying in that case. This is currently obfuscated by goto retry loop. The code is hard to follow and as a result it is even suboptimal becase each retry round scans the full range from start_pfn even though we have successfully scanned/migrated [start_pfn, pfn] range already. This is all only because check_pages_isolated failure has to rescan the full range again. De-obfuscate the migration retry loop by promoting it to a real for loop. In fact remove the goto altogether by making it a proper double loop (yeah, gotos are nasty in this specific case). In the end we will get a slightly more optimal code which is better readable. [akpm@linux-foundation.org: reflow comments to 80 cols] Link: http://lkml.kernel.org/r/20181211142741.2607-3-mhocko@kernel.org Signed-off-by: Michal Hocko <mhocko@suse.com> Reviewed-by: David Hildenbrand <david@redhat.com> Reviewed-by: Oscar Salvador <osalvador@suse.de> Cc: Hugh Dickins <hughd@google.com> Cc: Jan Kara <jack@suse.cz> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: Pavel Tatashin <pasha.tatashin@soleen.com> Cc: William Kucharski <william.kucharski@oracle.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent a85009c commit bb8965b

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

mm/memory_hotplug.c

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,38 +1607,42 @@ static int __ref __offline_pages(unsigned long start_pfn,
16071607
goto failed_removal_isolated;
16081608
}
16091609

1610-
pfn = start_pfn;
1611-
repeat:
1612-
/* start memory hot removal */
1613-
ret = -EINTR;
1614-
if (signal_pending(current)) {
1615-
reason = "signal backoff";
1616-
goto failed_removal_isolated;
1617-
}
1610+
do {
1611+
for (pfn = start_pfn; pfn;) {
1612+
if (signal_pending(current)) {
1613+
ret = -EINTR;
1614+
reason = "signal backoff";
1615+
goto failed_removal_isolated;
1616+
}
16181617

1619-
cond_resched();
1620-
lru_add_drain_all();
1621-
drain_all_pages(zone);
1618+
cond_resched();
1619+
lru_add_drain_all();
1620+
drain_all_pages(zone);
1621+
1622+
pfn = scan_movable_pages(pfn, end_pfn);
1623+
if (pfn) {
1624+
/*
1625+
* TODO: fatal migration failures should bail
1626+
* out
1627+
*/
1628+
do_migrate_range(pfn, end_pfn);
1629+
}
1630+
}
16221631

1623-
pfn = scan_movable_pages(start_pfn, end_pfn);
1624-
if (pfn) { /* We have movable pages */
1625-
ret = do_migrate_range(pfn, end_pfn);
1626-
goto repeat;
1627-
}
1632+
/*
1633+
* Dissolve free hugepages in the memory block before doing
1634+
* offlining actually in order to make hugetlbfs's object
1635+
* counting consistent.
1636+
*/
1637+
ret = dissolve_free_huge_pages(start_pfn, end_pfn);
1638+
if (ret) {
1639+
reason = "failure to dissolve huge pages";
1640+
goto failed_removal_isolated;
1641+
}
1642+
/* check again */
1643+
offlined_pages = check_pages_isolated(start_pfn, end_pfn);
1644+
} while (offlined_pages < 0);
16281645

1629-
/*
1630-
* dissolve free hugepages in the memory block before doing offlining
1631-
* actually in order to make hugetlbfs's object counting consistent.
1632-
*/
1633-
ret = dissolve_free_huge_pages(start_pfn, end_pfn);
1634-
if (ret) {
1635-
reason = "failure to dissolve huge pages";
1636-
goto failed_removal_isolated;
1637-
}
1638-
/* check again */
1639-
offlined_pages = check_pages_isolated(start_pfn, end_pfn);
1640-
if (offlined_pages < 0)
1641-
goto repeat;
16421646
pr_info("Offlined Pages %ld\n", offlined_pages);
16431647
/* Ok, all of our target is isolated.
16441648
We cannot do rollback at this point. */

0 commit comments

Comments
 (0)