|
|
@@ -614,7 +614,7 @@ static int move_to_new_page(struct page *newpage, struct page *page,
|
|
|
* to the newly allocated page in newpage.
|
|
|
*/
|
|
|
static int unmap_and_move(new_page_t get_new_page, unsigned long private,
|
|
|
- struct page *page, int force, int offlining)
|
|
|
+ struct page *page, int force, int offlining, bool sync)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
int *result = NULL;
|
|
|
@@ -682,7 +682,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
|
|
|
BUG_ON(charge);
|
|
|
|
|
|
if (PageWriteback(page)) {
|
|
|
- if (!force)
|
|
|
+ if (!force || !sync)
|
|
|
goto uncharge;
|
|
|
wait_on_page_writeback(page);
|
|
|
}
|
|
|
@@ -827,7 +827,7 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
|
|
|
*/
|
|
|
static int unmap_and_move_huge_page(new_page_t get_new_page,
|
|
|
unsigned long private, struct page *hpage,
|
|
|
- int force, int offlining)
|
|
|
+ int force, int offlining, bool sync)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
int *result = NULL;
|
|
|
@@ -841,7 +841,7 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
|
|
|
rc = -EAGAIN;
|
|
|
|
|
|
if (!trylock_page(hpage)) {
|
|
|
- if (!force)
|
|
|
+ if (!force || !sync)
|
|
|
goto out;
|
|
|
lock_page(hpage);
|
|
|
}
|
|
|
@@ -909,7 +909,8 @@ static int unmap_and_move_huge_page(new_page_t get_new_page,
|
|
|
* Return: Number of pages not migrated or error code.
|
|
|
*/
|
|
|
int migrate_pages(struct list_head *from,
|
|
|
- new_page_t get_new_page, unsigned long private, int offlining)
|
|
|
+ new_page_t get_new_page, unsigned long private, int offlining,
|
|
|
+ bool sync)
|
|
|
{
|
|
|
int retry = 1;
|
|
|
int nr_failed = 0;
|
|
|
@@ -929,7 +930,8 @@ int migrate_pages(struct list_head *from,
|
|
|
cond_resched();
|
|
|
|
|
|
rc = unmap_and_move(get_new_page, private,
|
|
|
- page, pass > 2, offlining);
|
|
|
+ page, pass > 2, offlining,
|
|
|
+ sync);
|
|
|
|
|
|
switch(rc) {
|
|
|
case -ENOMEM:
|
|
|
@@ -958,7 +960,8 @@ int migrate_pages(struct list_head *from,
|
|
|
}
|
|
|
|
|
|
int migrate_huge_pages(struct list_head *from,
|
|
|
- new_page_t get_new_page, unsigned long private, int offlining)
|
|
|
+ new_page_t get_new_page, unsigned long private, int offlining,
|
|
|
+ bool sync)
|
|
|
{
|
|
|
int retry = 1;
|
|
|
int nr_failed = 0;
|
|
|
@@ -974,7 +977,8 @@ int migrate_huge_pages(struct list_head *from,
|
|
|
cond_resched();
|
|
|
|
|
|
rc = unmap_and_move_huge_page(get_new_page,
|
|
|
- private, page, pass > 2, offlining);
|
|
|
+ private, page, pass > 2, offlining,
|
|
|
+ sync);
|
|
|
|
|
|
switch(rc) {
|
|
|
case -ENOMEM:
|
|
|
@@ -1107,7 +1111,7 @@ static int do_move_page_to_node_array(struct mm_struct *mm,
|
|
|
err = 0;
|
|
|
if (!list_empty(&pagelist)) {
|
|
|
err = migrate_pages(&pagelist, new_page_node,
|
|
|
- (unsigned long)pm, 0);
|
|
|
+ (unsigned long)pm, 0, true);
|
|
|
if (err)
|
|
|
putback_lru_pages(&pagelist);
|
|
|
}
|