|
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 |
|