mm: page_isolation: enable arbitrary range page isolation.
Now start_isolate_page_range() is ready to handle arbitrary range isolation, so move the alignment check/adjustment into the function body. Do the same for its counterpart undo_isolate_page_range(). alloc_contig_range(), its caller, can pass an arbitrary range instead of a MAX_ORDER_NR_PAGES aligned one. Link: https://lkml.kernel.org/r/20220425143118.2850746-5-zi.yan@sent.com Signed-off-by: Zi Yan <ziy@nvidia.com> Cc: Christophe Leroy <christophe.leroy@csgroup.eu> Cc: David Hildenbrand <david@redhat.com> Cc: Eric Ren <renzhengeek@gmail.com> Cc: kernel test robot <lkp@intel.com> Cc: Mel Gorman <mgorman@techsingularity.net> Cc: Mike Rapoport <rppt@linux.ibm.com> Cc: Minchan Kim <minchan@kernel.org> Cc: Oscar Salvador <osalvador@suse.de> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
Родитель
b2c9e2fbba
Коммит
6e263fff1d
|
@ -8956,16 +8956,6 @@ void *__init alloc_large_system_hash(const char *tablename,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CONTIG_ALLOC
|
#ifdef CONFIG_CONTIG_ALLOC
|
||||||
static unsigned long pfn_max_align_down(unsigned long pfn)
|
|
||||||
{
|
|
||||||
return ALIGN_DOWN(pfn, MAX_ORDER_NR_PAGES);
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long pfn_max_align_up(unsigned long pfn)
|
|
||||||
{
|
|
||||||
return ALIGN(pfn, MAX_ORDER_NR_PAGES);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(CONFIG_DYNAMIC_DEBUG) || \
|
#if defined(CONFIG_DYNAMIC_DEBUG) || \
|
||||||
(defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE))
|
(defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE))
|
||||||
/* Usage: See admin-guide/dynamic-debug-howto.rst */
|
/* Usage: See admin-guide/dynamic-debug-howto.rst */
|
||||||
|
@ -9107,8 +9097,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
|
||||||
* put back to page allocator so that buddy can use them.
|
* put back to page allocator so that buddy can use them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = start_isolate_page_range(pfn_max_align_down(start),
|
ret = start_isolate_page_range(start, end, migratetype, 0, gfp_mask);
|
||||||
pfn_max_align_up(end), migratetype, 0, gfp_mask);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
@ -9189,8 +9178,7 @@ int alloc_contig_range(unsigned long start, unsigned long end,
|
||||||
free_contig_range(end, outer_end - end);
|
free_contig_range(end, outer_end - end);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
undo_isolate_page_range(pfn_max_align_down(start),
|
undo_isolate_page_range(start, end, migratetype);
|
||||||
pfn_max_align_up(end), migratetype);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(alloc_contig_range);
|
EXPORT_SYMBOL(alloc_contig_range);
|
||||||
|
|
|
@ -444,7 +444,6 @@ failed:
|
||||||
* be MIGRATE_ISOLATE.
|
* be MIGRATE_ISOLATE.
|
||||||
* @start_pfn: The lower PFN of the range to be isolated.
|
* @start_pfn: The lower PFN of the range to be isolated.
|
||||||
* @end_pfn: The upper PFN of the range to be isolated.
|
* @end_pfn: The upper PFN of the range to be isolated.
|
||||||
* start_pfn/end_pfn must be aligned to pageblock_order.
|
|
||||||
* @migratetype: Migrate type to set in error recovery.
|
* @migratetype: Migrate type to set in error recovery.
|
||||||
* @flags: The following flags are allowed (they can be combined in
|
* @flags: The following flags are allowed (they can be combined in
|
||||||
* a bit mask)
|
* a bit mask)
|
||||||
|
@ -491,33 +490,33 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
|
||||||
{
|
{
|
||||||
unsigned long pfn;
|
unsigned long pfn;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
/* isolation is done at page block granularity */
|
||||||
|
unsigned long isolate_start = ALIGN_DOWN(start_pfn, pageblock_nr_pages);
|
||||||
|
unsigned long isolate_end = ALIGN(end_pfn, pageblock_nr_pages);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages));
|
/* isolate [isolate_start, isolate_start + pageblock_nr_pages) pageblock */
|
||||||
BUG_ON(!IS_ALIGNED(end_pfn, pageblock_nr_pages));
|
ret = isolate_single_pageblock(isolate_start, gfp_flags, false);
|
||||||
|
|
||||||
/* isolate [start_pfn, start_pfn + pageblock_nr_pages) pageblock */
|
|
||||||
ret = isolate_single_pageblock(start_pfn, gfp_flags, false);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* isolate [end_pfn - pageblock_nr_pages, end_pfn) pageblock */
|
/* isolate [isolate_end - pageblock_nr_pages, isolate_end) pageblock */
|
||||||
ret = isolate_single_pageblock(end_pfn, gfp_flags, true);
|
ret = isolate_single_pageblock(isolate_end, gfp_flags, true);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
unset_migratetype_isolate(pfn_to_page(start_pfn), migratetype);
|
unset_migratetype_isolate(pfn_to_page(isolate_start), migratetype);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip isolated pageblocks at the beginning and end */
|
/* skip isolated pageblocks at the beginning and end */
|
||||||
for (pfn = start_pfn + pageblock_nr_pages;
|
for (pfn = isolate_start + pageblock_nr_pages;
|
||||||
pfn < end_pfn - pageblock_nr_pages;
|
pfn < isolate_end - pageblock_nr_pages;
|
||||||
pfn += pageblock_nr_pages) {
|
pfn += pageblock_nr_pages) {
|
||||||
page = __first_valid_page(pfn, pageblock_nr_pages);
|
page = __first_valid_page(pfn, pageblock_nr_pages);
|
||||||
if (page && set_migratetype_isolate(page, migratetype, flags,
|
if (page && set_migratetype_isolate(page, migratetype, flags,
|
||||||
start_pfn, end_pfn)) {
|
start_pfn, end_pfn)) {
|
||||||
undo_isolate_page_range(start_pfn, pfn, migratetype);
|
undo_isolate_page_range(isolate_start, pfn, migratetype);
|
||||||
unset_migratetype_isolate(
|
unset_migratetype_isolate(
|
||||||
pfn_to_page(end_pfn - pageblock_nr_pages),
|
pfn_to_page(isolate_end - pageblock_nr_pages),
|
||||||
migratetype);
|
migratetype);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
@ -533,12 +532,12 @@ void undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn,
|
||||||
{
|
{
|
||||||
unsigned long pfn;
|
unsigned long pfn;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
|
unsigned long isolate_start = ALIGN_DOWN(start_pfn, pageblock_nr_pages);
|
||||||
|
unsigned long isolate_end = ALIGN(end_pfn, pageblock_nr_pages);
|
||||||
|
|
||||||
BUG_ON(!IS_ALIGNED(start_pfn, pageblock_nr_pages));
|
|
||||||
BUG_ON(!IS_ALIGNED(end_pfn, pageblock_nr_pages));
|
|
||||||
|
|
||||||
for (pfn = start_pfn;
|
for (pfn = isolate_start;
|
||||||
pfn < end_pfn;
|
pfn < isolate_end;
|
||||||
pfn += pageblock_nr_pages) {
|
pfn += pageblock_nr_pages) {
|
||||||
page = __first_valid_page(pfn, pageblock_nr_pages);
|
page = __first_valid_page(pfn, pageblock_nr_pages);
|
||||||
if (!page || !is_migrate_isolate_page(page))
|
if (!page || !is_migrate_isolate_page(page))
|
||||||
|
|
Загрузка…
Ссылка в новой задаче