All of lore.kernel.org
 help / color / mirror / Atom feed
From: Matthew Auld <matthew.william.auld@gmail.com>
To: Christoph Hellwig <hch@lst.de>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Juergen Gross <jgross@suse.com>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Matthew Wilcox <willy@infradead.org>,
	ML dri-devel <dri-devel@lists.freedesktop.org>,
	linux-mm@kvack.org, Peter Zijlstra <peterz@infradead.org>,
	kernel list <linux-kernel@vger.kernel.org>,
	Intel Graphics Development <intel-gfx@lists.freedesktop.org>,
	x86@kernel.org, Chris Wilson <chris@chris-wilson.co.uk>,
	Minchan Kim <minchan@kernel.org>,
	Matthew Auld <matthew.auld@intel.com>,
	xen-devel@lists.xenproject.org,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Nitin Gupta <ngupta@vflare.org>
Subject: Re: [Intel-gfx] [PATCH 08/11] drm/i915: use vmap in i915_gem_object_map
Date: Fri, 25 Sep 2020 15:08:59 +0100	[thread overview]
Message-ID: <CAM0jSHPaqpX2A5T4iybfLF+F=cBX05GW8u54cUe7AG0QKDJt2g@mail.gmail.com> (raw)
In-Reply-To: <20200924135853.875294-9-hch@lst.de>

