From 567b9dfa39edba602e85e60ce269be5438b39f86 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Thu, 14 Oct 2021 09:03:48 +0200 Subject: [PATCH] libdrm/iris: use VFS/GPU plugin Synchronize GPU completion by calling 'read' of the vfs_gpu plugin. This enables pthreads to wait for GPU completions instead of the main EP. issue #4380 --- repos/libports/lib/mk/spec/x86_64/libdrm.mk | 2 + .../libports/recipes/pkg/mesa_gears/archives | 1 + repos/libports/recipes/pkg/mesa_gears/runtime | 5 +- repos/libports/src/lib/libdrm/ioctl_iris.cc | 110 ++++++++++++------ 4 files changed, 80 insertions(+), 38 deletions(-) diff --git a/repos/libports/lib/mk/spec/x86_64/libdrm.mk b/repos/libports/lib/mk/spec/x86_64/libdrm.mk index faf41dc769..818348a86a 100644 --- a/repos/libports/lib/mk/spec/x86_64/libdrm.mk +++ b/repos/libports/lib/mk/spec/x86_64/libdrm.mk @@ -3,3 +3,5 @@ include $(REP_DIR)/lib/mk/libdrm.inc include $(call select_from_repositories,lib/import/import-libdrm.mk) SRC_CC := ioctl_iris.cc + +CC_CXX_WARN_STRICT = diff --git a/repos/libports/recipes/pkg/mesa_gears/archives b/repos/libports/recipes/pkg/mesa_gears/archives index 3e304e9517..4a1286cc01 100644 --- a/repos/libports/recipes/pkg/mesa_gears/archives +++ b/repos/libports/recipes/pkg/mesa_gears/archives @@ -4,6 +4,7 @@ _/src/init _/src/libdrm _/src/libc _/src/vfs +_/src/vfs_gpu _/src/expat _/src/zlib _/src/stdcxx diff --git a/repos/libports/recipes/pkg/mesa_gears/runtime b/repos/libports/recipes/pkg/mesa_gears/runtime index 5fe92550d1..9b67e8db31 100644 --- a/repos/libports/recipes/pkg/mesa_gears/runtime +++ b/repos/libports/recipes/pkg/mesa_gears/runtime @@ -8,7 +8,7 @@ - + @@ -20,6 +20,7 @@ + @@ -27,7 +28,7 @@ - 2000-01-01 00:00 + 2000-01-01 00:00 diff --git a/repos/libports/src/lib/libdrm/ioctl_iris.cc b/repos/libports/src/lib/libdrm/ioctl_iris.cc index 9d6c173101..eabe8e669d 100644 --- a/repos/libports/src/lib/libdrm/ioctl_iris.cc +++ b/repos/libports/src/lib/libdrm/ioctl_iris.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -28,11 +29,17 @@ extern "C" { #include #include #include -#include #define DRM_NUMBER(req) ((req) & 0xff) } +namespace Libc { +#include +#include +#include +#include +} + using Genode::addr_t; using Genode::Attached_dataspace; using Genode::Constructible; @@ -251,11 +258,13 @@ class Drm_call using Ram_quota = Genode::Ram_quota; Genode::Env &_env; - Genode::Heap _heap { _env.ram(), _env.rm() }; - Gpu::Connection _gpu_session { _env, 3*1024*1024 }; + Genode::Heap &_heap; + Gpu::Connection &_gpu_session; + Gpu::Info_intel const &_gpu_info { *_gpu_session.attached_info() }; size_t _available_gtt_size { _gpu_info.aperture_size }; + int _wait_fd { 0 }; using Buffer = Gpu::Buffer; using Buffer_space = Genode::Id_space; @@ -669,16 +678,6 @@ class Drm_call } } - /*************************** - ** execbuffer completion ** - ***************************/ - - void _handle_completion() { } - - Genode::Io_signal_handler _completion_sigh { - _env.ep(), *this, &Drm_call::_handle_completion }; - - /************ ** ioctls ** ************/ @@ -884,6 +883,14 @@ class Drm_call return 0; } + + int _device_gem_context_destroy(void *arg) + { + unsigned id = reinterpret_cast(arg)->ctx_id; + return 0; + } + + int _device_gem_context_set_param(void *arg) { auto * const p = reinterpret_cast(arg); @@ -1166,26 +1173,23 @@ class Drm_call } switch (cmd) { - case DRM_I915_GEM_GET_APERTURE: return _device_gem_get_aperture_size(arg); - case DRM_I915_GETPARAM: return _device_getparam(arg); - case DRM_I915_GEM_CREATE: return _device_gem_create(arg); - case DRM_I915_GEM_MMAP: return _device_gem_mmap(arg); - case DRM_I915_GEM_MMAP_GTT: return _device_gem_mmap_gtt(arg); - case DRM_I915_GEM_SET_DOMAIN: return _device_gem_set_domain(arg); - case DRM_I915_GEM_CONTEXT_CREATE: return _device_gem_context_create(arg); - case DRM_I915_GEM_SET_TILING: return _device_gem_set_tiling(arg); - case DRM_I915_GEM_SW_FINISH: return _device_gem_sw_finish(arg); - case DRM_I915_GEM_EXECBUFFER2: return _device_gem_execbuffer2(arg); - case DRM_I915_GEM_BUSY: return _device_gem_busy(arg); - case DRM_I915_GEM_MADVISE: return _device_gem_madvise(arg); - case DRM_I915_GEM_WAIT: return 0; - case DRM_I915_QUERY: return _device_query(arg); + case DRM_I915_GEM_GET_APERTURE: return _device_gem_get_aperture_size(arg); + case DRM_I915_GETPARAM: return _device_getparam(arg); + case DRM_I915_GEM_CREATE: return _device_gem_create(arg); + case DRM_I915_GEM_MMAP: return _device_gem_mmap(arg); + case DRM_I915_GEM_MMAP_GTT: return _device_gem_mmap_gtt(arg); + case DRM_I915_GEM_SET_DOMAIN: return _device_gem_set_domain(arg); + case DRM_I915_GEM_CONTEXT_CREATE: return _device_gem_context_create(arg); + case DRM_I915_GEM_CONTEXT_DESTROY: return _device_gem_context_destroy(arg); + case DRM_I915_GEM_SET_TILING: return _device_gem_set_tiling(arg); + case DRM_I915_GEM_SW_FINISH: return _device_gem_sw_finish(arg); + case DRM_I915_GEM_EXECBUFFER2: return _device_gem_execbuffer2(arg); + case DRM_I915_GEM_BUSY: return _device_gem_busy(arg); + case DRM_I915_GEM_MADVISE: return _device_gem_madvise(arg); + case DRM_I915_GEM_WAIT: return 0; + case DRM_I915_QUERY: return _device_query(arg); case DRM_I915_GEM_CONTEXT_SETPARAM: return _device_gem_context_set_param(arg); case DRM_I915_GEM_CONTEXT_GETPARAM: return _device_gem_context_get_param(arg); - case DRM_I915_GEM_CONTEXT_DESTROY: - if(verbose_ioctl) - Genode::warning("DRM_IOCTL_I915_GEM_CONTEXT_DESTROY not supported"); - return 0; default: if (verbose_ioctl) Genode::error("Unhandled device specific ioctl:", Genode::Hex(cmd)); @@ -1365,15 +1369,20 @@ class Drm_call public: - Drm_call(Genode::Env &env) - : _env(env) + Drm_call(Genode::Env &env, Genode::Heap &heap, Gpu::Connection &gpu_session) + : _env(env), _heap(heap), _gpu_session(gpu_session) { /* make handle id 0 unavailable, handled as invalid by iris */ drm_syncobj_create reserve_id_0 { }; if (_generic_syncobj_create(&reserve_id_0)) Genode::warning("syncobject 0 not reserved"); - _gpu_session.completion_sigh(_completion_sigh); + _wait_fd = Libc::open("/dev/gpu", 0); + if (_wait_fd < 0) { + Genode::error("Failed to open '/dev/gpu': ", + "try configure '' in 'dev' directory of VFS'"); + throw -1; + } } int lseek(int fd, off_t offset, int whence) @@ -1491,7 +1500,10 @@ class Drm_call if (_gpu_session.complete(seqno)) { break; } - _env.ep().wait_and_dispatch_one_io_signal(); + + /* wait for completion signal in VFS plugin */ + char buf; + Libc::read(_wait_fd, &buf, 1); } /* mark done buffer objects */ @@ -1511,7 +1523,27 @@ static Genode::Constructible _call; void drm_init(Genode::Env &env) { - _call.construct(env); + using namespace Genode; + + /* + * XXX: lookup Gpu::Connection via 'Gpu::Connection &vfs_gpu_connection()' in + * vfs_gpu.lib.so' VFS plugin + */ + static Heap heap { env.ram(), env.rm() }; + try { + Shared_object object { env, heap, "vfs_gpu.lib.so", + Shared_object::BIND_LAZY, + Shared_object::DONT_KEEP }; + + void *vfs_gpu_connection = object.lookup("_Z18vfs_gpu_connectionv"); + + log("libdrm (iris): 'vfs_gpu_connection' found at: ", vfs_gpu_connection); + Gpu::Connection &gpu_session = ((Gpu::Connection & (*)())vfs_gpu_connection)(); + + _call.construct(env, heap, gpu_session); + } catch (Shared_object::Invalid_rom_module) { + Genode::error("'vfs_gpu.lib.so' plugin not found"); + } catch (...) { } } @@ -1524,6 +1556,8 @@ extern "C" void *drm_mmap(void * /* vaddr */, size_t length, int /* prot */, int /* flags */, int /* fd */, off_t offset) { + if (_call.constructed() == false) { errno = EIO; return nullptr; } + /* sanity check if we got a GTT mapped offset */ bool const ok = _call->map_buffer_ggtt(offset, length); return ok ? (void *)offset : nullptr; @@ -1534,6 +1568,8 @@ extern "C" void *drm_mmap(void * /* vaddr */, size_t length, */ extern "C" int drm_munmap(void *addr, size_t length) { + if (_call.constructed() == false) { errno = EIO; return -1; } + _call->unmap_buffer(addr, length); return 0; } @@ -1555,7 +1591,9 @@ extern "C" int drm_lseek(int fd, off_t offset, int whence) extern "C" int genode_ioctl(int /* fd */, unsigned long request, void *arg) { + if (_call.constructed() == false) { errno = EIO; return -1; } if (verbose_ioctl) { dump_ioctl(request); } + int const ret = _call->ioctl(request, arg); if (verbose_ioctl) { Genode::log("returned ", ret); } return ret;