On 2019-10-31 at 02:14 Yang Shi wrote: > > >On 10/30/19 9:58 AM, Yang Shi wrote: >> The commit d883544515aa ("mm: mempolicy: make the behavior consistent >> when MPOL_MF_MOVE* and MPOL_MF_STRICT were specified") fixed the return >> value of mbind() for a couple of corner cases. But, it altered the >> errno for some other cases, for example, mbind() should return -EFAULT >> when part or all of the memory range specified by nodemask and maxnode >> points outside your accessible address space, or there was an unmapped >> hole in the specified memory range specified by addr and len. >> >> Fixed this by preserving the errno returned by queue_pages_range(). >> And, the pagelist may be not empty even though queue_pages_range() >> returns error, put the pages back to LRU since mbind_range() is not called >> to really apply the policy so those pages should not be migrated, this >> is also the old behavior before the problematic commit. >Forgot fixes tag. > >Fixes: d883544515aa ("mm: mempolicy: make the behavior consistent when >MPOL_MF_MOVE* and MPOL_MF_STRICT were specified") > Looks good to me. Reviewed-by: Li Xinhai <lixinhai.lxh@xxxxxxxxx> >> Reported-by: Li Xinhai <lixinhai.lxh@xxxxxxxxx> >> Cc: Vlastimil Babka <vbabka@xxxxxxx> >> Cc: Michal Hocko <mhocko@xxxxxxxx> >> Cc: Mel Gorman <mgorman@xxxxxxxxxxxxxxxxxxx> >> Cc: <stable@xxxxxxxxxxxxxxx> v4.19 and v5.2+ >> Signed-off-by: Yang Shi <yang.shi@xxxxxxxxxxxxxxxxx> >> --- >> mm/mempolicy.c | 14 +++++++++----- >> 1 file changed, 9 insertions(+), 5 deletions(-) >> >> diff --git a/mm/mempolicy.c b/mm/mempolicy.c >> index 4ae967b..e08c941 100644 >> --- a/mm/mempolicy.c >> +++ b/mm/mempolicy.c >> @@ -672,7 +672,9 @@ static int queue_pages_test_walk(unsigned long start, unsigned long end, >> * 1 - 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. >> + * errno - i.e. misplaced pages with MPOL_MF_STRICT specified (-EIO) or >> + * memory range specified by nodemask and maxnode points outside >> + * your accessible address space (-EFAULT) >> */ >> static int >> queue_pages_range(struct mm_struct *mm, unsigned long start, unsigned long end, >> @@ -1286,7 +1288,7 @@ static long do_mbind(unsigned long start, unsigned long len, >> flags | MPOL_MF_INVERT, &pagelist); >> >> if (ret < 0) { >> - err = -EIO; >> + err = ret; >> goto up_out; >> } >> >> @@ -1305,10 +1307,12 @@ static long do_mbind(unsigned long start, unsigned long len, >> >> if ((ret > 0) || (nr_failed && (flags & MPOL_MF_STRICT))) >> err = -EIO; >> - } else >> - putback_movable_pages(&pagelist); >> - >> + } else { >> up_out: >> + if (!list_empty(&pagelist)) >> + putback_movable_pages(&pagelist); >> + } >> + >> up_write(&mm->mmap_sem); >> mpol_out: >> mpol_put(new); >