On Sun, Oct 02, 2022 at 01:46:41AM +0100, Al Viro wrote: > On Sat, Oct 01, 2022 at 05:23:25PM -0700, ira.weiny@xxxxxxxxx wrote: > > > kiov = kcalloc(page_count, sizeof(*kiov), GFP_KERNEL); > > @@ -38,12 +39,12 @@ static int shm_get_kernel_pages(unsigned long start, size_t page_count, > > for (n = 0; n < page_count; n++) { > > kiov[n].iov_base = (void *)(start + n * PAGE_SIZE); > > kiov[n].iov_len = PAGE_SIZE; > > + pages[n] = virt_to_page(kiov[n].iov_base); > > + get_page(pages[n]); > > } > > - > > - rc = get_kernel_pages(kiov, page_count, 0, pages); > > kfree(kiov); > > IDGI. The only thing in kiov[...] you are every reading is > ->iov_base. And you fetch it once, right after the assignment. :-( Good point. Thanks for catching that. I was too focused on just replacing get_kernel_pages() with get_page() and I should have refactored more. > > Why bother with allocating the array at all? > pages[n] = virt_to_page((void *)start + n * PAGE_SIZE); > would do just as well, not to mention the fact that since you reject > vmalloc and kmap, you might simply do > > page = virt_to_page(start); > for (int n = 0; n < page_count; n++) > get_page(pages[n] = page + n); I think I'd avoid the assignment in the parameter as I would miss that if I came back and looked at this code later. I'll get rid of the kiov in v2. Sorry for not cleaning it up more and thanks for the review! Ira