From: Christoph Hellwig <hch@lst.de> To: Andrew Morton <akpm@linux-foundation.org> Cc: Juergen Gross <jgross@suse.com>, Stefano Stabellini <sstabellini@kernel.org>, linux-mm@kvack.org, Peter Zijlstra <peterz@infradead.org>, intel-gfx@lists.freedesktop.org, x86@kernel.org, linux-kernel@vger.kernel.org, Minchan Kim <minchan@kernel.org>, dri-devel@lists.freedesktop.org, xen-devel@lists.xenproject.org, Boris Ostrovsky <boris.ostrovsky@oracle.com>, Nitin Gupta <ngupta@vflare.org> Subject: [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map Date: Fri, 18 Sep 2020 18:37:22 +0200 Message-ID: <20200918163724.2511-5-hch@lst.de> (raw) In-Reply-To: <20200918163724.2511-1-hch@lst.de> i915_gem_object_map implements fairly low-level vmap functionality in a driver. Split it into two helpers, one for remapping kernel memory which can use vmap, and one for I/O memory that uses vmap_pfn. The only practical difference is that alloc_vm_area prefeaults the vmalloc area PTEs, which doesn't seem to be required here for the kernel memory case (and could be added to vmap using a flag if actually required). Signed-off-by: Christoph Hellwig <hch@lst.de> --- drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/gem/i915_gem_pages.c | 101 ++++++++++------------ 2 files changed, 47 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 9afa5c4a6bf006..1e1cb245fca778 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -25,6 +25,7 @@ config DRM_I915 select CRC32 select SND_HDA_I915 if SND_HDA_CORE select CEC_CORE if CEC_NOTIFIER + select VMAP_PFN help Choose this option if you have a system that has "Intel Graphics Media Accelerator" or "HD Graphics" integrated graphics, diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index e8a083743e0927..90029ea83aede9 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -234,50 +234,24 @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj) return err; } -static inline pte_t iomap_pte(resource_size_t base, - dma_addr_t offset, - pgprot_t prot) -{ - return pte_mkspecial(pfn_pte((base + offset) >> PAGE_SHIFT, prot)); -} - /* The 'mapping' part of i915_gem_object_pin_map() below */ -static void *i915_gem_object_map(struct drm_i915_gem_object *obj, +static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, enum i915_map_type type) { - unsigned long n_pte = obj->base.size >> PAGE_SHIFT; - struct sg_table *sgt = obj->mm.pages; - pte_t *stack[32], **mem; - struct vm_struct *area; + unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i; + struct page *stack[32], **pages = stack, *page; + struct sgt_iter iter; pgprot_t pgprot; - - if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC) - return NULL; - - /* A single page can always be kmapped */ - if (n_pte == 1 && type == I915_MAP_WB) - return kmap(sg_page(sgt->sgl)); - - mem = stack; - if (n_pte > ARRAY_SIZE(stack)) { - /* Too big for stack -- allocate temporary array instead */ - mem = kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL); - if (!mem) - return NULL; - } - - area = alloc_vm_area(obj->base.size, mem); - if (!area) { - if (mem != stack) - kvfree(mem); - return NULL; - } + void *vaddr; switch (type) { default: MISSING_CASE(type); fallthrough; /* to use PAGE_KERNEL anyway */ case I915_MAP_WB: + /* A single page can always be kmapped */ + if (n_pages == 1) + return kmap(sg_page(obj->mm.pages->sgl)); pgprot = PAGE_KERNEL; break; case I915_MAP_WC: @@ -285,30 +259,44 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj, break; } - if (i915_gem_object_has_struct_page(obj)) { - struct sgt_iter iter; - struct page *page; - pte_t **ptes = mem; - - for_each_sgt_page(page, iter, sgt) - **ptes++ = mk_pte(page, pgprot); - } else { - resource_size_t iomap; - struct sgt_iter iter; - pte_t **ptes = mem; - dma_addr_t addr; + if (n_pages > ARRAY_SIZE(stack)) { + /* Too big for stack -- allocate temporary array instead */ + pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL); + if (!pages) + return NULL; + } - iomap = obj->mm.region->iomap.base; - iomap -= obj->mm.region->region.start; + for_each_sgt_page(page, iter, obj->mm.pages) + pages[i++] = page; + vaddr = vmap(pages, n_pages, 0, pgprot); + if (pages != stack) + kvfree(pages); + return vaddr; +} - for_each_sgt_daddr(addr, iter, sgt) - **ptes++ = iomap_pte(iomap, addr, pgprot); +static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj) +{ + resource_size_t iomap = obj->mm.region->iomap.base - + obj->mm.region->region.start; + unsigned long n_pfn = obj->base.size >> PAGE_SHIFT; + unsigned long stack[32], *pfns = stack, i; + struct sgt_iter iter; + dma_addr_t addr; + void *vaddr; + + if (n_pfn > ARRAY_SIZE(stack)) { + /* Too big for stack -- allocate temporary array instead */ + pfns = kvmalloc_array(n_pfn, sizeof(*pfns), GFP_KERNEL); + if (!pfns) + return NULL; } - if (mem != stack) - kvfree(mem); - - return area->addr; + for_each_sgt_daddr(addr, iter, obj->mm.pages) + pfns[i++] = (iomap + addr) >> PAGE_SHIFT; + vaddr = vmap_pfn(pfns, n_pfn, pgprot_writecombine(PAGE_KERNEL_IO)); + if (pfns != stack) + kvfree(pfns); + return vaddr; } /* get, pin, and map the pages of the object into kernel space */ @@ -360,7 +348,10 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, } if (!ptr) { - ptr = i915_gem_object_map(obj, type); + if (i915_gem_object_has_struct_page(obj)) + ptr = i915_gem_object_map_page(obj, type); + else if (type == I915_MAP_WC) + ptr = i915_gem_object_map_pfn(obj); if (!ptr) { err = -ENOMEM; goto err_unpin; -- 2.28.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply index Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-09-18 16:37 [Intel-gfx] remove alloc_vm_area Christoph Hellwig 2020-09-18 16:37 ` [Intel-gfx] [PATCH 1/6] zsmalloc: switch from alloc_vm_area to get_vm_area Christoph Hellwig 2020-09-21 17:42 ` Minchan Kim 2020-09-21 18:17 ` Christoph Hellwig 2020-09-21 18:42 ` Minchan Kim 2020-09-21 18:43 ` Christoph Hellwig 2020-09-18 16:37 ` [Intel-gfx] [PATCH 2/6] mm: add a vmap_pfn function Christoph Hellwig 2020-09-18 16:37 ` [Intel-gfx] [PATCH 3/6] drm/i915: use vmap in shmem_pin_map Christoph Hellwig 2020-09-21 19:11 ` Matthew Wilcox 2020-09-22 6:22 ` Christoph Hellwig 2020-09-22 8:23 ` Tvrtko Ursulin 2020-09-22 14:31 ` Christoph Hellwig 2020-09-22 16:13 ` Tvrtko Ursulin 2020-09-22 16:33 ` Christoph Hellwig 2020-09-22 17:04 ` Tvrtko Ursulin 2020-09-23 6:11 ` Christoph Hellwig 2020-09-22 11:21 ` Matthew Wilcox 2020-09-22 14:39 ` Christoph Hellwig 2020-09-22 14:53 ` Matthew Wilcox 2020-09-18 16:37 ` Christoph Hellwig [this message] 2020-09-23 9:52 ` [Intel-gfx] [PATCH 4/6] drm/i915: use vmap in i915_gem_object_map Tvrtko Ursulin 2020-09-23 13:41 ` Christoph Hellwig 2020-09-23 13:58 ` Tvrtko Ursulin 2020-09-23 14:44 ` Christoph Hellwig 2020-09-24 12:22 ` Tvrtko Ursulin 2020-09-24 13:23 ` Christoph Hellwig 2020-09-18 16:37 ` [Intel-gfx] [PATCH 5/6] xen/xenbus: use apply_to_page_range directly in xenbus_map_ring_pv Christoph Hellwig 2020-09-18 16:37 ` [Intel-gfx] [PATCH 6/6] x86/xen: open code alloc_vm_area in arch_gnttab_valloc Christoph Hellwig 2020-09-21 20:44 ` boris.ostrovsky 2020-09-22 14:58 ` Christoph Hellwig 2020-09-22 15:24 ` boris.ostrovsky 2020-09-22 15:27 ` Christoph Hellwig 2020-09-22 15:34 ` boris.ostrovsky 2020-09-18 17:03 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area Patchwork 2020-09-21 17:50 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev2) Patchwork 2020-09-21 18:47 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev3) Patchwork 2020-09-22 14:44 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev4) Patchwork 2020-09-22 15:01 ` [Intel-gfx] ✗ Fi.CI.BUILD: failure for series starting with [1/6] zsmalloc: switch from alloc_vm_area to get_vm_area (rev5) Patchwork
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200918163724.2511-5-hch@lst.de \ --to=hch@lst.de \ --cc=akpm@linux-foundation.org \ --cc=boris.ostrovsky@oracle.com \ --cc=dri-devel@lists.freedesktop.org \ --cc=intel-gfx@lists.freedesktop.org \ --cc=jgross@suse.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=minchan@kernel.org \ --cc=ngupta@vflare.org \ --cc=peterz@infradead.org \ --cc=sstabellini@kernel.org \ --cc=x86@kernel.org \ --cc=xen-devel@lists.xenproject.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Intel-GFX Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/intel-gfx/0 intel-gfx/git/0.git git clone --mirror https://lore.kernel.org/intel-gfx/1 intel-gfx/git/1.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 intel-gfx intel-gfx/ https://lore.kernel.org/intel-gfx \ intel-gfx@lists.freedesktop.org public-inbox-index intel-gfx Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.freedesktop.lists.intel-gfx AGPL code for this site: git clone https://public-inbox.org/public-inbox.git