On Thu, 24 Sep 2020 at 14:59, Christoph Hellwig <hch@lst.de> wrote:
>
> 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 | 126 ++++++++++------------
>  2 files changed, 59 insertions(+), 68 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 6550c0bc824ea2..b519417667eb4b 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -232,34 +232,21 @@ 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,
> -                                enum i915_map_type type)
> +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;
> +       void *vaddr;
>
> -       if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
> -               return NULL;
> -
> -       if (GEM_WARN_ON(type == I915_MAP_WC &&
> -                       !static_cpu_has(X86_FEATURE_PAT)))
> -               return NULL;
> -
> -       /* A single page can always be kmapped */
> -       if (n_pte == 1 && type == I915_MAP_WB) {
> -               struct page *page = sg_page(sgt->sgl);
> -
> +       switch (type) {
> +       default:
> +               MISSING_CASE(type);
> +               fallthrough;    /* to use PAGE_KERNEL anyway */
> +       case I915_MAP_WB:
>                 /*
>                  * On 32b, highmem using a finite set of indirect PTE (i.e.
>                  * vmap) to provide virtual mappings of the high pages.
> @@ -277,30 +264,8 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
>                  * So if the page is beyond the 32b boundary, make an explicit
>                  * vmap.
>                  */
> -               if (!PageHighMem(page))
> -                       return page_address(page);
> -       }
> -
> -       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;
> -       }
> -
> -       switch (type) {
> -       default:
> -               MISSING_CASE(type);
> -               fallthrough;    /* to use PAGE_KERNEL anyway */
> -       case I915_MAP_WB:
> +               if (n_pages == 1 && !PageHighMem(sg_page(obj->mm.pages->sgl)))
> +                       return page_address(sg_page(obj->mm.pages->sgl));
>                 pgprot = PAGE_KERNEL;
>                 break;
>         case I915_MAP_WC:
> @@ -308,30 +273,49 @@ 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;
> +       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;
> +       }
>
> -               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;
> +       i = 0;
> +       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;
> +}
>
> -               iomap = obj->mm.region->iomap.base;
> -               iomap -= obj->mm.region->region.start;
> +static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj,
> +               enum i915_map_type type)
> +{
> +       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 (type != I915_MAP_WC)
> +               return NULL;
>
> -               for_each_sgt_daddr(addr, iter, sgt)
> -                       **ptes++ = iomap_pte(iomap, addr, pgprot);
> +       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;

Missing the i = 0 fix from Dan?

> +       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 */
> @@ -383,7 +367,13 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
>         }
>
>         if (!ptr) {
> -               ptr = i915_gem_object_map(obj, type);
> +               if (GEM_WARN_ON(type == I915_MAP_WC &&
> +                               !static_cpu_has(X86_FEATURE_PAT)))
> +                       ptr = NULL;
> +               else if (i915_gem_object_has_struct_page(obj))
> +                       ptr = i915_gem_object_map_page(obj, type);
> +               else
> +                       ptr = i915_gem_object_map_pfn(obj, type);
>                 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

WARNING: multiple messages have this Message-ID (diff)
From: Matthew Auld <matthew.william.auld@gmail.com>
To: Christoph Hellwig <hch@lst.de>
Cc: Juergen Gross <jgross@suse.com>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Minchan Kim <minchan@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Intel Graphics Development <intel-gfx@lists.freedesktop.org>,
	x86@kernel.org, kernel list <linux-kernel@vger.kernel.org>,
	ML dri-devel <dri-devel@lists.freedesktop.org>,
	Chris Wilson <chris@chris-wilson.co.uk>,
	linux-mm@kvack.org, Matthew Wilcox <willy@infradead.org>,
	xen-devel@lists.xenproject.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Nitin Gupta <ngupta@vflare.org>,
	Matthew Auld <matthew.auld@intel.com>
Subject: Re: [Intel-gfx] [PATCH 08/11] drm/i915: use vmap in i915_gem_object_map
Date: Fri, 25 Sep 2020 15:08:59 +0100	[thread overview]
Message-ID: <CAM0jSHPaqpX2A5T4iybfLF+F=cBX05GW8u54cUe7AG0QKDJt2g@mail.gmail.com> (raw)
In-Reply-To: <20200924135853.875294-9-hch@lst.de>

On Thu, 24 Sep 2020 at 14:59, Christoph Hellwig <hch@lst.de> wrote:
>
> 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 | 126 ++++++++++------------
>  2 files changed, 59 insertions(+), 68 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 6550c0bc824ea2..b519417667eb4b 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -232,34 +232,21 @@ 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,
> -                                enum i915_map_type type)
> +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;
> +       void *vaddr;
>
> -       if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
> -               return NULL;
> -
> -       if (GEM_WARN_ON(type == I915_MAP_WC &&
> -                       !static_cpu_has(X86_FEATURE_PAT)))
> -               return NULL;
> -
> -       /* A single page can always be kmapped */
> -       if (n_pte == 1 && type == I915_MAP_WB) {
> -               struct page *page = sg_page(sgt->sgl);
> -
> +       switch (type) {
> +       default:
> +               MISSING_CASE(type);
> +               fallthrough;    /* to use PAGE_KERNEL anyway */
> +       case I915_MAP_WB:
>                 /*
>                  * On 32b, highmem using a finite set of indirect PTE (i.e.
>                  * vmap) to provide virtual mappings of the high pages.
> @@ -277,30 +264,8 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
>                  * So if the page is beyond the 32b boundary, make an explicit
>                  * vmap.
>                  */
> -               if (!PageHighMem(page))
> -                       return page_address(page);
> -       }
> -
> -       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;
> -       }
> -
> -       switch (type) {
> -       default:
> -               MISSING_CASE(type);
> -               fallthrough;    /* to use PAGE_KERNEL anyway */
> -       case I915_MAP_WB:
> +               if (n_pages == 1 && !PageHighMem(sg_page(obj->mm.pages->sgl)))
> +                       return page_address(sg_page(obj->mm.pages->sgl));
>                 pgprot = PAGE_KERNEL;
>                 break;
>         case I915_MAP_WC:
> @@ -308,30 +273,49 @@ 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;
> +       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;
> +       }
>
> -               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;
> +       i = 0;
> +       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;
> +}
>
> -               iomap = obj->mm.region->iomap.base;
> -               iomap -= obj->mm.region->region.start;
> +static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj,
> +               enum i915_map_type type)
> +{
> +       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 (type != I915_MAP_WC)
> +               return NULL;
>
> -               for_each_sgt_daddr(addr, iter, sgt)
> -                       **ptes++ = iomap_pte(iomap, addr, pgprot);
> +       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;

Missing the i = 0 fix from Dan?

> +       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 */
> @@ -383,7 +367,13 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
>         }
>
>         if (!ptr) {
> -               ptr = i915_gem_object_map(obj, type);
> +               if (GEM_WARN_ON(type == I915_MAP_WC &&
> +                               !static_cpu_has(X86_FEATURE_PAT)))
> +                       ptr = NULL;
> +               else if (i915_gem_object_has_struct_page(obj))
> +                       ptr = i915_gem_object_map_page(obj, type);
> +               else
> +                       ptr = i915_gem_object_map_pfn(obj, type);
>                 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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: Matthew Auld <matthew.william.auld@gmail.com>
To: Christoph Hellwig <hch@lst.de>
Cc: Juergen Gross <jgross@suse.com>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Minchan Kim <minchan@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Intel Graphics Development <intel-gfx@lists.freedesktop.org>,
	x86@kernel.org, kernel list <linux-kernel@vger.kernel.org>,
	ML dri-devel <dri-devel@lists.freedesktop.org>,
	Chris Wilson <chris@chris-wilson.co.uk>,
	linux-mm@kvack.org, Matthew Wilcox <willy@infradead.org>,
	xen-devel@lists.xenproject.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Boris Ostrovsky <boris.ostrovsky@oracle.com>,
	Nitin Gupta <ngupta@vflare.org>,
	Matthew Auld <matthew.auld@intel.com>
Subject: Re: [Intel-gfx] [PATCH 08/11] drm/i915: use vmap in i915_gem_object_map
Date: Fri, 25 Sep 2020 15:08:59 +0100	[thread overview]
Message-ID: <CAM0jSHPaqpX2A5T4iybfLF+F=cBX05GW8u54cUe7AG0QKDJt2g@mail.gmail.com> (raw)
In-Reply-To: <20200924135853.875294-9-hch@lst.de>

On Thu, 24 Sep 2020 at 14:59, Christoph Hellwig <hch@lst.de> wrote:
>
> 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 | 126 ++++++++++------------
>  2 files changed, 59 insertions(+), 68 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 6550c0bc824ea2..b519417667eb4b 100644
> --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c
> @@ -232,34 +232,21 @@ 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,
> -                                enum i915_map_type type)
> +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;
> +       void *vaddr;
>
> -       if (!i915_gem_object_has_struct_page(obj) && type != I915_MAP_WC)
> -               return NULL;
> -
> -       if (GEM_WARN_ON(type == I915_MAP_WC &&
> -                       !static_cpu_has(X86_FEATURE_PAT)))
> -               return NULL;
> -
> -       /* A single page can always be kmapped */
> -       if (n_pte == 1 && type == I915_MAP_WB) {
> -               struct page *page = sg_page(sgt->sgl);
> -
> +       switch (type) {
> +       default:
> +               MISSING_CASE(type);
> +               fallthrough;    /* to use PAGE_KERNEL anyway */
> +       case I915_MAP_WB:
>                 /*
>                  * On 32b, highmem using a finite set of indirect PTE (i.e.
>                  * vmap) to provide virtual mappings of the high pages.
> @@ -277,30 +264,8 @@ static void *i915_gem_object_map(struct drm_i915_gem_object *obj,
>                  * So if the page is beyond the 32b boundary, make an explicit
>                  * vmap.
>                  */
> -               if (!PageHighMem(page))
> -                       return page_address(page);
> -       }
> -
> -       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;
> -       }
> -
> -       switch (type) {
> -       default:
> -               MISSING_CASE(type);
> -               fallthrough;    /* to use PAGE_KERNEL anyway */
> -       case I915_MAP_WB:
> +               if (n_pages == 1 && !PageHighMem(sg_page(obj->mm.pages->sgl)))
> +                       return page_address(sg_page(obj->mm.pages->sgl));
>                 pgprot = PAGE_KERNEL;
>                 break;
>         case I915_MAP_WC:
> @@ -308,30 +273,49 @@ 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;
> +       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;
> +       }
>
> -               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;
> +       i = 0;
> +       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;
> +}
>
> -               iomap = obj->mm.region->iomap.base;
> -               iomap -= obj->mm.region->region.start;
> +static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj,
> +               enum i915_map_type type)
> +{
> +       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 (type != I915_MAP_WC)
> +               return NULL;
>
> -               for_each_sgt_daddr(addr, iter, sgt)
> -                       **ptes++ = iomap_pte(iomap, addr, pgprot);
> +       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;

Missing the i = 0 fix from Dan?

> +       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 */
> @@ -383,7 +367,13 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj,
>         }
>
>         if (!ptr) {
> -               ptr = i915_gem_object_map(obj, type);
> +               if (GEM_WARN_ON(type == I915_MAP_WC &&
> +                               !static_cpu_has(X86_FEATURE_PAT)))
> +                       ptr = NULL;
> +               else if (i915_gem_object_has_struct_page(obj))
> +                       ptr = i915_gem_object_map_page(obj, type);
> +               else
> +                       ptr = i915_gem_object_map_pfn(obj, type);
>                 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
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2020-09-25 14:09 UTC|newest]

