mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
mm/compaction: split freepages without holding the zone lock
We don't need to split freepages with holding the zone lock. It will cause more contention on zone lock so not desirable. [[email protected]: if __isolate_free_page() fails, avoid adding to freelist so we don't call map_pages() with it] Link: http://lkml.kernel.org/r/[email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Joonsoo Kim <[email protected]> Acked-by: Vlastimil Babka <[email protected]> Cc: Mel Gorman <[email protected]> Cc: Minchan Kim <[email protected]> Cc: Alexander Potapenko <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Michal Hocko <[email protected]> Signed-off-by: David Rientjes <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
3b1d9ca65a
commit
66c64223ad
3 changed files with 33 additions and 42 deletions
|
|
@ -64,13 +64,31 @@ static unsigned long release_freepages(struct list_head *freelist)
|
|||
|
||||
static void map_pages(struct list_head *list)
|
||||
{
|
||||
struct page *page;
|
||||
unsigned int i, order, nr_pages;
|
||||
struct page *page, *next;
|
||||
LIST_HEAD(tmp_list);
|
||||
|
||||
list_for_each_entry(page, list, lru) {
|
||||
arch_alloc_page(page, 0);
|
||||
kernel_map_pages(page, 1, 1);
|
||||
kasan_alloc_pages(page, 0);
|
||||
list_for_each_entry_safe(page, next, list, lru) {
|
||||
list_del(&page->lru);
|
||||
|
||||
order = page_private(page);
|
||||
nr_pages = 1 << order;
|
||||
set_page_private(page, 0);
|
||||
set_page_refcounted(page);
|
||||
|
||||
arch_alloc_page(page, order);
|
||||
kernel_map_pages(page, nr_pages, 1);
|
||||
kasan_alloc_pages(page, order);
|
||||
if (order)
|
||||
split_page(page, order);
|
||||
|
||||
for (i = 0; i < nr_pages; i++) {
|
||||
list_add(&page->lru, &tmp_list);
|
||||
page++;
|
||||
}
|
||||
}
|
||||
|
||||
list_splice(&tmp_list, list);
|
||||
}
|
||||
|
||||
static inline bool migrate_async_suitable(int migratetype)
|
||||
|
|
@ -405,12 +423,13 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
|
|||
unsigned long flags = 0;
|
||||
bool locked = false;
|
||||
unsigned long blockpfn = *start_pfn;
|
||||
unsigned int order;
|
||||
|
||||
cursor = pfn_to_page(blockpfn);
|
||||
|
||||
/* Isolate free pages. */
|
||||
for (; blockpfn < end_pfn; blockpfn++, cursor++) {
|
||||
int isolated, i;
|
||||
int isolated;
|
||||
struct page *page = cursor;
|
||||
|
||||
/*
|
||||
|
|
@ -476,17 +495,17 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
|
|||
goto isolate_fail;
|
||||
}
|
||||
|
||||
/* Found a free page, break it into order-0 pages */
|
||||
isolated = split_free_page(page);
|
||||
/* Found a free page, will break it into order-0 pages */
|
||||
order = page_order(page);
|
||||
isolated = __isolate_free_page(page, order);
|
||||
if (!isolated)
|
||||
break;
|
||||
set_page_private(page, order);
|
||||
|
||||
total_isolated += isolated;
|
||||
cc->nr_freepages += isolated;
|
||||
for (i = 0; i < isolated; i++) {
|
||||
list_add(&page->lru, freelist);
|
||||
page++;
|
||||
}
|
||||
list_add_tail(&page->lru, freelist);
|
||||
|
||||
if (!strict && cc->nr_migratepages <= cc->nr_freepages) {
|
||||
blockpfn += isolated;
|
||||
break;
|
||||
|
|
@ -605,7 +624,7 @@ isolate_freepages_range(struct compact_control *cc,
|
|||
*/
|
||||
}
|
||||
|
||||
/* split_free_page does not map the pages */
|
||||
/* __isolate_free_page() does not map the pages */
|
||||
map_pages(&freelist);
|
||||
|
||||
if (pfn < end_pfn) {
|
||||
|
|
@ -1102,7 +1121,7 @@ static void isolate_freepages(struct compact_control *cc)
|
|||
}
|
||||
}
|
||||
|
||||
/* split_free_page does not map the pages */
|
||||
/* __isolate_free_page() does not map the pages */
|
||||
map_pages(freelist);
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue