Blame 0001-fio-fix-dlopen-refcounting-of-dynamic-engines.patch

Eric Sandeen c47191
From 48ff7df9daea86c82a572b0a840bb8371b6b1a29 Mon Sep 17 00:00:00 2001
Eric Sandeen c47191
From: Eric Sandeen <sandeen@redhat.com>
Eric Sandeen c47191
Date: Mon, 25 Jan 2021 13:23:48 -0600
Eric Sandeen c47191
Subject: [PATCH] fio: fix dlopen refcounting of dynamic engines
Eric Sandeen c47191
Eric Sandeen c47191
ioengine_load() will dlclose the dynamic library if it matches one
Eric Sandeen c47191
that we've already got open, but this defeats the built-in refcounting
Eric Sandeen c47191
done by dlopen/dlclose.  As each thread exits, it calls free_ioengine(),
Eric Sandeen c47191
and this may do a final dlclose on a dynamic ioengine that is still
Eric Sandeen c47191
in use if we don't have the proper reference count.
Eric Sandeen c47191
Eric Sandeen c47191
Fix this by dropping the explicit dlclose of a "matching" dlopened
Eric Sandeen c47191
dynamic engine library, and let each dlclose decrement the refcount
Eric Sandeen c47191
on the engine library as is normal.
Eric Sandeen c47191
Eric Sandeen c47191
This also adds/modifies a couple of debug messages to help track this.
Eric Sandeen c47191
Eric Sandeen c47191
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Eric Sandeen c47191
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Eric Sandeen c47191
---
Eric Sandeen c47191
 init.c      | 5 +----
Eric Sandeen c47191
 ioengines.c | 8 ++++++--
Eric Sandeen c47191
 2 files changed, 7 insertions(+), 6 deletions(-)
Eric Sandeen c47191
Eric Sandeen c47191
diff --git a/init.c b/init.c
Eric Sandeen c47191
index ab38b334..d6dbaf7c 100644
Eric Sandeen c47191
--- a/init.c
Eric Sandeen c47191
+++ b/init.c
Eric Sandeen c47191
@@ -1109,11 +1109,8 @@ int ioengine_load(struct thread_data *td)
Eric Sandeen c47191
 		if (!ops)
Eric Sandeen c47191
 			goto fail;
Eric Sandeen c47191
 
Eric Sandeen c47191
-		if (ops == td->io_ops && dlhandle == td->io_ops->dlhandle) {
Eric Sandeen c47191
-			if (dlhandle)
Eric Sandeen c47191
-				dlclose(dlhandle);
Eric Sandeen c47191
+		if (ops == td->io_ops && dlhandle == td->io_ops->dlhandle)
Eric Sandeen c47191
 			return 0;
Eric Sandeen c47191
-		}
Eric Sandeen c47191
 
Eric Sandeen c47191
 		if (dlhandle && dlhandle != td->io_ops->dlhandle)
Eric Sandeen c47191
 			dlclose(dlhandle);
Eric Sandeen c47191
diff --git a/ioengines.c b/ioengines.c
Eric Sandeen c47191
index dcc9496d..f88b0537 100644
Eric Sandeen c47191
--- a/ioengines.c
Eric Sandeen c47191
+++ b/ioengines.c
Eric Sandeen c47191
@@ -95,6 +95,7 @@ static void *dlopen_external(struct thread_data *td, const char *engine)
Eric Sandeen c47191
 
Eric Sandeen c47191
 	sprintf(engine_path, "%s/fio-%s.so", FIO_EXT_ENG_DIR, engine);
Eric Sandeen c47191
 
Eric Sandeen c47191
+	dprint(FD_IO, "dlopen external %s\n", engine_path);
Eric Sandeen c47191
 	dlhandle = dlopen(engine_path, RTLD_LAZY);
Eric Sandeen c47191
 	if (!dlhandle)
Eric Sandeen c47191
 		log_info("Engine %s not found; Either name is invalid, was not built, or fio-engine-%s package is missing.\n",
Eric Sandeen c47191
@@ -116,7 +117,7 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td,
Eric Sandeen c47191
 	    !strncmp(engine_lib, "aio", 3))
Eric Sandeen c47191
 		engine_lib = "libaio";
Eric Sandeen c47191
 
Eric Sandeen c47191
-	dprint(FD_IO, "dload engine %s\n", engine_lib);
Eric Sandeen c47191
+	dprint(FD_IO, "dlopen engine %s\n", engine_lib);
Eric Sandeen c47191
 
Eric Sandeen c47191
 	dlerror();
Eric Sandeen c47191
 	dlhandle = dlopen(engine_lib, RTLD_LAZY);
Eric Sandeen c47191
@@ -194,7 +195,9 @@ struct ioengine_ops *load_ioengine(struct thread_data *td)
Eric Sandeen c47191
 	 * so as not to break job files not using the prefix.
Eric Sandeen c47191
 	 */
Eric Sandeen c47191
 	ops = __load_ioengine(td->o.ioengine);
Eric Sandeen c47191
-	if (!ops)
Eric Sandeen c47191
+
Eric Sandeen c47191
+	/* We do re-dlopen existing handles, for reference counting */
Eric Sandeen c47191
+	if (!ops || ops->dlhandle)
Eric Sandeen c47191
 		ops = dlopen_ioengine(td, name);
Eric Sandeen c47191
 
Eric Sandeen c47191
 	/*
Eric Sandeen c47191
@@ -229,6 +232,7 @@ void free_ioengine(struct thread_data *td)
Eric Sandeen c47191
 	}
Eric Sandeen c47191
 
Eric Sandeen c47191
 	if (td->io_ops->dlhandle) {
Eric Sandeen c47191
+		dprint(FD_IO, "dlclose ioengine %s\n", td->io_ops->name);
Eric Sandeen c47191
 		dlclose(td->io_ops->dlhandle);
Eric Sandeen c47191
 		td->io_ops->dlhandle = NULL;
Eric Sandeen c47191
 	}
Eric Sandeen c47191
-- 
Eric Sandeen c47191
2.26.2
Eric Sandeen c47191