Thread overview: 73+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-24 13:58 remove alloc_vm_area v2 Christoph Hellwig
2020-09-24 13:58 ` [Intel-gfx] " Christoph Hellwig
2020-09-24 13:58 ` [PATCH 01/11] mm: update the documentation for vfree Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-24 13:58 ` [PATCH 02/11] mm: add a VM_MAP_PUT_PAGES flag for vmap Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-24 13:58 ` [PATCH 03/11] mm: add a vmap_pfn function Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-24 13:58 ` [PATCH 04/11] mm: allow a NULL fn callback in apply_to_page_range Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-24 13:58 ` [PATCH 05/11] zsmalloc: switch from alloc_vm_area to get_vm_area Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-24 13:58 ` [PATCH 06/11] drm/i915: use vmap in shmem_pin_map Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-25 13:05   ` Tvrtko Ursulin
2020-09-25 13:05     ` [Intel-gfx] " Tvrtko Ursulin
2020-09-25 13:05     ` Tvrtko Ursulin
2020-09-24 13:58 ` [PATCH 07/11] drm/i915: stop using kmap in i915_gem_object_map Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-25 13:01   ` Tvrtko Ursulin
2020-09-25 13:01     ` [Intel-gfx] " Tvrtko Ursulin
2020-09-25 13:01     ` Tvrtko Ursulin
2020-09-24 13:58 ` [PATCH 08/11] drm/i915: use vmap " Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-25 13:11   ` Tvrtko Ursulin
2020-09-25 13:11     ` [Intel-gfx] " Tvrtko Ursulin
2020-09-25 13:11     ` Tvrtko Ursulin
2020-09-25 14:08   ` Matthew Auld [this message]
2020-09-25 14:08     ` [Intel-gfx] " Matthew Auld
2020-09-25 14:08     ` Matthew Auld
2020-09-25 14:08     ` Matthew Auld
2020-09-25 14:08     ` Matthew Auld
2020-09-25 16:02     ` Christoph Hellwig
2020-09-25 16:02       ` Christoph Hellwig
2020-09-25 16:09   ` [PATCH 08/11, fixed] " Christoph Hellwig
2020-09-25 16:09     ` [Intel-gfx] " Christoph Hellwig
2020-09-24 13:58 ` [PATCH 09/11] xen/xenbus: use apply_to_page_range directly in xenbus_map_ring_pv Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-24 23:42   ` boris.ostrovsky
2020-09-24 23:42     ` [Intel-gfx] " boris.ostrovsky
2020-09-24 23:42     ` boris.ostrovsky
2020-09-24 13:58 ` [PATCH 10/11] x86/xen: open code alloc_vm_area in arch_gnttab_valloc Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-24 23:43   ` boris.ostrovsky
2020-09-24 23:43     ` [Intel-gfx] " boris.ostrovsky
2020-09-24 23:43     ` boris.ostrovsky
2020-09-24 13:58 ` [PATCH 11/11] mm: remove alloc_vm_area Christoph Hellwig
2020-09-24 13:58   ` [Intel-gfx] " Christoph Hellwig
2020-09-24 15:09 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for series starting with [01/11] mm: update the documentation for vfree Patchwork
2020-09-24 15:34 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-09-24 20:44 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
2020-09-25 16:50 ` [Intel-gfx] ✓ Fi.CI.BAT: success for series starting with [01/11] mm: update the documentation for vfree (rev2) Patchwork
2020-09-26  0:08 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
2020-09-26  2:43 ` remove alloc_vm_area v2 Andrew Morton
2020-09-26  2:43   ` [Intel-gfx] " Andrew Morton
2020-09-26  2:43   ` Andrew Morton
2020-09-26  6:29   ` Christoph Hellwig
2020-09-26  6:29     ` [Intel-gfx] " Christoph Hellwig
2020-09-28 10:13     ` Joonas Lahtinen
2020-09-28 10:13       ` [Intel-gfx] " Joonas Lahtinen
2020-09-28 10:13       ` Joonas Lahtinen
2020-09-28 12:37       ` Christoph Hellwig
2020-09-28 12:37         ` [Intel-gfx] " Christoph Hellwig
2020-09-29 12:43         ` Joonas Lahtinen
2020-09-29 12:43           ` [Intel-gfx] " Joonas Lahtinen
2020-09-29 12:43           ` Joonas Lahtinen
2020-09-30 14:48           ` Christoph Hellwig
2020-09-30 14:48             ` [Intel-gfx] " Christoph Hellwig
2020-09-30 18:37             ` Daniel Vetter
2020-09-30 18:37               ` [Intel-gfx] " Daniel Vetter
2020-09-30 18:37               ` Daniel Vetter
2020-09-30 18:37               ` Daniel Vetter
2020-10-02 12:21 remove alloc_vm_area v4 Christoph Hellwig
2020-10-02 12:22 ` [Intel-gfx] [PATCH 08/11] drm/i915: use vmap in i915_gem_object_map Christoph Hellwig

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='CAM0jSHPaqpX2A5T4iybfLF+F=cBX05GW8u54cUe7AG0QKDJt2g@mail.gmail.com' \
    --to=matthew.william.auld@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=boris.ostrovsky@oracle.com \
    --cc=chris@chris-wilson.co.uk \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hch@lst.de \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=jgross@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=matthew.auld@intel.com \
    --cc=minchan@kernel.org \
    --cc=ngupta@vflare.org \
    --cc=peterz@infradead.org \
    --cc=sstabellini@kernel.org \
    --cc=willy@infradead.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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.