mm, mempolicy: fix up gup usage in lookup_node
ba841078cd
("mm/mempolicy: Allow lookup_node() to handle fatal signal") has added a special casing for 0 return value because that was a possible gup return value when interrupted by fatal signal. This has been fixed byae46d2aa6a
("mm/gup: Let __get_user_pages_locked() return -EINTR for fatal signal") in the mean time soba841078cd
can be reverted. This patch however doesn't go all the way to revert it because the check for 0 is wrong and confusing here. Firstly it is inherently unsafe to access the page when get_user_pages_locked returns 0 (aka no page returned). Fortunatelly this will not happen because get_user_pages_locked will not return 0 when nr_pages > 0 unless FOLL_NOWAIT is specified which is not the case here. Document this potential error code in gup code while we are at it. Signed-off-by: Michal Hocko <mhocko@suse.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Cc: Peter Xu <peterx@redhat.com> Link: http://lkml.kernel.org/r/20200421071026.18394-1-mhocko@kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
5b94ce2fca
commit
2d3a36a479
5
mm/gup.c
5
mm/gup.c
@ -989,6 +989,7 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags)
|
||||
* -- If nr_pages is >0, but no pages were pinned, returns -errno.
|
||||
* -- If nr_pages is >0, and some pages were pinned, returns the number of
|
||||
* pages pinned. Again, this may be less than nr_pages.
|
||||
* -- 0 return value is possible when the fault would need to be retried.
|
||||
*
|
||||
* The caller is responsible for releasing returned @pages, via put_page().
|
||||
*
|
||||
@ -1265,6 +1266,10 @@ retry:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fixup_user_fault);
|
||||
|
||||
/*
|
||||
* Please note that this function, unlike __get_user_pages will not
|
||||
* return 0 for nr_pages > 0 without FOLL_NOWAIT
|
||||
*/
|
||||
static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
|
||||
struct mm_struct *mm,
|
||||
unsigned long start,
|
||||
|
@ -927,10 +927,7 @@ static int lookup_node(struct mm_struct *mm, unsigned long addr)
|
||||
|
||||
int locked = 1;
|
||||
err = get_user_pages_locked(addr & PAGE_MASK, 1, 0, &p, &locked);
|
||||
if (err == 0) {
|
||||
/* E.g. GUP interrupted by fatal signal */
|
||||
err = -EFAULT;
|
||||
} else if (err > 0) {
|
||||
if (err > 0) {
|
||||
err = page_to_nid(p);
|
||||
put_page(p);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user