X-Git-Url: https://bbs.cooldavid.org/git/?a=blobdiff_plain;f=mm%2Fmigrate.c;h=fe5a3c6a54260f2ae9999fbaabe03082a818982f;hb=9ed05ad3c0629f434b18d20c51162f9bbb4f5d31;hp=d917ac3207f51b9f4c4ec2927f31db82159fc193;hpb=1b430beee5e388605dfb092b214ef0320f752cf6;p=net-next-2.6.git diff --git a/mm/migrate.c b/mm/migrate.c index d917ac3207f..fe5a3c6a542 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -883,8 +883,9 @@ out: * * The function returns after 10 attempts or if no pages * are movable anymore because to has become empty - * or no retryable pages exist anymore. All pages will be - * returned to the LRU or freed. + * or no retryable pages exist anymore. + * Caller should call putback_lru_pages to return pages to the LRU + * or free list. * * Return: Number of pages not migrated or error code. */ @@ -931,8 +932,6 @@ out: if (!swapwrite) current->flags &= ~PF_SWAPWRITE; - putback_lru_pages(from); - if (rc) return rc; @@ -1038,7 +1037,7 @@ static int do_move_page_to_node_array(struct mm_struct *mm, err = -EFAULT; vma = find_vma(mm, pp->addr); - if (!vma || !vma_migratable(vma)) + if (!vma || pp->addr < vma->vm_start || !vma_migratable(vma)) goto set_status; page = follow_page(vma, pp->addr, FOLL_GET); @@ -1087,9 +1086,12 @@ set_status: } err = 0; - if (!list_empty(&pagelist)) + if (!list_empty(&pagelist)) { err = migrate_pages(&pagelist, new_page_node, (unsigned long)pm, 0); + if (err) + putback_lru_pages(&pagelist); + } up_read(&mm->mmap_sem); return err; @@ -1202,7 +1204,7 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages, int err = -EFAULT; vma = find_vma(mm, addr); - if (!vma) + if (!vma || addr < vma->vm_start) goto set_status; page = follow_page(vma, addr, 0);