Without this change, dlopen()/dlclose() of any driver results in memory
being leaked which becomes problematic if things are being reinitialized
repeatedly (eg from a fuzzer).

Even with this change, repeated dlopen()/dlclose() results in a single
LLVM mutex being allocated and never freed (used to synchronize 
ManagedStatic).  I've spoken to some LLVM folks and haven't come up with
a great answer on avoiding that memory leak and not running into issues
with signal handlers and/or global destructors being called after
llvm_shutdown().

With regards to the RFC, there's potentially some issues here with
multiple drivers being loaded with separate LLVM instances and being
shared due to the dlopen() being done with RTLD_GLOBAL, but this falls
squarely outside my realm of confidence.

---
 src/gallium/auxiliary/gallivm/lp_bld_misc.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp 
b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index 79dbedbb56..d537ae6029 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -68,6 +68,7 @@
 #endif
 #include <llvm/Support/CommandLine.h>
 #include <llvm/Support/Host.h>
+#include <llvm/Support/ManagedStatic.h>
 #include <llvm/Support/PrettyStackTrace.h>
 
 #include <llvm/Support/TargetSelect.h>
@@ -813,3 +814,12 @@ lp_is_function(LLVMValueRef v)
        return llvm::isa<llvm::Function>(llvm::unwrap(v));
 #endif
 }
+
+/*
+ * Attempt to clean up to allow drivers to be loaded/unloaded without
+ * leaking excessive amounts of memory.
+ */
+__attribute__((destructor)) static void llvm_fini()
+{
+   llvm::llvm_shutdown();
+}
-- 
2.18.0.203.gfac676dfb9-goog

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to