[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200921191157.GX32101@casper.infradead.org>
Date: Mon, 21 Sep 2020 20:11:57 +0100
From: Matthew Wilcox <willy@...radead.org>
To: Christoph Hellwig <hch@....de>
Cc: Andrew Morton <akpm@...ux-foundation.org>,
Peter Zijlstra <peterz@...radead.org>,
Boris Ostrovsky <boris.ostrovsky@...cle.com>,
Juergen Gross <jgross@...e.com>,
Stefano Stabellini <sstabellini@...nel.org>,
Jani Nikula <jani.nikula@...ux.intel.com>,
Joonas Lahtinen <joonas.lahtinen@...ux.intel.com>,
Rodrigo Vivi <rodrigo.vivi@...el.com>,
Minchan Kim <minchan@...nel.org>,
Nitin Gupta <ngupta@...are.org>, x86@...nel.org,
xen-devel@...ts.xenproject.org, linux-kernel@...r.kernel.org,
intel-gfx@...ts.freedesktop.org, dri-devel@...ts.freedesktop.org,
linux-mm@...ck.org
Subject: Re: [PATCH 3/6] drm/i915: use vmap in shmem_pin_map
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.
Powered by blists - more mailing lists