Message ID | 20221003172819.99245-1-matthew.auld@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v3] drm/i915/ttm: implement access_memory | expand |
Hi Matt, On Mon, Oct 03, 2022 at 06:28:19PM +0100, Matthew Auld wrote: > It looks like we need this for local-memory, if we want to use ptrace. > Something more is still needed if we want to handle non-mappable memory, > which looks quite annoying. > > v2: > - ttm_bo_kmap doesn't seem to work well here, and seems to expect > contiguous resource. > v3(Andi): > - s/PAGE_SIZE/bytes/ when passing in the size of the mapping. > > References: https://gitlab.freedesktop.org/drm/intel/-/issues/6989 > Signed-off-by: Matthew Auld <matthew.auld@intel.com> > Cc: Andrzej Hajda <andrzej.hajda@intel.com> > Cc: Nirmoy Das <nirmoy.das@intel.com> > Cc: Andi Shyti <andi.shyti@linux.intel.com> Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> Thanks, Andi > --- > drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 45 +++++++++++++++++++++++++ > 1 file changed, 45 insertions(+) > > diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c > index 3dc6acfcf4ec..d11cd9c57247 100644 > --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c > +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c > @@ -699,6 +699,50 @@ static unsigned long i915_ttm_io_mem_pfn(struct ttm_buffer_object *bo, > return ((base + sg_dma_address(sg)) >> PAGE_SHIFT) + ofs; > } > > +static int i915_ttm_access_memory(struct ttm_buffer_object *bo, > + unsigned long offset, void *buf, > + int len, int write) > +{ > + struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); > + resource_size_t iomap = obj->mm.region->iomap.base - > + obj->mm.region->region.start; > + unsigned long page = offset >> PAGE_SHIFT; > + unsigned long bytes_left = len; > + > + /* > + * TODO: For now just let it fail if the resource is non-mappable, > + * otherwise we need to perform the memcpy from the gpu here, without > + * interfering with the object (like moving the entire thing). > + */ > + if (!i915_ttm_resource_mappable(bo->resource)) > + return -EIO; > + > + offset -= page << PAGE_SHIFT; > + do { > + unsigned long bytes = min(bytes_left, PAGE_SIZE - offset); > + void __iomem *ptr; > + dma_addr_t daddr; > + > + daddr = i915_gem_object_get_dma_address(obj, page); > + ptr = ioremap_wc(iomap + daddr + offset, bytes); > + if (!ptr) > + return -EIO; > + > + if (write) > + memcpy_toio(ptr, buf, bytes); > + else > + memcpy_fromio(buf, ptr, bytes); > + iounmap(ptr); > + > + page++; > + buf += bytes; > + bytes_left -= bytes; > + offset = 0; > + } while (bytes_left); > + > + return len; > +} > + > /* > * All callbacks need to take care not to downcast a struct ttm_buffer_object > * without checking its subclass, since it might be a TTM ghost object. > @@ -715,6 +759,7 @@ static struct ttm_device_funcs i915_ttm_bo_driver = { > .delete_mem_notify = i915_ttm_delete_mem_notify, > .io_mem_reserve = i915_ttm_io_mem_reserve, > .io_mem_pfn = i915_ttm_io_mem_pfn, > + .access_memory = i915_ttm_access_memory, > }; > > /** > -- > 2.37.3
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index 3dc6acfcf4ec..d11cd9c57247 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -699,6 +699,50 @@ static unsigned long i915_ttm_io_mem_pfn(struct ttm_buffer_object *bo, return ((base + sg_dma_address(sg)) >> PAGE_SHIFT) + ofs; } +static int i915_ttm_access_memory(struct ttm_buffer_object *bo, + unsigned long offset, void *buf, + int len, int write) +{ + struct drm_i915_gem_object *obj = i915_ttm_to_gem(bo); + resource_size_t iomap = obj->mm.region->iomap.base - + obj->mm.region->region.start; + unsigned long page = offset >> PAGE_SHIFT; + unsigned long bytes_left = len; + + /* + * TODO: For now just let it fail if the resource is non-mappable, + * otherwise we need to perform the memcpy from the gpu here, without + * interfering with the object (like moving the entire thing). + */ + if (!i915_ttm_resource_mappable(bo->resource)) + return -EIO; + + offset -= page << PAGE_SHIFT; + do { + unsigned long bytes = min(bytes_left, PAGE_SIZE - offset); + void __iomem *ptr; + dma_addr_t daddr; + + daddr = i915_gem_object_get_dma_address(obj, page); + ptr = ioremap_wc(iomap + daddr + offset, bytes); + if (!ptr) + return -EIO; + + if (write) + memcpy_toio(ptr, buf, bytes); + else + memcpy_fromio(buf, ptr, bytes); + iounmap(ptr); + + page++; + buf += bytes; + bytes_left -= bytes; + offset = 0; + } while (bytes_left); + + return len; +} + /* * All callbacks need to take care not to downcast a struct ttm_buffer_object * without checking its subclass, since it might be a TTM ghost object. @@ -715,6 +759,7 @@ static struct ttm_device_funcs i915_ttm_bo_driver = { .delete_mem_notify = i915_ttm_delete_mem_notify, .io_mem_reserve = i915_ttm_io_mem_reserve, .io_mem_pfn = i915_ttm_io_mem_pfn, + .access_memory = i915_ttm_access_memory, }; /**
It looks like we need this for local-memory, if we want to use ptrace. Something more is still needed if we want to handle non-mappable memory, which looks quite annoying. v2: - ttm_bo_kmap doesn't seem to work well here, and seems to expect contiguous resource. v3(Andi): - s/PAGE_SIZE/bytes/ when passing in the size of the mapping. References: https://gitlab.freedesktop.org/drm/intel/-/issues/6989 Signed-off-by: Matthew Auld <matthew.auld@intel.com> Cc: Andrzej Hajda <andrzej.hajda@intel.com> Cc: Nirmoy Das <nirmoy.das@intel.com> Cc: Andi Shyti <andi.shyti@linux.intel.com> --- drivers/gpu/drm/i915/gem/i915_gem_ttm.c | 45 +++++++++++++++++++++++++ 1 file changed, 45 insertions(+)