From ce409a24385a7ef8ecb5d1dc58c7795da117ecb6 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Fri, 22 Oct 2021 07:34:17 +0200 Subject: [PATCH] libdrm/iris: map PPGTT buffers lazy + lseek * let iris handle buffer management, this implies that BOs are mapped to the PPGTT during buffer execution and unmapped by iris later, for this to work buffers need to be unmapped when allocating cached BOs (vma_free) which requires a patch * support lseek (drm_lseek for now) for determining object size issue #4380 --- repos/libports/ports/mesa.hash | 2 +- repos/libports/ports/mesa.port | 2 + repos/libports/src/lib/libdrm/ioctl_iris.cc | 61 +++++++++++++++---- .../lib/mesa/patches/iris_bufmgr_unmap.patch | 21 +++++++ .../libports/src/lib/mesa/patches/lseek.patch | 13 ++++ 5 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 repos/libports/src/lib/mesa/patches/iris_bufmgr_unmap.patch create mode 100644 repos/libports/src/lib/mesa/patches/lseek.patch diff --git a/repos/libports/ports/mesa.hash b/repos/libports/ports/mesa.hash index a9fd1ba455..a5059b9a9f 100644 --- a/repos/libports/ports/mesa.hash +++ b/repos/libports/ports/mesa.hash @@ -1 +1 @@ -c964a648360166b72246613a7be71bbfa6475d88 +ad8293ad3be9e4d0158ae5fbabb9fde180cea1ac diff --git a/repos/libports/ports/mesa.port b/repos/libports/ports/mesa.port index 1e9010cc01..63de2f8adb 100644 --- a/repos/libports/ports/mesa.port +++ b/repos/libports/ports/mesa.port @@ -17,8 +17,10 @@ PATCHES := src/lib/mesa/patches/bitset_redefined.patch \ src/lib/mesa/patches/etnaviv.patch \ src/lib/mesa/patches/iris.patch \ src/lib/mesa/patches/iris_bufmgr_tmp.patch \ + src/lib/mesa/patches/iris_bufmgr_unmap.patch \ src/lib/mesa/patches/iris_binder.patch \ src/lib/mesa/patches/iris_disable_compute.patch \ + src/lib/mesa/patches/lseek.patch \ src/lib/mesa/patches/mesa.patch \ src/lib/mesa/patches/os_mmap.patch \ src/lib/mesa/patches/softpipe_cache.patch diff --git a/repos/libports/src/lib/libdrm/ioctl_iris.cc b/repos/libports/src/lib/libdrm/ioctl_iris.cc index bcd1c69476..9d6c173101 100644 --- a/repos/libports/src/lib/libdrm/ioctl_iris.cc +++ b/repos/libports/src/lib/libdrm/ioctl_iris.cc @@ -28,6 +28,7 @@ extern "C" { #include #include #include +#include #define DRM_NUMBER(req) ((req) & 0xff) } @@ -251,7 +252,7 @@ class Drm_call Genode::Env &_env; Genode::Heap _heap { _env.ram(), _env.rm() }; - Gpu::Connection _gpu_session { _env }; + Gpu::Connection _gpu_session { _env, 3*1024*1024 }; Gpu::Info_intel const &_gpu_info { *_gpu_session.attached_info() }; size_t _available_gtt_size { _gpu_info.aperture_size }; @@ -1032,9 +1033,6 @@ class Drm_call Genode::warning("handle: ", obj[i].handle, " reused but is busy"); if (b.gpu_vaddr_valid && b.gpu_vaddr.addr != obj[i].offset) { - Genode::error("unmap already mapped ", b.id().value, " ", - Genode::Hex(b.gpu_vaddr.addr), "->", - Genode::Hex(obj[i].offset)); _unmap_buffer_ppgtt(b); } @@ -1320,12 +1318,15 @@ class Drm_call Gpu::Buffer_id const id { .value = p->handle }; try { - _buffer_space.apply(id, [&](Buffer const &b) { + _buffer_space.apply(id, [&](Buffer const &) { + if (!prime_handle.value) prime_handle = id; - if (prime_handle.value != id.value) - Genode::error("prime handle changed - ignored ", b.id().value); + if (prime_handle.value != id.value) { + Genode::warning("prime handle changed: ", id.value); + prime_handle = id; + } }); } catch (Genode::Id_space::Unknown_id) { return -1; @@ -1375,6 +1376,19 @@ class Drm_call _gpu_session.completion_sigh(_completion_sigh); } + int lseek(int fd, off_t offset, int whence) + { + if (fd != prime_fd || offset || whence != SEEK_END) + return -1; + + int size = -1; + _buffer_space.apply(prime_handle, [&](Buffer const &b) { + size =(int)b.size; + }); + + return size; + } + bool map_buffer_ggtt(Offset offset, size_t length) { bool result = false; @@ -1451,6 +1465,19 @@ class Drm_call } } + void unmap_buffer_ppgtt(__u32 handle) + { + Gpu::Buffer_id const id = { .value = handle }; + try { + _buffer_space.apply(id, [&](Buffer &b) { + if (b.busy) + return; + + _unmap_buffer_ppgtt(b); + }); + } catch (Genode::Id_space::Unknown_id) { } + } + int ioctl(unsigned long request, void *arg) { bool const device = device_ioctl(request); @@ -1473,12 +1500,6 @@ class Drm_call if (!h.busy) return; if (h.seqno.value > _gpu_info.last_completed.value) return; h.busy = false; - - /* - * Because bo object map/unmap is not supported correctly right now - * (reference counting), we unmap and map the buffers on for each frame - */ - _unmap_buffer_ppgtt(h); }); } @@ -1518,6 +1539,20 @@ extern "C" int drm_munmap(void *addr, size_t length) } +extern "C" void drm_unmap_ppgtt(__u32 handle) +{ + _call->unmap_buffer_ppgtt(handle); +} + + +extern "C" int drm_lseek(int fd, off_t offset, int whence) +{ + if (_call.constructed() == false) { errno = EIO; return -1; } + + return _call->lseek(fd, offset, whence); +} + + extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg) { if (verbose_ioctl) { dump_ioctl(request); } diff --git a/repos/libports/src/lib/mesa/patches/iris_bufmgr_unmap.patch b/repos/libports/src/lib/mesa/patches/iris_bufmgr_unmap.patch new file mode 100644 index 0000000000..aafdbc17a5 --- /dev/null +++ b/repos/libports/src/lib/mesa/patches/iris_bufmgr_unmap.patch @@ -0,0 +1,21 @@ +--- a/src/lib/mesa/src/gallium/drivers/iris/iris_bufmgr.c ++++ b/src/lib/mesa/src/gallium/drivers/iris/iris_bufmgr.c +@@ -101,6 +101,8 @@ + + #define FILE_DEBUG_FLAG DEBUG_BUFMGR + ++void drm_unmap_ppgtt(__u32 handle); ++ + static inline int + atomic_add_unless(int *v, int add, int unless) + { +@@ -439,6 +441,9 @@ + */ + if (memzone != iris_memzone_for_address(bo->gtt_offset) || + bo->gtt_offset % alignment != 0) { ++ ++ ++ drm_unmap_ppgtt(bo->gem_handle); + vma_free(bufmgr, bo->gtt_offset, bo->size); + bo->gtt_offset = 0ull; + } diff --git a/repos/libports/src/lib/mesa/patches/lseek.patch b/repos/libports/src/lib/mesa/patches/lseek.patch new file mode 100644 index 0000000000..f365b841ed --- /dev/null +++ b/repos/libports/src/lib/mesa/patches/lseek.patch @@ -0,0 +1,13 @@ +diff --git a/src/lib/mesa/src/gallium/drivers/iris/iris_bufmgr.c b/src/lib/mesa/src/gallium/drivers/iris/iris_bufmgr.c +index 2549729..c0045eb 100644 +--- a/src/lib/mesa/src/gallium/drivers/iris/iris_bufmgr.c ++++ b/src/lib/mesa/src/gallium/drivers/iris/iris_bufmgr.c +@@ -1417,7 +1417,7 @@ iris_bo_import_dmabuf(struct iris_bufmgr *bufmgr, int prime_fd, + * later, we can lseek on the prime fd to get the size. Older + * kernels will just fail, in which case we fall back to the + * provided (estimated or guess size). */ +- ret = lseek(prime_fd, 0, SEEK_END); ++ ret = drm_lseek(prime_fd, 0, SEEK_END); + if (ret != -1) + bo->size = ret; +