*参照元 [#b7b19182] #backlinks *説明 [#v383ef80] -パス: 複数あり --CONFIG_MMU 有効: [[linux-4.4.1/mm/gup.c]] --CONFIG_MMU 無効: [[linux-4.4.1/mm/nommu.c]] --[[linux-4.4.1/CONFIG_MMU]] -FIXME: これは何? --説明 **引数 [#r394ee99] -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]] **返り値 [#w1dfec1a] -long -- **参考 [#w6c7c97a] *実装 [#u149b71e] **CONFIG_MMU 有効: mm/gup.c [#d354b391] /* * get_user_pages() - pin user pages in memory * @tsk: the task_struct to use for page fault accounting, or * NULL if faults are not to be recorded. * @mm: mm_struct of target mm * @start: starting user address * @nr_pages: number of pages from start to pin * @write: whether pages will be written to by the caller * @force: whether to force access even when user mapping is currently * protected (but never forces write access to shared mapping). * @pages: array that receives pointers to the pages pinned. * Should be at least nr_pages long. Or NULL, if caller * only intends to ensure the pages are faulted in. * @vmas: array of pointers to vmas corresponding to each page. * Or NULL if the caller does not require them. * * Returns number of pages pinned. This may be fewer than the number * requested. If nr_pages is 0 or negative, returns 0. If no pages * were pinned, returns -errno. Each page returned must be released * with a put_page() call when it is finished with. vmas will only * remain valid while mmap_sem is held. * * Must be called with mmap_sem held for read or write. * * get_user_pages walks a process's page tables and takes a reference to * each struct page that each user address corresponds to at a given * instant. That is, it takes the page that would be accessed if a user * thread accesses the given user virtual address at that instant. * * This does not guarantee that the page exists in the user mappings when * get_user_pages returns, and there may even be a completely different * page there in some cases (eg. if mmapped pagecache has been invalidated * and subsequently re faulted). However it does guarantee that the page * won't be freed completely. And mostly callers simply care that the page * contains data that was valid *at some point in time*. Typically, an IO * or similar operation cannot guarantee anything stronger anyway because * locks can't be held over the syscall boundary. * * If write=0, the page must not be written to. If the page is written to, * set_page_dirty (or set_page_dirty_lock, as appropriate) must be called * after the page is finished with, and before put_page is called. * * get_user_pages is typically used for fewer-copy IO operations, to get a * handle on the memory by some means other than accesses via the user virtual * addresses. The pages may be submitted for DMA to devices or accessed via * their kernel linear mapping (via the kmap APIs). Care should be taken to * use the correct cache flushing APIs. * * See also get_user_pages_fast, for performance critical applications. * * get_user_pages should be phased out in favor of * get_user_pages_locked|unlocked or get_user_pages_fast. Nothing * should use get_user_pages because it cannot pass * FAULT_FLAG_ALLOW_RETRY to handle_mm_fault. */ long get_user_pages(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) { return __get_user_pages_locked(tsk, mm, start, nr_pages, write, force, pages, vmas, NULL, false, FOLL_TOUCH); - --[[linux-4.4.1/__get_user_pages_locked()]] } EXPORT_SYMBOL(get_user_pages); - --[[linux-4.4.1/EXPORT_SYMBOL()]] **CONFIG_MMU 無効: mm/nommu.c [#s1404945] /* * get a list of pages in an address range belonging to the specified process * and indicate the VMA that covers each page * - this is potentially dodgy as we may end incrementing the page count of a * slab page or a secondary page from a compound page * - don't permit access to VMAs that don't support it, such as I/O mappings */ long get_user_pages(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 flags = 0; if (write) flags |= FOLL_WRITE; if (force) flags |= FOLL_FORCE; return __get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas, NULL); - --[[linux-4.4.1/__get_user_pages()]] } EXPORT_SYMBOL(get_user_pages); - --[[linux-4.4.1/EXPORT_SYMBOL()]] *コメント [#y8f2e01d]