On Fri, Mar 08, 2019 at 02:31:58PM +0000, Bernard Metzler wrote: > >> + for (i = 0; num_pages; i++) { > >> + int got, nents = min_t(int, num_pages, PAGES_PER_CHUNK); > >> + > >> + umem->page_chunk[i].p = kcalloc(nents, sizeof(struct page *), > >> + GFP_KERNEL); > >> + if (!umem->page_chunk[i].p) { > >> + rv = -ENOMEM; > >> + goto out; > >> + } > >> + got = 0; > >> + while (nents) { > >> + struct page **plist = &umem->page_chunk[i].p[got]; > >> + > >> + rv = get_user_pages(first_page_va, nents, FOLL_WRITE, > >> + plist, NULL); > >> + if (rv < 0) > >> + goto out; > >> + > >> + umem->num_pages += rv; > >> + atomic64_add(rv, ¤t->mm->pinned_vm); > >> + first_page_va += rv * PAGE_SIZE; > >> + nents -= rv; > >> + got += rv; > >> + } > >> + num_pages -= got; > >> + } > > > >Actually why isn't this just using umem_get? > > > I found it not really optimized for a fast lookup of a page from a > vaddr. I had all that umem in before, and it was a mess if one > wants to start sending/receiving from/to an address or resume to > do so w/o searching through the sg lists again. > I am not sure it is as efficient in rxe (didn't check). > siw_get_upage() is rather simple in the end and does what I need. You are still better to use umem_get and then transform the sgl into something you want. I don't like seeing drivers mess with mm's and things like this, they usually get it wrong. Jason