diff options
Diffstat (limited to 'mm/migrate.c')
| -rw-r--r-- | mm/migrate.c | 21 | 
1 files changed, 13 insertions, 8 deletions
diff --git a/mm/migrate.c b/mm/migrate.c index a26bccd44ccb..c04692774e88 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -161,6 +161,8 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,  	get_page(new);  	pte = pte_mkold(mk_pte(new, vma->vm_page_prot)); +	if (pte_swp_soft_dirty(*ptep)) +		pte = pte_mksoft_dirty(pte);  	if (is_write_migration_entry(entry))  		pte = pte_mkwrite(pte);  #ifdef CONFIG_HUGETLB_PAGE @@ -1713,12 +1715,12 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,  		unlock_page(new_page);  		put_page(new_page);		/* Free it */ -		unlock_page(page); +		/* Retake the callers reference and putback on LRU */ +		get_page(page);  		putback_lru_page(page); - -		count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR); -		isolated = 0; -		goto out; +		mod_zone_page_state(page_zone(page), +			 NR_ISOLATED_ANON + page_lru, -HPAGE_PMD_NR); +		goto out_fail;  	}  	/* @@ -1735,9 +1737,9 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,  	entry = maybe_pmd_mkwrite(pmd_mkdirty(entry), vma);  	entry = pmd_mkhuge(entry); -	page_add_new_anon_rmap(new_page, vma, haddr); - +	pmdp_clear_flush(vma, haddr, pmd);  	set_pmd_at(mm, haddr, pmd, entry); +	page_add_new_anon_rmap(new_page, vma, haddr);  	update_mmu_cache_pmd(vma, address, &entry);  	page_remove_rmap(page);  	/* @@ -1756,7 +1758,6 @@ int migrate_misplaced_transhuge_page(struct mm_struct *mm,  	count_vm_events(PGMIGRATE_SUCCESS, HPAGE_PMD_NR);  	count_vm_numa_events(NUMA_PAGE_MIGRATE, HPAGE_PMD_NR); -out:  	mod_zone_page_state(page_zone(page),  			NR_ISOLATED_ANON + page_lru,  			-HPAGE_PMD_NR); @@ -1765,6 +1766,10 @@ out:  out_fail:  	count_vm_events(PGMIGRATE_FAIL, HPAGE_PMD_NR);  out_dropref: +	entry = pmd_mknonnuma(entry); +	set_pmd_at(mm, haddr, pmd, entry); +	update_mmu_cache_pmd(vma, address, &entry); +  	unlock_page(page);  	put_page(page);  	return 0;  | 
