mm/mempolicy.c | 10 +++++----- mm/pagewalk.c | 11 ++++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 4ae967bcf954..f8c99591592b 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -482,7 +482,7 @@ static int queue_pages_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, * * queue_pages_pte_range() has three possible return values: * 0 - pages are placed on the right node or queued successfully. - * 1 - there is unmovable page, and MPOL_MF_MOVE* & MPOL_MF_STRICT were + * -EBUSY - there is unmovable page, and MPOL_MF_MOVE* & MPOL_MF_STRICT were * specified. * -EIO - only MPOL_MF_STRICT was specified and an existing page was already * on a node that does not follow the policy. @@ -669,7 +669,7 @@ static const struct mm_walk_ops queue_pages_walk_ops = { * passed via @private. * * queue_pages_range() has three possible return values: - * 1 - there is unmovable page, but MPOL_MF_MOVE* & MPOL_MF_STRICT were + * -EBUSY - there is unmovable page, but MPOL_MF_MOVE* & MPOL_MF_STRICT were * specified. * 0 - queue pages successfully or no misplaced page. * -EIO - there is misplaced page and only MPOL_MF_STRICT was specified. @@ -1285,8 +1285,8 @@ static long do_mbind(unsigned long start, unsigned long len, ret = queue_pages_range(mm, start, end, nmask, flags | MPOL_MF_INVERT, &pagelist); - if (ret < 0) { - err = -EIO; + if (ret < 0 && ret != -EBUSY) { + err = ret; goto up_out; } @@ -1303,7 +1303,7 @@ static long do_mbind(unsigned long start, unsigned long len, putback_movable_pages(&pagelist); } - if ((ret > 0) || (nr_failed && (flags & MPOL_MF_STRICT))) + if ((ret < 0) || (nr_failed && (flags & MPOL_MF_STRICT))) err = -EIO; } else putback_movable_pages(&pagelist); diff --git a/mm/pagewalk.c b/mm/pagewalk.c index d48c2a986ea3..eb9d292588a2 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c @@ -49,10 +49,15 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end, * This implies that each ->pmd_entry() handler * needs to know about pmd_trans_huge() pmds */ - if (ops->pmd_entry) + if (ops->pmd_entry) { err = ops->pmd_entry(pmd, addr, next, walk); - if (err) - break; + if (err < 0) + break; + if (err > 0) { + err = 0; + continue; + } + } /* * Check this here so we only break down trans_huge