@@ -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 */
886886static 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}
22322234EXPORT_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}
22702274EXPORT_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}
31673174EXPORT_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}
31953204EXPORT_SYMBOL (pin_user_pages );
31963205
0 commit comments