From 015985016c39c8e5917b4c677929d55effbc747b Mon Sep 17 00:00:00 2001 From: erikwijmans Date: Mon, 4 Jan 2021 20:57:01 -0500 Subject: [PATCH] Add a nv-egl-crashy-query-device-attrib workaround. --- src/Magnum/GL/Implementation/driverSpecific.cpp | 8 ++++++++ src/Magnum/Platform/WindowlessEglApplication.cpp | 14 +++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Magnum/GL/Implementation/driverSpecific.cpp b/src/Magnum/GL/Implementation/driverSpecific.cpp index d5cda6adf..2d44cdcc4 100644 --- a/src/Magnum/GL/Implementation/driverSpecific.cpp +++ b/src/Magnum/GL/Implementation/driverSpecific.cpp @@ -161,6 +161,14 @@ const char* KnownWorkarounds[]{ possible to get driver version through EGL, so enabling this unconditionally on all EGL NV contexts. */ "nv-egl-incorrect-gl11-function-pointers", + +/* On NV driver 450.80.02, eglQueryDeviceAttribEXT() segfaults when querying + GPUs that the user does not have access to (i.e. via cgroup). Instead, + always call eglQueryDeviceStringEXT() as that doesn't segfault and sets an + error that can be retrieved via eglGetError() to see if the user has access + to that device. On well-behaved driver versions, eglQueryDeviceAttribEXT() + returns false instead of segfaulting. */ +"nv-egl-crashy-query-device-attrib", #endif #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/Platform/WindowlessEglApplication.cpp b/src/Magnum/Platform/WindowlessEglApplication.cpp index 85e718864..9cb464956 100644 --- a/src/Magnum/Platform/WindowlessEglApplication.cpp +++ b/src/Magnum/Platform/WindowlessEglApplication.cpp @@ -180,8 +180,20 @@ WindowlessEglContext::WindowlessEglContext(const Configuration& configuration, G /* Go through the EGL devices and find one that has the desired CUDA device number */ for(selectedDevice = 0; selectedDevice < UnsignedInt(count); ++selectedDevice) { + /* On NV driver 450.80.02, eglQueryDeviceAttribEXT() + segfaults when querying GPUs that the user does not have + access to (i.e. via cgroup). Instead, always call + eglQueryDeviceStringEXT() as that doesn't segfault and + sets an error that can be retrieved via eglGetError() to + see if the user has access to that device. On + well-behaved driver versions, eglQueryDeviceAttribEXT() + returns false instead of segfaulting. */ + const char* const eglExtensions = eglQueryDeviceStringEXT(devices[selectedDevice], EGL_EXTENSIONS); + if(eglGetError() == EGL_BAD_DEVICE_EXT && !magnumContext->isDriverWorkaroundDisabled("nv-egl-crashy-query-device-attrib")) + continue; + if(magnumContext && (magnumContext->internalFlags() >= GL::Context::InternalFlag::DisplayVerboseInitializationLog)) - Debug{} << "Platform::WindowlessEglApplication: eglQueryDeviceStringEXT(EGLDevice=" << Debug::nospace << selectedDevice << Debug::nospace << "):" << eglQueryDeviceStringEXT(devices[selectedDevice], EGL_EXTENSIONS); + Debug{} << "Platform::WindowlessEglApplication: eglQueryDeviceStringEXT(EGLDevice=" << Debug::nospace << selectedDevice << Debug::nospace << "):" << eglExtensions; EGLAttrib cudaDeviceNumber; if(eglQueryDeviceAttribEXT(devices[selectedDevice], EGL_CUDA_DEVICE_NV, &cudaDeviceNumber) && UnsignedInt(cudaDeviceNumber) == configuration.cudaDevice())