diff options
Diffstat (limited to 'mm/migrate.c')
| -rw-r--r-- | mm/migrate.c | 14 | 
1 files changed, 13 insertions, 1 deletions
diff --git a/mm/migrate.c b/mm/migrate.c index 3b676b0c5c3e..c38778610aa8 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1679,9 +1679,21 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,  	page_xchg_last_nid(new_page, page_last_nid(page));  	isolated = numamigrate_isolate_page(pgdat, page); -	if (!isolated) { + +	/* +	 * Failing to isolate or a GUP pin prevents migration. The expected +	 * page count is 2. 1 for anonymous pages without a mapping and 1 +	 * for the callers pin. If the page was isolated, the page will +	 * need to be put back on the LRU. +	 */ +	if (!isolated || page_count(page) != 2) {  		count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR);  		put_page(new_page); +		if (isolated) { +			putback_lru_page(page); +			isolated = 0; +			goto out; +		}  		goto out_keep_locked;  	}  | 
