Skip to content

Commit 9a863a6

Browse files
jgunthorpeakpm00
authored andcommitted
mm/gup: make locked never NULL in the internal GUP functions
Now that NULL locked doesn't have a special meaning we can just make it non-NULL in all cases and remove the special tests. get_user_pages() and pin_user_pages() can safely pass in a locked = 1 get_user_pages_remote) and pin_user_pages_remote() can swap in a local variable for locked if NULL is passed. Remove all the NULL checks. Link: https://lkml.kernel.org/r/9-v2-987e91b59705+36b-gup_tidy_jgg@nvidia.com Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Acked-by: Mike Rapoport (IBM) <rppt@kernel.org> Reviewed-by: John Hubbard <jhubbard@nvidia.com> Cc: Alistair Popple <apopple@nvidia.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Claudio Imbrenda <imbrenda@linux.ibm.com> Cc: David Hildenbrand <david@redhat.com> Cc: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent f04740f commit 9a863a6

File tree

1 file changed

+30
-21
lines changed

1 file changed

+30
-21
lines changed

mm/gup.c

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -879,9 +879,9 @@ static int get_gate_page(struct mm_struct *mm, unsigned long address,
879879
}
880880

881881
/*
882-
* mmap_lock must be held on entry. If @locked != NULL and *@flags
883-
* does not include FOLL_NOWAIT, the mmap_lock may be released. If it
884-
* is, *@locked will be set to 0 and -EBUSY returned.
882+
* mmap_lock must be held on entry. If @flags has FOLL_UNLOCKABLE but not
883+
* FOLL_NOWAIT, the mmap_lock may be released. If it is, *@locked will be set
884+
* to 0 and -EBUSY returned.
885885
*/
886886
static int faultin_page(struct vm_area_struct *vma,
887887
unsigned long address, unsigned int *flags, bool unshare,
@@ -930,8 +930,8 @@ static int faultin_page(struct vm_area_struct *vma,
930930
* mmap lock in the page fault handler. Sanity check this.
931931
*/
932932
WARN_ON_ONCE(fault_flags & FAULT_FLAG_RETRY_NOWAIT);
933-
if (locked)
934-
*locked = 0;
933+
*locked = 0;
934+
935935
/*
936936
* We should do the same as VM_FAULT_RETRY, but let's not
937937
* return -EBUSY since that's not reflecting the reality of
@@ -951,7 +951,7 @@ static int faultin_page(struct vm_area_struct *vma,
951951
}
952952

953953
if (ret & VM_FAULT_RETRY) {
954-
if (locked && !(fault_flags & FAULT_FLAG_RETRY_NOWAIT))
954+
if (!(fault_flags & FAULT_FLAG_RETRY_NOWAIT))
955955
*locked = 0;
956956
return -EBUSY;
957957
}
@@ -1062,14 +1062,12 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags)
10621062
* appropriate) must be called after the page is finished with, and
10631063
* before put_page is called.
10641064
*
1065-
* If @locked != NULL, *@locked will be set to 0 when mmap_lock is
1066-
* released by an up_read(). That can happen if @gup_flags does not
1067-
* have FOLL_NOWAIT.
1065+
* If FOLL_UNLOCKABLE is set without FOLL_NOWAIT then the mmap_lock may
1066+
* be released. If this happens *@locked will be set to 0 on return.
10681067
*
1069-
* A caller using such a combination of @locked and @gup_flags
1070-
* must therefore hold the mmap_lock for reading only, and recognize
1071-
* when it's been released. Otherwise, it must be held for either
1072-
* reading or writing and will not be released.
1068+
* A caller using such a combination of @gup_flags must therefore hold the
1069+
* mmap_lock for reading only, and recognize when it's been released. Otherwise,
1070+
* it must be held for either reading or writing and will not be released.
10731071
*
10741072
* In most cases, get_user_pages or get_user_pages_fast should be used
10751073
* instead of __get_user_pages. __get_user_pages should be used only if
@@ -1121,7 +1119,7 @@ static long __get_user_pages(struct mm_struct *mm,
11211119
i = follow_hugetlb_page(mm, vma, pages, vmas,
11221120
&start, &nr_pages, i,
11231121
gup_flags, locked);
1124-
if (locked && *locked == 0) {
1122+
if (!*locked) {
11251123
/*
11261124
* We've got a VM_FAULT_RETRY
11271125
* and we've lost mmap_lock.
@@ -1354,7 +1352,7 @@ static __always_inline long __get_user_pages_locked(struct mm_struct *mm,
13541352
* The internal caller expects GUP to manage the lock internally and the
13551353
* lock must be released when this returns.
13561354
*/
1357-
if (locked && !*locked) {
1355+
if (!*locked) {
13581356
if (mmap_read_lock_killable(mm))
13591357
return -EAGAIN;
13601358
must_unlock = true;
@@ -1502,6 +1500,7 @@ long populate_vma_page_range(struct vm_area_struct *vma,
15021500
{
15031501
struct mm_struct *mm = vma->vm_mm;
15041502
unsigned long nr_pages = (end - start) / PAGE_SIZE;
1503+
int local_locked = 1;
15051504
int gup_flags;
15061505
long ret;
15071506

@@ -1542,7 +1541,7 @@ long populate_vma_page_range(struct vm_area_struct *vma,
15421541
* not result in a stack expansion that recurses back here.
15431542
*/
15441543
ret = __get_user_pages(mm, start, nr_pages, gup_flags,
1545-
NULL, NULL, locked);
1544+
NULL, NULL, locked ? locked : &local_locked);
15461545
lru_add_drain();
15471546
return ret;
15481547
}
@@ -1683,7 +1682,7 @@ static long __get_user_pages_locked(struct mm_struct *mm, unsigned long start,
16831682
* The internal caller expects GUP to manage the lock internally and the
16841683
* lock must be released when this returns.
16851684
*/
1686-
if (locked && !*locked) {
1685+
if (!*locked) {
16871686
if (mmap_read_lock_killable(mm))
16881687
return -EAGAIN;
16891688
must_unlock = true;
@@ -2222,11 +2221,14 @@ long get_user_pages_remote(struct mm_struct *mm,
22222221
unsigned int gup_flags, struct page **pages,
22232222
struct vm_area_struct **vmas, int *locked)
22242223
{
2224+
int local_locked = 1;
2225+
22252226
if (!is_valid_gup_args(pages, vmas, locked, &gup_flags,
22262227
FOLL_TOUCH | FOLL_REMOTE))
22272228
return -EINVAL;
22282229

2229-
return __get_user_pages_locked(mm, start, nr_pages, pages, vmas, locked,
2230+
return __get_user_pages_locked(mm, start, nr_pages, pages, vmas,
2231+
locked ? locked : &local_locked,
22302232
gup_flags);
22312233
}
22322234
EXPORT_SYMBOL(get_user_pages_remote);
@@ -2261,11 +2263,13 @@ long get_user_pages(unsigned long start, unsigned long nr_pages,
22612263
unsigned int gup_flags, struct page **pages,
22622264
struct vm_area_struct **vmas)
22632265
{
2266+
int locked = 1;
2267+
22642268
if (!is_valid_gup_args(pages, vmas, NULL, &gup_flags, FOLL_TOUCH))
22652269
return -EINVAL;
22662270

22672271
return __get_user_pages_locked(current->mm, start, nr_pages, pages,
2268-
vmas, NULL, gup_flags);
2272+
vmas, &locked, gup_flags);
22692273
}
22702274
EXPORT_SYMBOL(get_user_pages);
22712275

@@ -3158,10 +3162,13 @@ long pin_user_pages_remote(struct mm_struct *mm,
31583162
unsigned int gup_flags, struct page **pages,
31593163
struct vm_area_struct **vmas, int *locked)
31603164
{
3165+
int local_locked = 1;
3166+
31613167
if (!is_valid_gup_args(pages, vmas, locked, &gup_flags,
31623168
FOLL_PIN | FOLL_TOUCH | FOLL_REMOTE))
31633169
return 0;
3164-
return __gup_longterm_locked(mm, start, nr_pages, pages, vmas, locked,
3170+
return __gup_longterm_locked(mm, start, nr_pages, pages, vmas,
3171+
locked ? locked : &local_locked,
31653172
gup_flags);
31663173
}
31673174
EXPORT_SYMBOL(pin_user_pages_remote);
@@ -3187,10 +3194,12 @@ long pin_user_pages(unsigned long start, unsigned long nr_pages,
31873194
unsigned int gup_flags, struct page **pages,
31883195
struct vm_area_struct **vmas)
31893196
{
3197+
int locked = 1;
3198+
31903199
if (!is_valid_gup_args(pages, vmas, NULL, &gup_flags, FOLL_PIN))
31913200
return 0;
31923201
return __gup_longterm_locked(current->mm, start, nr_pages,
3193-
pages, vmas, NULL, gup_flags);
3202+
pages, vmas, &locked, gup_flags);
31943203
}
31953204
EXPORT_SYMBOL(pin_user_pages);
31963205

0 commit comments

Comments
 (0)