[Intel-gfx] [RFC PATCH v2 1/1] drm/i915: Replace shmem memory region and object backend with TTM
Ruhl, Michael J
michael.j.ruhl at intel.com
Wed Jun 1 19:43:15 UTC 2022
>-----Original Message-----
>From: Adrian Larumbe <adrian.larumbe at collabora.com>
>Sent: Friday, May 27, 2022 12:08 PM
>To: Ruhl, Michael J <michael.j.ruhl at intel.com>
>Cc: daniel at ffwll.ch; intel-gfx at lists.freedesktop.org
>Subject: Re: [Intel-gfx] [RFC PATCH v2 1/1] drm/i915: Replace shmem memory
>region and object backend with TTM
>
>On 17.05.2022 21:39, Ruhl, Michael J wrote:
>> >-----Original Message-----
>> >From: Intel-gfx <intel-gfx-bounces at lists.freedesktop.org> On Behalf Of
>> >Adrian Larumbe
>> >Sent: Tuesday, May 17, 2022 4:45 PM
>> >To: daniel at ffwll.ch; intel-gfx at lists.freedesktop.org
>> >Cc: adrian.larumbe at collabora.com
>> >Subject: [Intel-gfx] [RFC PATCH v2 1/1] drm/i915: Replace shmem memory
>> >region and object backend with TTM
>> >
>> >Remove shmem region and object backend code as they are now
>> >unnecessary.
>> >In the case of objects placed in SMEM and backed by kernel shmem files,
>the
>> >file pointer has to be retrieved from the ttm_tt structure, so change this
>> >as well. This means accessing an shmem-backed BO's file pointer requires
>> >getting its pages beforehand, unlike in the old shmem backend.
>> >
>> >Expand TTM BO creation by handling devices with no LLC so that their
>> >caching and coherency properties are set accordingly.
>> >
>> >Adapt phys backend to put pages of original shmem object in a 'TTM way',
>> >also making sure its pages are put when a TTM shmem object has no struct
>> >page.
>> >
>> >Signed-off-by: Adrian Larumbe <adrian.larumbe at collabora.com>
>> >---
>> > drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c | 12 +-
>> > drivers/gpu/drm/i915/gem/i915_gem_mman.c | 32 +-
>> > drivers/gpu/drm/i915/gem/i915_gem_object.h | 4 +-
>> > drivers/gpu/drm/i915/gem/i915_gem_phys.c | 32 +-
>> > drivers/gpu/drm/i915/gem/i915_gem_shmem.c | 390 +------------------
>> > drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 267 ++++++++++++-
>> > drivers/gpu/drm/i915/gem/i915_gem_ttm.h | 3 +
>> > drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c | 9 +-
>> > drivers/gpu/drm/i915/gt/shmem_utils.c | 64 ++-
>> > drivers/gpu/drm/i915/intel_memory_region.c | 7 +-
>> > 10 files changed, 398 insertions(+), 422 deletions(-)
>> >
>> >diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> >b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> >index f5062d0c6333..de04ce4210b3 100644
>> >--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> >+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
>> >@@ -12,6 +12,7 @@
>> > #include <asm/smp.h>
>> >
>> > #include "gem/i915_gem_dmabuf.h"
>> >+#include "gem/i915_gem_ttm.h"
>> > #include "i915_drv.h"
>> > #include "i915_gem_object.h"
>> > #include "i915_scatterlist.h"
>> >@@ -94,22 +95,25 @@ static int i915_gem_dmabuf_mmap(struct dma_buf
>> >*dma_buf, struct vm_area_struct *
>> > {
>> > struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
>> > struct drm_i915_private *i915 = to_i915(obj->base.dev);
>> >+ struct file *filp = i915_gem_ttm_get_filep(obj);
>> > int ret;
>> >
>> >+ GEM_BUG_ON(obj->base.import_attach != NULL);
>> >+
>> > if (obj->base.size < vma->vm_end - vma->vm_start)
>> > return -EINVAL;
>> >
>> > if (HAS_LMEM(i915))
>> > return drm_gem_prime_mmap(&obj->base, vma);
>>
>> Since all of the devices that will have device memory will be true for
>HAS_LMEM,
>> won't your code path always go to drm_gem_prime_mmap()?
>
>This makes me wonder, how was mapping of a dmabuf BO working before, in
>the case
>of DG2 and DG1, when an object is smem-bound, and therefore backed by
>shmem?
LMEM is a new thing. DG2 and DG1 have it available, but the initial patch
sets did not support access via dma-buf.
With the TTM being used for the LMEM objects, I think that the drm_gem code
was able to be used.
>
>I guess in this case it might be more sensible to control for the case that it's
>an lmem-only object on a discrete platform as follows:
>
>static int i915_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct
>vm_area_struct *vma)
>{
> struct drm_i915_gem_object *obj = dma_buf_to_obj(dma_buf);
> struct drm_i915_private *i915 = to_i915(obj->base.dev);
> struct ttm_buffer_object *bo = i915_gem_to_ttm(obj);
> struct file *filp = i915_gem_ttm_get_filep(obj);
> int ret;
>
> if (obj->base.size < vma->vm_end - vma->vm_start)
> return -EINVAL;
>
> if (IS_DGFX(i915) && i915_ttm_cpu_maps_iomem(bo->resource))
> return drm_gem_prime_mmap(&obj->base, vma);
HAS_LMEM is roughly IS_DGFX...
As for the second part, (_maps_iomem), hmm...
If I am following this correctly drm_gem_prime_mmap() will call i915_gem_mmap,
so I think that just the call (without the iomem check) is correct.
This is a newer mmap code path than the older integrated cards had, so I think that
the context is HAS_LMEM (new and discrete), otherwise the old path.
> if (IS_ERR(filp))
> return PTR_ERR(filp);
>
> ret = call_mmap(filp, vma);
> if (ret)
> return ret;
>
> vma_set_file(vma, filp);
>
> return 0;
>}
>
>> >- if (!obj->base.filp)
>> >+ if (!filp)
>> > return -ENODEV;
>> >
>> >- ret = call_mmap(obj->base.filp, vma);
>> >+ ret = call_mmap(filp, vma);
>> > if (ret)
>> > return ret;
>> >
>> >- vma_set_file(vma, obj->base.filp);
>> >+ vma_set_file(vma, filp);
>> >
>> > return 0;
>> > }
>> >@@ -224,6 +228,8 @@ struct dma_buf *i915_gem_prime_export(struct
>> >drm_gem_object *gem_obj, int flags)
>> > exp_info.priv = gem_obj;
>> > exp_info.resv = obj->base.resv;
>> >
>> >+ GEM_BUG_ON(obj->base.import_attach != NULL);
>> >+
>> > if (obj->ops->dmabuf_export) {
>> > int ret = obj->ops->dmabuf_export(obj);
>> > if (ret)
>> >diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
>> >b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
>> >index 0c5c43852e24..d963cf35fdc9 100644
>> >--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c
>> >+++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c
>> >@@ -64,7 +64,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void
>> >*data,
>> > struct drm_i915_private *i915 = to_i915(dev);
>> > struct drm_i915_gem_mmap *args = data;
>> > struct drm_i915_gem_object *obj;
>> >+ struct file *filp;
>> > unsigned long addr;
>> >+ int ret;
>> >
>> > /*
>> > * mmap ioctl is disallowed for all discrete platforms,
>> >@@ -83,12 +85,20 @@ i915_gem_mmap_ioctl(struct drm_device *dev,
>void
>> >*data,
>> > if (!obj)
>> > return -ENOENT;
>> >
>> >- /* prime objects have no backing filp to GEM mmap
>> >- * pages from.
>> >- */
>> >- if (!obj->base.filp) {
>> >- addr = -ENXIO;
>> >- goto err;
>> >+ if (obj->base.import_attach)
>> >+ filp = obj->base.filp;
>>
>> Why is this now ok? This is the imported object. And it used to give an error.
>>
>> If you are importing from a different device, (i.e. an amd device is exporting
>> the object, and you are i915 here), can you even do this?
>>
>> My understanding was that mmaping was only for the exported object.
>>
>> Has this changed?
>
>You're right here, I completely misunderstood how this function is meant to
>deal
>with imported objects. This arose as a consequence of the file pointer being
>moved into the ttm_tt structure from the base DRM object.
Hmm, one other thing that I am seeing here for i915_gem_mmap_ioctl:
/*
* mmap ioctl is disallowed for all discrete platforms,
* and for all platforms with GRAPHICS_VER > 12.
*/
if (IS_DGFX(i915) || GRAPHICS_VER_FULL(i915) > IP_VER(12, 0))
return -EOPNOTSUPP;
You need to use the i915_gem_mmap_offset_ioctl() to do mmap with the discrete
(i.e. devices with LMEM).
So are we looking at the right code path?
>The way I now check for the case that it's an imported object and therefore
>this
>function should throw back an error is as follows:
>
>/* prime objects have no backing filp to GEM mmap
> * pages from.
> */
>if (obj->base.import_attach) {
> GEM_WARN_ON(obj->base.filp != NULL);
> addr = -ENXIO;
> goto err;
>}
>
>I believe the import_attach member has to be set for all imported
>members. However, this just made me think, what would happen in the case
>we want
>to mat a BO that we have exported for another driver to use? The
>import_attach
>field would be set so my code would return with an error, even though we
>should
>be in full control of mmaping it.
I am not following your comment.
import_attach is the BO pointer to the dmabuf attachment.
If I export a BO, I cannot set this pointer on the BO because it is for the
import side only.
>Maybe by allowing the function to go forward in case the base GEM object's
>dma-buf
>operations are the same as our driver's:
>
>i915_gem_dmabuf.c:
>
>const struct dma_buf_ops *i915_get_dmabuf_ops(void) {
> return &i915_dmabuf_ops;
>}
These will only get set on the exported BO.
>i915_gem_mman.c:
>
>/* prime objects have no backing filp to GEM mmap
> * pages from.
> */
>if (obj->base.import_attach &&
> obj->base.dma_buf->ops != i915_get_dmabuf_ops()) {
> GEM_WARN_ON(obj->base.filp != NULL);
> addr = -ENXIO;
> goto err;
>}
So you would never have import_attach and i915_dmabuf_ops.
Can you restate what you are trying to solve here? Maybe that
will make things more clear?
Thanks,
M
>> Thanks,
>>
>> Mike
>
>Cheers,
>Adrian
More information about the Intel-gfx
mailing list