mm/gup: allow to react to fatal signals
The existing gup code does not react to the fatal signals in many code paths. For example, in one retry path of gup we're still using down_read() rather than down_read_killable(). Also, when doing page faults we don't pass in FAULT_FLAG_KILLABLE as well, which means that within the faulting process we'll wait in non-killable way as well. These were spotted by Linus during the code review of some other patches. Let's allow the gup code to react to fatal signals to improve the responsiveness of threads when during gup and being killed. Signed-off-by: Peter Xu <peterx@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Tested-by: Brian Geffon <bgeffon@google.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Bobby Powers <bobbypowers@gmail.com> Cc: David Hildenbrand <david@redhat.com> Cc: Denis Plotnikov <dplotnikov@virtuozzo.com> Cc: "Dr . David Alan Gilbert" <dgilbert@redhat.com> Cc: Hugh Dickins <hughd@google.com> Cc: Jerome Glisse <jglisse@redhat.com> Cc: Johannes Weiner <hannes@cmpxchg.org> Cc: "Kirill A . Shutemov" <kirill@shutemov.name> Cc: Martin Cracauer <cracauer@cons.org> Cc: Marty McFadden <mcfadden8@llnl.gov> Cc: Matthew Wilcox <willy@infradead.org> Cc: Maya Gokhale <gokhale2@llnl.gov> Cc: Mel Gorman <mgorman@suse.de> Cc: Mike Kravetz <mike.kravetz@oracle.com> Cc: Mike Rapoport <rppt@linux.vnet.ibm.com> Cc: Pavel Emelyanov <xemul@openvz.org> Link: http://lkml.kernel.org/r/20200220160256.9887-1-peterx@redhat.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
4426e945df
commit
71335f37c5
12
mm/gup.c
12
mm/gup.c
|
@ -864,7 +864,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
|
||||||
if (*flags & FOLL_REMOTE)
|
if (*flags & FOLL_REMOTE)
|
||||||
fault_flags |= FAULT_FLAG_REMOTE;
|
fault_flags |= FAULT_FLAG_REMOTE;
|
||||||
if (locked)
|
if (locked)
|
||||||
fault_flags |= FAULT_FLAG_ALLOW_RETRY;
|
fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
|
||||||
if (*flags & FOLL_NOWAIT)
|
if (*flags & FOLL_NOWAIT)
|
||||||
fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT;
|
fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT;
|
||||||
if (*flags & FOLL_TRIED) {
|
if (*flags & FOLL_TRIED) {
|
||||||
|
@ -1207,7 +1207,7 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
|
||||||
address = untagged_addr(address);
|
address = untagged_addr(address);
|
||||||
|
|
||||||
if (unlocked)
|
if (unlocked)
|
||||||
fault_flags |= FAULT_FLAG_ALLOW_RETRY;
|
fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
vma = find_extend_vma(mm, address);
|
vma = find_extend_vma(mm, address);
|
||||||
|
@ -1329,7 +1329,13 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
*locked = 1;
|
*locked = 1;
|
||||||
down_read(&mm->mmap_sem);
|
ret = down_read_killable(&mm->mmap_sem);
|
||||||
|
if (ret) {
|
||||||
|
BUG_ON(ret > 0);
|
||||||
|
if (!pages_done)
|
||||||
|
pages_done = ret;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ret = __get_user_pages(tsk, mm, start, 1, flags | FOLL_TRIED,
|
ret = __get_user_pages(tsk, mm, start, 1, flags | FOLL_TRIED,
|
||||||
pages, NULL, locked);
|
pages, NULL, locked);
|
||||||
|
|
|
@ -4344,7 +4344,8 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
|
||||||
if (flags & FOLL_WRITE)
|
if (flags & FOLL_WRITE)
|
||||||
fault_flags |= FAULT_FLAG_WRITE;
|
fault_flags |= FAULT_FLAG_WRITE;
|
||||||
if (locked)
|
if (locked)
|
||||||
fault_flags |= FAULT_FLAG_ALLOW_RETRY;
|
fault_flags |= FAULT_FLAG_ALLOW_RETRY |
|
||||||
|
FAULT_FLAG_KILLABLE;
|
||||||
if (flags & FOLL_NOWAIT)
|
if (flags & FOLL_NOWAIT)
|
||||||
fault_flags |= FAULT_FLAG_ALLOW_RETRY |
|
fault_flags |= FAULT_FLAG_ALLOW_RETRY |
|
||||||
FAULT_FLAG_RETRY_NOWAIT;
|
FAULT_FLAG_RETRY_NOWAIT;
|
||||||
|
|
Loading…
Reference in New Issue