[Devel] [PATCH vz8 19/42] mm/gup: allow to react to fatal signals

Andrey Ryabinin aryabinin at virtuozzo.com
Thu Apr 16 13:35:57 MSK 2020


From: Peter Xu <peterx at redhat.com>

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 at redhat.com>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Tested-by: Brian Geffon <bgeffon at google.com>
Cc: Andrea Arcangeli <aarcange at redhat.com>
Cc: Bobby Powers <bobbypowers at gmail.com>
Cc: David Hildenbrand <david at redhat.com>
Cc: Denis Plotnikov <dplotnikov at virtuozzo.com>
Cc: "Dr . David Alan Gilbert" <dgilbert at redhat.com>
Cc: Hugh Dickins <hughd at google.com>
Cc: Jerome Glisse <jglisse at redhat.com>
Cc: Johannes Weiner <hannes at cmpxchg.org>
Cc: "Kirill A . Shutemov" <kirill at shutemov.name>
Cc: Martin Cracauer <cracauer at cons.org>
Cc: Marty McFadden <mcfadden8 at llnl.gov>
Cc: Matthew Wilcox <willy at infradead.org>
Cc: Maya Gokhale <gokhale2 at llnl.gov>
Cc: Mel Gorman <mgorman at suse.de>
Cc: Mike Kravetz <mike.kravetz at oracle.com>
Cc: Mike Rapoport <rppt at linux.vnet.ibm.com>
Cc: Pavel Emelyanov <xemul at openvz.org>
Link: http://lkml.kernel.org/r/20200220160256.9887-1-peterx@redhat.com
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>

https://jira.sw.ru/browse/PSBM-102938
(cherry picked from commit 71335f37c5e8ec9225285206f7f875057b9737ad)
Signed-off-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 mm/gup.c     | 12 +++++++++---
 mm/hugetlb.c |  3 ++-
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/mm/gup.c b/mm/gup.c
index cdf438ea8621..3d08b68c210f 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -507,7 +507,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
 	if (*flags & FOLL_REMOTE)
 		fault_flags |= FAULT_FLAG_REMOTE;
 	if (locked)
-		fault_flags |= FAULT_FLAG_ALLOW_RETRY;
+		fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 	if (*flags & FOLL_NOWAIT)
 		fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_RETRY_NOWAIT;
 	if (*flags & FOLL_TRIED) {
@@ -832,7 +832,7 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm,
 	int ret, major = 0;
 
 	if (unlocked)
-		fault_flags |= FAULT_FLAG_ALLOW_RETRY;
+		fault_flags |= FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
 
 retry:
 	vma = find_extend_vma(mm, address);
@@ -945,7 +945,13 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
 			break;
 
 		*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,
 				       pages, NULL, locked);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 417b96f4aa14..ec839cd22a3f 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -4223,7 +4223,8 @@ long follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
 			if (flags & FOLL_WRITE)
 				fault_flags |= FAULT_FLAG_WRITE;
 			if (locked)
-				fault_flags |= FAULT_FLAG_ALLOW_RETRY;
+				fault_flags |= FAULT_FLAG_ALLOW_RETRY |
+					FAULT_FLAG_KILLABLE;
 			if (flags & FOLL_NOWAIT)
 				fault_flags |= FAULT_FLAG_ALLOW_RETRY |
 					FAULT_FLAG_RETRY_NOWAIT;
-- 
2.25.3



More information about the Devel mailing list