From 47f8caa53f247a0f562845826d5ac0004ef8a582 Mon Sep 17 00:00:00 2001 From: erikwijmans Date: Mon, 4 Jan 2021 20:57:01 -0500 Subject: [PATCH] Add nv-egl-crashy-query-device-attrib workaround for eglQueryDeviceAttrib segfault --- src/Magnum/GL/Implementation/driverSpecific.cpp | 7 +++++++ src/Magnum/Platform/WindowlessEglApplication.cpp | 11 ++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Magnum/GL/Implementation/driverSpecific.cpp b/src/Magnum/GL/Implementation/driverSpecific.cpp index d5cda6adf..3c83ec8ca 100644 --- a/src/Magnum/GL/Implementation/driverSpecific.cpp +++ b/src/Magnum/GL/Implementation/driverSpecific.cpp @@ -161,6 +161,13 @@ 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 query 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..174afb083 100644 --- a/src/Magnum/Platform/WindowlessEglApplication.cpp +++ b/src/Magnum/Platform/WindowlessEglApplication.cpp @@ -180,8 +180,17 @@ 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 query 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())