On Fri, Sep 18, 2020 at 06:37:21PM +0200, Christoph Hellwig wrote: > void shmem_unpin_map(struct file *file, void *ptr) > { > + long i = shmem_npages(file); > + > mapping_clear_unevictable(file->f_mapping); > - __shmem_unpin_map(file, ptr, shmem_npte(file)); > + vunmap(ptr); > + > + for (i = 0; i < shmem_npages(file); i++) { > + struct page *page; > + > + page = shmem_read_mapping_page_gfp(file->f_mapping, i, > + GFP_KERNEL); > + if (!WARN_ON(IS_ERR(page))) { > + put_page(page); > + put_page(page); > + } > + } > } This is awkward. I'd like it if we had a vfree() variant which called put_page() instead of __free_pages(). I'd like it even more if we used release_pages() instead of our own loop that called put_page(). Perhaps something like this ... +++ b/mm/vmalloc.c @@ -2262,7 +2262,7 @@ static void __vunmap(const void *addr, int deallocate_page s) vm_remove_mappings(area, deallocate_pages); - if (deallocate_pages) { + if (deallocate_pages == 1) { int i; for (i = 0; i < area->nr_pages; i++) { @@ -2271,8 +2271,12 @@ static void __vunmap(const void *addr, int deallocate_pages) BUG_ON(!page); __free_pages(page, 0); } - atomic_long_sub(area->nr_pages, &nr_vmalloc_pages); + } else if (deallocate_pages == 2) { + release_pages(area->pages, area->nr_pages); + } + if (deallocate_pages) { + atomic_long_sub(area->nr_pages, &nr_vmalloc_pages); kvfree(area->pages); } @@ -2369,6 +2373,14 @@ void vunmap(const void *addr) } EXPORT_SYMBOL(vunmap); +void vunmap_put_pages(const void *addr) +{ + BUG_ON(in_interrupt()); + might_sleep(); + if (addr) + __vunmap(addr, 2); +} + /** * vmap - map an array of pages into virtually contiguous space * @pages: array of page pointers only with kernel-doc and so on. I bet somebody has a better idea for a name. _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel