*参照元 [#wb018f17]
#backlinks

*説明 [#xaccec38]
-パス: [[linux-4.4.1/mm/gup.c]]

-FIXME: これは何?
--説明


**引数 [#d03de652]
-struct task_struct *tsk
--
--[[linux-4.4.1/task_struct]]
-struct mm_struct *mm
--
--[[linux-4.4.1/mm_struct]]
-unsigned long start
--
-unsigned long nr_pages
--
-int write
--
-int force
--
-struct page **pages
--
--[[linux-4.4.1/page]]
-struct vm_area_struct **vmas
--
--[[linux-4.4.1/vm_area_struct]]
-int *locked
--
-bool notify_drop
--
-unsigned int flags
--


**返り値 [#w61274fb]
-long
--


**参考 [#lca7624d]


*実装 [#s46ea28d]
 static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
                                                 struct mm_struct *mm,
                                                 unsigned long start,
                                                 unsigned long nr_pages,
                                                 int write, int force,
                                                 struct page **pages,
                                                 struct vm_area_struct **vmas,
                                                 int *locked, bool notify_drop,
                                                 unsigned int flags)
 {
         long ret, pages_done;
         bool lock_dropped;
 
         if (locked) {
                 /* if VM_FAULT_RETRY can be returned, vmas become invalid */
                 BUG_ON(vmas);
                 /* check caller initialized locked */
                 BUG_ON(*locked != 1);
         }
 
-
--[[linux-4.4.1/BUG_ON()]]

         if (pages)
                 flags |= FOLL_GET;
         if (write)
                 flags |= FOLL_WRITE;
         if (force)
                 flags |= FOLL_FORCE;
 
         pages_done = 0;
         lock_dropped = false;
         for (;;) {
                 ret = __get_user_pages(tsk, mm, start, nr_pages, flags, pages,
                                        vmas, locked);
                 if (!locked)
                         /* VM_FAULT_RETRY couldn't trigger, bypass */
                         return ret;
 
-
--[[linux-4.4.1/__get_user_pages()]]

                 /* VM_FAULT_RETRY cannot return errors */
                 if (!*locked) {
                         BUG_ON(ret < 0);
                         BUG_ON(ret >= nr_pages);
                 }
 
                 if (!pages)
                         /* If it's a prefault don't insist harder */
                         return ret;
 
                 if (ret > 0) {
                         nr_pages -= ret;
                         pages_done += ret;
                         if (!nr_pages)
                                 break;
                 }
                 if (*locked) {
                         /* VM_FAULT_RETRY didn't trigger */
                         if (!pages_done)
                                 pages_done = ret;
                         break;
                 }
                 /* VM_FAULT_RETRY triggered, so seek to the faulting offset */
                 pages += ret;
                 start += ret << PAGE_SHIFT;
 
                 /*
                  * Repeat on the address that fired VM_FAULT_RETRY
                  * without FAULT_FLAG_ALLOW_RETRY but with
                  * FAULT_FLAG_TRIED.
                  */
                 *locked = 1;
                 lock_dropped = true;
                 down_read(&mm->mmap_sem);
                 ret = __get_user_pages(tsk, mm, start, 1, flags | FOLL_TRIED,
                                        pages, NULL, NULL);
                 if (ret != 1) {
                         BUG_ON(ret > 1);
                         if (!pages_done)
                                 pages_done = ret;
                         break;
                 }
-
--[[linux-4.4.1/down_read()]]
--[[linux-4.4.1/__get_user_pages()]]

                 nr_pages--;
                 pages_done++;
                 if (!nr_pages)
                         break;
                 pages++;
                 start += PAGE_SIZE;
         }
         if (notify_drop && lock_dropped && *locked) {
                 /*
                  * We must let the caller know we temporarily dropped the lock
                  * and so the critical section protected by it was lost.
                  */
                 up_read(&mm->mmap_sem);
                 *locked = 0;
         }
         return pages_done;
-
--[[linux-4.4.1/up_read()]]

 }


*コメント [#kf891f5a]


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS