fio: option to make engines load dynamically
cover fio: option to make engines load dynamically
Hi,
The following patchset provides a configuration option that converts a select set of engines into external engines that are loaded dynamically on demand. The purpose of this option is to provide distribution packagers the ability to separate the core fio functionality from the addition optional engines. Some of the optional engines have multiple dependencies that increase the footprint of fio considerably even when the user requires only the basic 'sync' engine. See examples of the issue below.
I've tried to keep the changes as small and unobtrusive as possible. The only significant change is the way an engine is defined in the Makefile (variables are now prefixed with engine name). If the option is provided, the Makefile will build the engines as external libraries and install them in /usr/lib/fio by default. Fio will then search for the engines in that location if the engine is not compiled in. The last patch should help with the migration to the new scheme by suggesting that an additional package is required if the engine is not found.
Future work to consider:
* Move the engine help text from fio to the engines themselves. Create
* a whitelist of engines so that only engines that are part of the main
* codebase are searched and loaded automatically. Convert more engines
* to this scheme. The current set of engines was selected based on
* simplicity and external dependencies. Engines with multiple exported
* flavors (i.e. glusterfs) are not converted yet.
Branch is also available on github, at
https://github.com/ykorman/fio/tree/dynamic-libengines.
A sample of how to package fio with this new mode for RPM-based distributions is available here:
https://src.fedoraproject.org/fork/ykorman/rpms/fio/tree/dynamic-libengines
A sample of the packages for Fedora can be found here:
https://copr.fedorainfracloud.org/coprs/ykorman/fio/
See examples of how this improves our quality of life (tm) below the pull summary.
Yigal Korman (3):
configure/Makefile: engine LIBS consistency
configure: new --dynamic-libengines build option
fio: suggest installing engine package when missing
.gitignore | 1 + Makefile | 86 +++++++++++++++++++++++++++++++++++++--------- configure | 20 +++++------ engines/dev-dax.c | 2 +- engines/guasi.c | 2 +- engines/http.c | 2 +- engines/libaio.c | 2 +- engines/libhdfs.c | 6 ++-- engines/libiscsi.c | 6 ++-- engines/libpmem.c | 2 +- engines/libzbc.c | 2 +- engines/nbd.c | 2 +- engines/pmemblk.c | 2 +- engines/rados.c | 2 +- engines/rbd.c | 2 +- engines/rdma.c | 9 ++--- ioengines.c | 26 ++++++++++++-- ioengines.h | 6 ++++ os/os-linux.h | 2 ++ 19 files changed, 131 insertions(+), 51 deletions(-)
Signature · 129 lines
2.17.1 Fedora 31 install of fio, before the the patches (redacted for brevity): [root@host ~]# dnf install fio Dependencies resolved. ========================================================== Package Version Size ========================================================== Installing: fio 3.14-3.fc31 524 k Installing dependencies: cpio 2.12-12.fc31 260 k daxctl-libs 68-1.fc31 38 k dracut 050-26.git20200316.fc31 321 k findutils 1:4.6.0-25.fc31 517 k hwdata 0.336-1.fc31 1.4 M kbd-legacy 2.0.4-14.fc31 464 k kbd-misc 2.0.4-14.fc31 1.5 M kmod 26-4.fc31 122 k libaio 0.3.111-6.fc31 24 k libibverbs 20.1-6.fc31 256 k libkcapi 1.1.5-1.fc31 47 k libkcapi-hmaccalc 1.1.5-1.fc31 29 k libnl3 3.5.0-1.fc31 331 k libpmem 1.7-1.fc31 80 k libpmemblk 1.7-1.fc31 92 k librados2 2:14.2.9-2.fc31 3.5 M librbd1 2:14.2.9-2.fc31 1.8 M librdmacm 20.1-6.fc31 66 k lttng-ust 2.10.4-2.fc31 271 k ndctl-libs 68-1.fc31 77 k nspr 4.25.0-1.fc31 137 k nss 3.53.0-1.fc31 677 k nss-softokn 3.53.0-1.fc31 441 k nss-softokn-freebl 3.53.0-1.fc31 248 k nss-sysinit 3.53.0-1.fc31 20 k nss-util 3.53.0-1.fc31 89 k numactl-libs 2.0.12-3.fc31 30 k pciutils 3.6.4-1.fc31 90 k pciutils-libs 3.6.4-1.fc31 41 k procps-ng 3.3.15-6.fc31 326 k rdma-core 20.1-6.fc31 51 k systemd-udev 243.8-1.fc31 1.3 M userspace-rcu 0.11.1-2.fc31 104 k xz 5.2.4-6.fc31 147 k Installing weak dependenc kbd 2.0.4-14.fc31 391 k kpartx 0.8.0-3.fc31 55 k pigz 2.4-5.fc31 78 k systemd-bootchart 233-5.fc31 71 k Transaction Summary ========================================================= Install 39 Packages Total download size: 16 M Installed size: 57 M After this patchset: [root@host ~]# dnf install fio =============================================== Package Version Size =============================================== Installing: fio 3.20-1.fc33 526 k Installing dependencies: numactl-libs 2.0.12-3.fc31 30 k Transaction Summary =============================================== Install 2 Packages Total size: 557 k Total download size: 30 k Installed size: 2.1 M And when a specific engine is needed: [root@host ~]# dnf install fio-engine-rados Dependencies resolved. ======================================================== Package Version Size ======================================================== Installing: fio-engine-rados 3.20-1.fc33 15 k Installing dependencies: cpio 2.12-12.fc31 260 k dracut 050-26.git20200316.fc31 321 k findutils 1:4.6.0-25.fc31 517 k hwdata 0.336-1.fc31 1.4 M kbd-legacy 2.0.4-14.fc31 464 k kbd-misc 2.0.4-14.fc31 1.5 M kmod 26-4.fc31 122 k libibverbs 20.1-6.fc31 256 k libkcapi 1.1.5-1.fc31 47 k libkcapi-hmaccalc 1.1.5-1.fc31 29 k libnl3 3.5.0-1.fc31 331 k librados2 2:14.2.9-2.fc31 3.5 M librdmacm 20.1-6.fc31 66 k lttng-ust 2.10.4-2.fc31 271 k nspr 4.25.0-1.fc31 137 k nss 3.53.0-1.fc31 677 k nss-softokn 3.53.0-1.fc31 441 k nss-softokn-freebl 3.53.0-1.fc31 248 k nss-sysinit 3.53.0-1.fc31 20 k nss-util 3.53.0-1.fc31 89 k pciutils 3.6.4-1.fc31 90 k pciutils-libs 3.6.4-1.fc31 41 k procps-ng 3.3.15-6.fc31 326 k rdma-core 20.1-6.fc31 51 k systemd-udev 243.8-1.fc31 1.3 M userspace-rcu 0.11.1-2.fc31 104 k xz 5.2.4-6.fc31 147 k Installing weak dependenc kbd 2.0.4-14.fc31 391 k kpartx 0.8.0-3.fc31 55 k pigz 2.4-5.fc31 78 k systemd-bootchart 233-5.fc31 71 k Transaction Summary ======================================================== Install 32 Packages Total size: 13 M Total download size: 13 M Installed size: 48 M
PATCH 1/3 configure/Makefile: engine LIBS consistency
Some engines were adding their LIBS in the Makefile and some were declaring them in the configure script.
This is inconsistent and confusing and prevents easy bulk changes to the engines.
--- Makefile | 14 ++++++++++++++ configure | 12 ------------ 2 files changed, 14 insertions(+), 12 deletions(-)
Makefile +14 -0
@@ -79,9 +79,15 @@ ifdef CONFIG_32BIT endif ifdef CONFIG_LIBAIO SOURCE += engines/libaio.c + ifdef CONFIG_LIBAIO_URING + LIBS += -luring + else + LIBS += -laio + endif endif ifdef CONFIG_RDMA SOURCE += engines/rdma.c + LIBS += -libverbs -lrdmacm endif ifdef CONFIG_POSIXAIO SOURCE += engines/posixaio.c
@@ -106,12 +112,15 @@ ifdef CONFIG_WINDOWSAIO endif ifdef CONFIG_RADOS SOURCE += engines/rados.c + LIBS += -lrados endif ifdef CONFIG_RBD SOURCE += engines/rbd.c + LIBS += -lrbd -lrados endif ifdef CONFIG_HTTP SOURCE += engines/http.c + LIBS += -lcurl -lssl -lcrypto endif SOURCE += oslib/asprintf.c ifndef CONFIG_STRSEP
@@ -139,6 +148,7 @@ ifdef CONFIG_GFAPI SOURCE += engines/glusterfs.c SOURCE += engines/glusterfs_sync.c SOURCE += engines/glusterfs_async.c + LIBS += -lgfapi -lglusterfs ifdef CONFIG_GF_FADVISE CFLAGS := "-DGFAPI_USE_FADVISE" $(CFLAGS) endif
@@ -150,18 +160,22 @@ ifdef CONFIG_MTD endif ifdef CONFIG_PMEMBLK SOURCE += engines/pmemblk.c + LIBS += -lpmemblk endif ifdef CONFIG_LINUX_DEVDAX SOURCE += engines/dev-dax.c + LIBS += -lpmem endif ifdef CONFIG_LIBPMEM SOURCE += engines/libpmem.c + LIBS += -lpmem endif ifdef CONFIG_IME SOURCE += engines/ime.c endif ifdef CONFIG_LIBZBC SOURCE += engines/libzbc.c + LIBS += -lzbc endif ifeq ($(CONFIG_TARGET_OS), Linux)
configure +0 -12
@@ -605,11 +605,9 @@ int main(void) EOF if test "$libaio_uring" = "yes" && compile_prog "" "-luring" "libaio io_uring" ; then libaio=yes - LIBS="-luring $LIBS" elif compile_prog "" "-laio" "libaio" ; then libaio=yes libaio_uring=no - LIBS="-laio $LIBS" else if test "$libaio" = "yes" ; then feature_not_found "linux AIO" "libaio-dev or libaio-devel"
@@ -859,7 +857,6 @@ int main(int argc, char **argv) EOF if test "$disable_rdma" != "yes" && compile_prog "" "-libverbs" "libverbs" ; then libverbs="yes" - LIBS="-libverbs $LIBS" fi print_config "libverbs" "$libverbs"
@@ -879,7 +876,6 @@ int main(int argc, char **argv) EOF if test "$disable_rdma" != "yes" && compile_prog "" "-lrdmacm" "rdma"; then rdmacm="yes" - LIBS="-lrdmacm $LIBS" fi print_config "rdmacm" "$rdmacm"
@@ -1770,10 +1766,8 @@ if test "$disable_http" != "yes"; then if compile_prog "" "$HTTP_LIBS" "curl-new-ssl"; then output_sym "CONFIG_HAVE_OPAQUE_HMAC_CTX" http="yes" - LIBS="$HTTP_LIBS $LIBS" elif mv $TMPC2 $TMPC && compile_prog "" "$HTTP_LIBS" "curl-old-ssl"; then http="yes" - LIBS="$HTTP_LIBS $LIBS" fi fi print_config "http engine" "$http"
@@ -1802,7 +1796,6 @@ int main(int argc, char **argv) } EOF if test "$disable_rados" != "yes" && compile_prog "" "-lrados" "rados"; then - LIBS="-lrados $LIBS" rados="yes" fi print_config "Rados engine" "$rados"
@@ -1833,7 +1826,6 @@ int main(int argc, char **argv) } EOF if test "$disable_rbd" != "yes" && compile_prog "" "-lrbd -lrados" "rbd"; then - LIBS="-lrbd -lrados $LIBS" rbd="yes" fi print_config "Rados Block Device engine" "$rbd"
@@ -1924,7 +1916,6 @@ int main(int argc, char **argv) } EOF if test "$disable_gfapi" != "yes" && compile_prog "" "-lgfapi -lglusterfs" "gfapi"; then - LIBS="-lgfapi -lglusterfs $LIBS" gfapi="yes" fi print_config "Gluster API engine" "$gfapi"
@@ -2086,7 +2077,6 @@ int main(int argc, char **argv) EOF if compile_prog "" "-lpmem" "libpmem"; then libpmem="yes" - LIBS="-lpmem $LIBS" fi print_config "libpmem" "$libpmem"
@@ -2108,7 +2098,6 @@ int main(int argc, char **argv) EOF if compile_prog "" "-lpmemblk" "libpmemblk"; then libpmemblk="yes" - LIBS="-lpmemblk $LIBS" fi fi print_config "libpmemblk" "$libpmemblk"
@@ -2432,7 +2421,6 @@ if compile_prog "" "-lzbc" "libzbc"; then libzbcvermaj=$(pkg-config --modversion libzbc | sed 's/\.[0-9]*\.[0-9]*//') if test "$libzbcvermaj" -ge "5" ; then libzbc="yes" - LIBS="-lzbc $LIBS" else print_config "libzbc engine" "Unsupported libzbc version (version 5 or above required)" libzbc="no"
Signature · 1 line
2.17.1
PATCH 2/3 configure: new --dynamic-libengines build option
In reply to Yigal KormanWhen enabled, some of the more dependency-heavy internal engines are converted to "plugin" engines, i.e. they are built into separate object files and are loaded by fio on demand.
This helps downstream distros package these engines separately and not force a long list of package dependencies from the base fio package.
--- .gitignore | 1 + Makefile | 92 ++++++++++++++++++++++++++++++++-------------- configure | 8 ++++ engines/dev-dax.c | 2 +- engines/guasi.c | 2 +- engines/http.c | 2 +- engines/libaio.c | 2 +- engines/libhdfs.c | 6 +-- engines/libiscsi.c | 6 +-- engines/libpmem.c | 2 +- engines/libzbc.c | 2 +- engines/nbd.c | 2 +- engines/pmemblk.c | 2 +- engines/rados.c | 2 +- engines/rbd.c | 2 +- engines/rdma.c | 9 +++-- ioengines.c | 20 +++++++++- ioengines.h | 6 +++ os/os-linux.h | 2 + 19 files changed, 121 insertions(+), 49 deletions(-)
.gitignore +1 -0
@@ -1,5 +1,6 @@ *.d *.o +*.so *.exe /.depend /FIO-VERSION-FILE
Makefile +65 -27
167 lines not on this page · raw message
configure +8 -0
@@ -151,6 +151,7 @@ march_set="no" libiscsi="no" libnbd="no" libaio_uring="no" +dynamic_engines="no" prefix=/usr/local # parse options
@@ -215,6 +216,8 @@ for opt do ;; --enable-libaio-uring) libaio_uring="yes" ;; + --dynamic-libengines) dynamic_engines="yes" + ;; --help) show_help="yes" ;;
@@ -254,6 +257,7 @@ if test "$show_help" = "yes" ; then echo "--enable-libnbd Enable libnbd (NBD engine) support" echo "--disable-tcmalloc Disable tcmalloc support" echo "--enable-libaio-uring Enable libaio emulated over io_uring" + echo "--dynamic-libengines Lib-based ioengines as dynamic libraries" exit $exit_val fi
@@ -2954,6 +2958,10 @@ if test "$libnbd" = "yes" ; then echo "LIBNBD_CFLAGS=$libnbd_cflags" >> $config_host_mak echo "LIBNBD_LIBS=$libnbd_libs" >> $config_host_mak fi +if test "$dynamic_engines" = "yes" ; then + output_sym "CONFIG_DYNAMIC_ENGINES" +fi +print_config "Lib-based ioengines dynamic" "$dynamic_engines" cat > $TMPC << EOF int main(int argc, char **argv) {
engines/dev-dax.c +1 -1
@@ -328,7 +328,7 @@ fio_devdax_get_file_size(struct thread_data *td, struct fio_file *f)return 0 ; } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="dev-dax" , .version =FIO_IOOPS_VERSION , .init = fio_devdax_init,
engines/guasi.c +1 -1
@@ -242,7 +242,7 @@ static int fio_guasi_init(struct thread_data *td)return 0 ; } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="guasi" , .version =FIO_IOOPS_VERSION , .init = fio_guasi_init,
engines/http.c +1 -1
@@ -639,7 +639,7 @@ static int fio_http_invalidate(struct thread_data *td, struct fio_file *f)return 0 ; } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="http" , .version =FIO_IOOPS_VERSION , .flags =FIO_DISKLESSIO |FIO_SYNCIO ,
engines/libaio.c +1 -1
@@ -445,7 +445,7 @@ static int fio_libaio_init(struct thread_data *td)return 0 ; } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="libaio" , .version =FIO_IOOPS_VERSION , .flags =FIO_ASYNCIO_SYNC_TRIM ,
engines/libhdfs.c +3 -3
@@ -393,7 +393,7 @@ static void fio_hdfsio_io_u_free(struct thread_data *td, struct io_u *io_u) } } -static struct ioengine_ops ioengine_hdfs = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="libhdfs" , .version =FIO_IOOPS_VERSION , .flags =FIO_SYNCIO |FIO_DISKLESSIO |FIO_NODISKUTIL ,
@@ -412,10 +412,10 @@ static struct ioengine_ops ioengine_hdfs = { static void fio_init fio_hdfsio_register(void) { -register_ioengine (&ioengine_hdfs); +register_ioengine (&ioengine); } static void fio_exit fio_hdfsio_unregister(void) { -unregister_ioengine (&ioengine_hdfs); +unregister_ioengine (&ioengine); }
engines/libiscsi.c +3 -3
@@ -383,7 +383,7 @@ static struct io_u *fio_iscsi_event(struct thread_data *td, int event)return io_u; } -static struct ioengine_ops ioengine_iscsi = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="libiscsi" , .version =FIO_IOOPS_VERSION , .flags =FIO_SYNCIO |FIO_DISKLESSIO |FIO_NODISKUTIL ,
@@ -402,10 +402,10 @@ static struct ioengine_ops ioengine_iscsi = { static void fio_init fio_iscsi_register(void) { -register_ioengine (&ioengine_iscsi); +register_ioengine (&ioengine); } static void fio_exit fio_iscsi_unregister(void) { -unregister_ioengine (&ioengine_iscsi); +unregister_ioengine (&ioengine); }
engines/libpmem.c +1 -1
@@ -558,7 +558,7 @@ static int fio_libpmem_close_file(struct thread_data *td, struct fio_file *f)return generic_close_file (td, f); } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="libpmem" , .version =FIO_IOOPS_VERSION , .init = fio_libpmem_init,
engines/libzbc.c +1 -1
@@ -397,7 +397,7 @@ static enum fio_q_status libzbc_queue(struct thread_data *td, struct io_u *io_u)return FIO_Q_COMPLETED ; } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="libzbc" , .version =FIO_IOOPS_VERSION , .open_file = libzbc_open_file,
engines/nbd.c +1 -1
@@ -328,7 +328,7 @@ static int nbd_invalidate(struct thread_data *td, struct fio_file *f)return 0 ; } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="nbd" , .version =FIO_IOOPS_VERSION , .options = options,
engines/pmemblk.c +1 -1
@@ -426,7 +426,7 @@ static int fio_pmemblk_unlink_file(struct thread_data *td, struct fio_file *f)return 0 ; } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="pmemblk" , .version =FIO_IOOPS_VERSION , .queue = fio_pmemblk_queue,
engines/rados.c +1 -1
@@ -444,7 +444,7 @@ static int fio_rados_io_u_init(struct thread_data *td, struct io_u *io_u) }/* ioengine_ops for get_ioengine() */ -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="rados" , .version =FIO_IOOPS_VERSION , .flags =FIO_DISKLESSIO ,
engines/rbd.c +1 -1
@@ -668,7 +668,7 @@ static int fio_rbd_io_u_init(struct thread_data *td, struct io_u *io_u)return 0 ; } -static struct ioengine_ops ioengine = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="rbd" , .version =FIO_IOOPS_VERSION , .setup = fio_rbd_setup,
engines/rdma.c +5 -4
@@ -226,7 +226,8 @@ static int client_recv(struct thread_data *td, struct ibv_wc *wc) rd->rmt_nr =ntohl (rd->recv_buf.nr);for (i =0 ; i < rd->rmt_nr; i++) { - rd->rmt_us[i].buf =be64_to_cpu (rd->recv_buf.rmt_us[i].buf); + rd->rmt_us[i].buf =__be64_to_cpu ( + rd->recv_buf.rmt_us[i].buf); rd->rmt_us[i].rkey =ntohl (rd->recv_buf.rmt_us[i].rkey); rd->rmt_us[i].size =ntohl (rd->recv_buf.rmt_us[i].size);
@@ -1389,7 +1390,7 @@ static int fio_rdmaio_setup(struct thread_data *td)return 0 ; } -static struct ioengine_ops ioengine_rw = { +FIO_STATIC struct ioengine_ops ioengine = { .name ="rdma" , .version =FIO_IOOPS_VERSION , .setup = fio_rdmaio_setup,
@@ -1410,10 +1411,10 @@ static struct ioengine_ops ioengine_rw = { static void fio_init fio_rdmaio_register(void) { -register_ioengine (&ioengine_rw); +register_ioengine (&ioengine); } static void fio_exit fio_rdmaio_unregister(void) { -unregister_ioengine (&ioengine_rw); +unregister_ioengine (&ioengine); }
ioengines.c +18 -2
@@ -75,6 +75,19 @@ static struct ioengine_ops *find_ioengine(const char *name)return NULL ; } +#ifdef CONFIG_DYNAMIC_ENGINES +static void *dlopen_external (struct thread_data *td,const char *engine) +{ +char engine_path[PATH_MAX ]; + +sprintf (engine_path,"%s/lib%s.so" ,FIO_EXT_ENG_DIR , engine); + +return dlopen (engine_path,RTLD_LAZY ); +} +#else +#define dlopen_external (td, engine) (NULL) +#endif +static struct ioengine_ops *dlopen_ioengine (struct thread_data *td,const char *engine_lib) {
@@ -86,8 +99,11 @@ static struct ioengine_ops *dlopen_ioengine(struct thread_data *td,dlerror (); dlhandle =dlopen (engine_lib,RTLD_LAZY );if (!dlhandle) { -td_vmsg (td,-1 ,dlerror (),"dlopen" ); -return NULL ; + dlhandle =dlopen_external (td, engine_lib); +if (!dlhandle) { +td_vmsg (td,-1 ,dlerror (),"dlopen" ); +return NULL ; + } }/*
ioengines.h +6 -0
@@ -10,6 +10,12 @@#define FIO_IOOPS_VERSION 26 +#ifndef CONFIG_DYNAMIC_ENGINES +#define FIO_STATIC static +#else +#define FIO_STATIC +#endif +/* * io_ops->queue() return values */
os/os-linux.h +2 -0
@@ -58,6 +58,8 @@#define OS_MAP_ANON MAP_ANONYMOUS +#define FIO_EXT_ENG_DIR "/usr/lib/fio" +typedef cpu_set_t os_cpu_mask_t ;#ifdef CONFIG_3ARG_AFFINITY
Signature · 1 line
2.17.1
PATCH 3/3 fio: suggest installing engine package when missing
In reply to Yigal Korman--- ioengines.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
ioengines.c +7 -1
@@ -79,10 +79,16 @@ static struct ioengine_ops *find_ioengine(const char *name)static void *dlopen_external (struct thread_data *td,const char *engine) {char engine_path[PATH_MAX ]; +void *dlhandle;sprintf (engine_path,"%s/lib%s.so" ,FIO_EXT_ENG_DIR , engine); -return dlopen (engine_path,RTLD_LAZY ); + dlhandle =dlopen (engine_path,RTLD_LAZY ); +if (!dlhandle) +log_info ("Engine not available; Install the fio-engine-%s package\n" , + engine); + +return dlhandle; }#else #define dlopen_external (td, engine) (NULL)
Signature · 1 line
2.17.1
Re: [PATCH v1 3/3] fio: suggest installing engine package when missing
Quoted 17 lines · Yigal Korman
Signed-off-by Yigal Korman <[email protected]>--- ioengines.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)ioengines.c +1
-0@@ -79,10 +79,16 @@ static struct ioengine_ops *find_ioengine(const char *name)static void *dlopen_external (struct thread_data *td,const char *engine) {char engine_path[PATH_MAX ]; +void *dlhandle;sprintf (engine_path,"%s/lib%s.so" ,FIO_EXT_ENG_DIR , engine);
ioengines.c static struct ioengine_ops *find_ioengine(const char *name) · line 94
Quoted 10 lines
ioengines.c +6
-1- return dlopen(engine_path, RTLD_LAZY); + dlhandle =dlopen (engine_path,RTLD_LAZY ); +if (!dlhandle) +log_info ("Engine not available; Install the fio-engine-%s package\n" , + engine); + + return dlhandle; }#else #define dlopen_external (td, engine) (NULL)
This assumes fio is part of a package, and that's not always (often?) the case. It may be that the engine simply wasn't built.
-Jeff
Quoted 10 lines · Yigal Korman
Hi,
The following patchset provides a configuration option that converts a select set of engines into external engines that are loaded dynamically on demand. The purpose of this option is to provide distribution packagers the ability to separate the core fio functionality from the addition optional engines. Some of the optional engines have multiple dependencies that increase the footprint of fio considerably even when the user requires only the basic 'sync' engine. See examples of the issue below.
Did you forget to include the examples?
I'm not sure I see a benefit to this change. fio isn't some core system service--it's a benchmarking tool. Maybe your examples shed more light on why this matters?
-Jeff
Quoted 57 lines
I've tried to keep the changes as small and unobtrusive as possible. The only significant change is the way an engine is defined in the
Makefile(variables are now prefixed with engine name). If the option is provided, theMakefilewill build the engines as external libraries and install them in/usr/lib/fioby default. Fio will then search for the engines in that location if the engine is not compiled in. The last patch should help with the migration to the new scheme by suggesting that an additional package is required if the engine is not found.Future work to consider:
* Move the engine help text from fio to the engines themselves. Create
* a whitelist of engines so that only engines that are part of the main
* codebase are searched and loaded automatically. Convert more engines
* to this scheme. The current set of engines was selected based on
* simplicity and external dependencies. Engines with multiple exported
* flavors (i.e. glusterfs) are not converted yet.Branch is also available on github, at
https://github.com/ykorman/fio/tree/dynamic-libengines.A sample of how to package fio with this new mode for RPM-based distributions is available here:
https://src.fedoraproject.org/fork/ykorman/rpms/fio/tree/dynamic-libenginesA sample of the packages for Fedora can be found here:
https://copr.fedorainfracloud.org/coprs/ykorman/fio/See examples of how this improves our quality of life (tm) below the pull summary.
Yigal Korman (3):
configure/Makefile: engine LIBS consistency
configure: new --dynamic-libengines build option
fio: suggest installing engine package when missing.gitignore | 1 + Makefile | 86 +++++++++++++++++++++++++++++++++++++--------- configure | 20 +++++------ engines/dev-dax.c | 2 +- engines/guasi.c | 2 +- engines/http.c | 2 +- engines/libaio.c | 2 +- engines/libhdfs.c | 6 ++-- engines/libiscsi.c | 6 ++-- engines/libpmem.c | 2 +- engines/libzbc.c | 2 +- engines/nbd.c | 2 +- engines/pmemblk.c | 2 +- engines/rados.c | 2 +- engines/rbd.c | 2 +- engines/rdma.c | 9 ++--- ioengines.c | 26 ++++++++++++-- ioengines.h | 6 ++++ os/os-linux.h | 2 ++ 19 files changed, 131 insertions(+), 51 deletions(-)
Hi Jeff,
Thanks for taking a look at this.
Answers inline below.
Quoted 13 lines · Jeff Moyer
Quoted 10 lines · Yigal Korman
Hi,
The following patchset provides a configuration option that converts a select set of engines into external engines that are loaded dynamically on demand. The purpose of this option is to provide distribution packagers the ability to separate the core fio functionality from the addition optional engines. Some of the optional engines have multiple dependencies that increase the footprint of fio considerably even when the user requires only the basic 'sync' engine. See examples of the issue below.
Quoted 2 lines
Did you forget to include the examples?
Sorry, I didn't, it's easy to miss though, they're below the pull summary.
They are a bit verbose, so I'll recap here:
Without the patchset, on a Fedora 31 system, installing fio brings a total of 38 package dependencies, the installed size is 57MB.
With the patchset, installing fio brings a single dependency (numactl-libs) and the installed size is 2.1MB.
These numbers are relatively small but when one needs to bring fio to an offline server, collecting these dependencies is a hassle. Also, bundling fio into a container where the base image is small (Fedora 31 is ~200MB), the install size becomes more prominent.
Quoted 4 lines
I'm not sure I see a benefit to this change. fio isn't some core system service--it's a benchmarking tool. Maybe your examples shed more light on why this matters?
I actually think that although fio is a benchmarking tool, it became so ubiquitous in the storage world that I'd consider it a core tool. I think all recent storage-related research papers and product brochures that I saw have always included fio performance numbers. Perhaps, if it will be possible to reduce its footprint, we might start seeing it on the distro's base install.
Regards,
Yigal
Quoted 62 lines
-Jeff
Quoted 18 lines
I've tried to keep the changes as small and unobtrusive as possible. The only significant change is the way an engine is defined in the
Makefile(variables are now prefixed with engine name). If the option is provided, theMakefilewill build the engines as external libraries and install them in/usr/lib/fioby default. Fio will then search for the engines in that location if the engine is not compiled in. The last patch should help with the migration to the new scheme by suggesting that an additional package is required if the engine is not found.Future work to consider:
* Move the engine help text from fio to the engines themselves. Create
* a whitelist of engines so that only engines that are part of the main
* codebase are searched and loaded automatically. Convert more engines
* to this scheme. The current set of engines was selected based on
* simplicity and external dependencies. Engines with multiple exported
* flavors (i.e. glusterfs) are not converted yet.Quoted 6 lines
Branch is also available on github, at
https://github.com/ykorman/fio/tree/dynamic-libengines.A sample of how to package fio with this new mode for RPM-based distributions is available here:
https://src.fedoraproject.org/fork/ykorman/rpms/fio/tree/dynamic-libengines
Quoted 33 lines
A sample of the packages for Fedora can be found here:
https://copr.fedorainfracloud.org/coprs/ykorman/fio/See examples of how this improves our quality of life (tm) below the pull summary.
Yigal Korman (3):
configure/Makefile: engine LIBS consistency
configure: new --dynamic-libengines build option
fio: suggest installing engine package when missing.gitignore | 1 + Makefile | 86 +++++++++++++++++++++++++++++++++++++--------- configure | 20 +++++------ engines/dev-dax.c | 2 +- engines/guasi.c | 2 +- engines/http.c | 2 +- engines/libaio.c | 2 +- engines/libhdfs.c | 6 ++-- engines/libiscsi.c | 6 ++-- engines/libpmem.c | 2 +- engines/libzbc.c | 2 +- engines/nbd.c | 2 +- engines/pmemblk.c | 2 +- engines/rados.c | 2 +- engines/rbd.c | 2 +- engines/rdma.c | 9 ++--- ioengines.c | 26 ++++++++++++-- ioengines.h | 6 ++++ os/os-linux.h | 2 ++ 19 files changed, 131 insertions(+), 51 deletions(-)
Hi Jeff,
Thanks for taking a look at this.
Answers (this time in plain text, sorry about that) inline below.
Quoted 14 lines · Jeff Moyer
Quoted 10 lines · Yigal Korman
Hi,
The following patchset provides a configuration option that converts a select set of engines into external engines that are loaded dynamically on demand. The purpose of this option is to provide distribution packagers the ability to separate the core fio functionality from the addition optional engines. Some of the optional engines have multiple dependencies that increase the footprint of fio considerably even when the user requires only the basic 'sync' engine. See examples of the issue below.
Quoted 1 line
Did you forget to include the examples?
Sorry, I didn't, it's easy to miss though, they're below the pull summary.
They are a bit verbose, so I'll recap here:
Without the patchset, on a Fedora 31 system, installing fio brings a total of 38 package dependencies, the installed size is 57MB. With the patchset, installing fio brings a single dependency (numactl-libs) and the installed size is 2.1MB.
These numbers are relatively small but when one needs to bring fio to an offline server, collecting these dependencies is a hassle. Also, bundling fio into a container where the base image is small (Fedora 31 is ~200MB), the install size becomes more prominent.
Quoted 4 lines
I'm not sure I see a benefit to this change. fio isn't some core system service--it's a benchmarking tool. Maybe your examples shed more light on why this matters?
I actually think that although fio is a benchmarking tool, it became so ubiquitous in the storage world that I'd consider it a core tool. I think all recent storage-related research papers and product brochures that I saw have always included fio performance numbers. Perhaps, if it will be possible to reduce its footprint, we might start seeing it on the distro's base install.
Regards,
Yigal
Quoted 61 lines
-Jeff
Quoted 57 lines
I've tried to keep the changes as small and unobtrusive as possible. The only significant change is the way an engine is defined in the
Makefile(variables are now prefixed with engine name). If the option is provided, theMakefilewill build the engines as external libraries and install them in/usr/lib/fioby default. Fio will then search for the engines in that location if the engine is not compiled in. The last patch should help with the migration to the new scheme by suggesting that an additional package is required if the engine is not found.Future work to consider:
* Move the engine help text from fio to the engines themselves. Create
* a whitelist of engines so that only engines that are part of the main
* codebase are searched and loaded automatically. Convert more engines
* to this scheme. The current set of engines was selected based on
* simplicity and external dependencies. Engines with multiple exported
* flavors (i.e. glusterfs) are not converted yet.Branch is also available on github, at
https://github.com/ykorman/fio/tree/dynamic-libengines.A sample of how to package fio with this new mode for RPM-based distributions is available here:
https://src.fedoraproject.org/fork/ykorman/rpms/fio/tree/dynamic-libenginesA sample of the packages for Fedora can be found here:
https://copr.fedorainfracloud.org/coprs/ykorman/fio/See examples of how this improves our quality of life (tm) below the pull summary.
Yigal Korman (3):
configure/Makefile: engine LIBS consistency
configure: new --dynamic-libengines build option
fio: suggest installing engine package when missing.gitignore | 1 + Makefile | 86 +++++++++++++++++++++++++++++++++++++--------- configure | 20 +++++------ engines/dev-dax.c | 2 +- engines/guasi.c | 2 +- engines/http.c | 2 +- engines/libaio.c | 2 +- engines/libhdfs.c | 6 ++-- engines/libiscsi.c | 6 ++-- engines/libpmem.c | 2 +- engines/libzbc.c | 2 +- engines/nbd.c | 2 +- engines/pmemblk.c | 2 +- engines/rados.c | 2 +- engines/rbd.c | 2 +- engines/rdma.c | 9 ++--- ioengines.c | 26 ++++++++++++-- ioengines.h | 6 ++++ os/os-linux.h | 2 ++ 19 files changed, 131 insertions(+), 51 deletions(-)
Re: [PATCH v1 2/3] configure: new --dynamic-libengines build option
In reply to Yigal KormanQuoted 5 lines · Yigal Korman
When enabled, some of the more dependency-heavy internal engines are converted to "plugin" engines, i.e. they are built into separate object files and are loaded by fio on demand.
This helps downstream distros package these engines separately and not force a long list of package dependencies from the base fio package.
How does this impact the performance of the engine? It'd be interesting to run a test with something ala:
fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
with the current build, then apply these patches (and turn the null engine into an externally loadable engine, of course), and re-run the test case.
For what it's worth, I like the change in general, as dependencies do pile on. But I'd like to ensure that we're not taking a performance hit for something like this.
Signature · 1 line
Jens Axboe
Re: [PATCH v1 2/3] configure: new --dynamic-libengines build option
Quoted 11 lines · Jens Axboe
Quoted 5 lines · Yigal Korman
When enabled, some of the more dependency-heavy internal engines are converted to "plugin" engines, i.e. they are built into separate object files and are loaded by fio on demand.
This helps downstream distros package these engines separately and not force a long list of package dependencies from the base fio package.How does this impact the performance of the engine? It'd be interesting to run a test with something ala:
Quoted 8 lines
fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
with the current build, then apply these patches (and turn the null engine into an externally loadable engine, of course), and re-run the test case.
For what it's worth, I like the change in general, as dependencies do pile on. But I'd like to ensure that we're not taking a performance hit for something like this.
Great to hear.
Here are the results of the run you suggested:
current build (statically linked) -
[root@host fio]# ./fio.static --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3910MiB/s][r=1001k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=155: Tue Jun 30 06:55:19 2020
read: IOPS=1000k, BW=3906MiB/s (4095MB/s)(100GiB/26219msec)
bw ( MiB/s): min= 3786, max= 3967, per=100.00%, avg=3909.96,
stdev=38.59, samples=52
iops : min=969293, max=1015596, avg=1000951.42,
stdev=9879.80, samples=52
cpu : usr=61.66%, sys=38.31%, ctx=103, majf=8, minf=5
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1Run status group 0 (all jobs):
READ: bw=3906MiB/s (4095MB/s), 3906MiB/s-3906MiB/s
(4095MB/s-4095MB/s), io=100GiB (107GB), run=26219-26219msec
With patches applied[0] -
[root@host fio]# ./fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3905MiB/s][r=1000k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=158: Tue Jun 30 06:55:49 2020
read: IOPS=1006k, BW=3929MiB/s (4120MB/s)(100GiB/26060msec)
bw ( MiB/s): min= 3753, max= 3988, per=100.00%, avg=3933.86,
stdev=45.93, samples=52
iops : min=960962, max=1021038, avg=1007067.92,
stdev=11758.92, samples=52
cpu : usr=62.14%, sys=37.81%, ctx=117, majf=8, minf=5
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1Run status group 0 (all jobs):
READ: bw=3929MiB/s (4120MB/s), 3929MiB/s-3929MiB/s
(4120MB/s-4120MB/s), io=100GiB (107GB), run=26060-26060msec
I wasn't expecting dynamic linking to have a performance impact and the results seem to agree.
Thanks!
[0] branch with the null engine converted to dynamic:
https://github.com/ykorman/fio/tree/devel
Yigal
Quoted 5 lines
--
Jens Axboe
Re: [PATCH v1 3/3] fio: suggest installing engine package when missing
In reply to Jeff MoyerQuoted 20 lines · Jeff Moyer
Quoted 17 lines · Yigal Korman
Signed-off-by Yigal Korman <[email protected]>--- ioengines.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)ioengines.c +1
-0@@ -79,10 +79,16 @@ static struct ioengine_ops *find_ioengine(const char *name)static void *dlopen_external (struct thread_data *td,const char *engine) {char engine_path[PATH_MAX ]; +void *dlhandle;sprintf (engine_path,"%s/lib%s.so" ,FIO_EXT_ENG_DIR , engine);
Quoted 13 lines
ioengines.c static struct ioengine_ops *find_ioengine(const char *name) · line 94
Quoted 10 lines
ioengines.c +6
-1- return dlopen(engine_path, RTLD_LAZY); + dlhandle =dlopen (engine_path,RTLD_LAZY ); +if (!dlhandle) +log_info ("Engine not available; Install the fio-engine-%s package\n" , + engine); + + return dlhandle; }#else #define dlopen_external (td, engine) (NULL)This assumes fio is part of a package, and that's not always (often?) the case. It may be that the engine simply wasn't built.
I agree.
This patch is more of a showcase of how to help package maintainers transition users to the new packaging model.
I will drop it from the next patchset version.
This patch might have made more sense if I had implemented a whitelist of engines that were compiled dynamically.
Thanks,
Yigal
Quoted 3 lines
-Jeff
Re: [PATCH v1 2/3] configure: new --dynamic-libengines build option
In reply to Yigal KormanQuoted 73 lines · Yigal Korman
Quoted 11 lines · Jens Axboe
Quoted 5 lines · Yigal Korman
When enabled, some of the more dependency-heavy internal engines are converted to "plugin" engines, i.e. they are built into separate object files and are loaded by fio on demand.
This helps downstream distros package these engines separately and not force a long list of package dependencies from the base fio package.How does this impact the performance of the engine? It'd be interesting to run a test with something ala:
Quoted 8 lines
fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
with the current build, then apply these patches (and turn the null engine into an externally loadable engine, of course), and re-run the test case.
For what it's worth, I like the change in general, as dependencies do pile on. But I'd like to ensure that we're not taking a performance hit for something like this.
Great to hear.
Here are the results of the run you suggested:
current build (statically linked) -
[root@host fio]# ./fio.static --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3910MiB/s][r=1001k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=155: Tue Jun 30 06:55:19 2020
read: IOPS=1000k, BW=3906MiB/s (4095MB/s)(100GiB/26219msec)
bw ( MiB/s): min= 3786, max= 3967, per=100.00%, avg=3909.96,
stdev=38.59, samples=52
iops : min=969293, max=1015596, avg=1000951.42,
stdev=9879.80, samples=52cpu : usr=61.66%, sys=38.31%, ctx=103, majf=8, minf=5 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1Run status group 0 (all jobs):
READ: bw=3906MiB/s (4095MB/s), 3906MiB/s-3906MiB/s(4095MB/s-4095MB/s), io=100GiB (107GB), run=26219-26219msec
With patches applied[0] -
[root@host fio]# ./fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3905MiB/s][r=1000k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=158: Tue Jun 30 06:55:49 2020
read: IOPS=1006k, BW=3929MiB/s (4120MB/s)(100GiB/26060msec)
bw ( MiB/s): min= 3753, max= 3988, per=100.00%, avg=3933.86,
stdev=45.93, samples=52
iops : min=960962, max=1021038, avg=1007067.92,
stdev=11758.92, samples=52cpu : usr=62.14%, sys=37.81%, ctx=117, majf=8, minf=5 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1
Quoted 6 lines
Run status group 0 (all jobs):
READ: bw=3929MiB/s (4120MB/s), 3929MiB/s-3929MiB/s(4120MB/s-4120MB/s), io=100GiB (107GB), run=26060-26060msec
I wasn't expecting dynamic linking to have a performance impact and the results seem to agree.
That's nice to see. I'd probably add --cpus_allowed=0 to it for better locality, and then run 10 tests back-to-back with each just to be sure. There will be some fluctuations, but that should be enough for me to feel comfortable.
1000K IOPS is pretty slow though, what are you running this on? Pretty sure my laptop does 10x that.
Signature · 1 line
Jens Axboe
Re: [PATCH v1 3/3] fio: suggest installing engine package when missing
In reply to Yigal KormanQuoted 35 lines · Yigal Korman
Quoted 20 lines · Jeff Moyer
Quoted 17 lines · Yigal Korman
Signed-off-by Yigal Korman <[email protected]>--- ioengines.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)ioengines.c +1
-0@@ -79,10 +79,16 @@ static struct ioengine_ops *find_ioengine(const char *name)static void *dlopen_external (struct thread_data *td,const char *engine) {char engine_path[PATH_MAX ]; +void *dlhandle;sprintf (engine_path,"%s/lib%s.so" ,FIO_EXT_ENG_DIR , engine);Quoted 13 lines
ioengines.c static struct ioengine_ops *find_ioengine(const char *name) · line 94
Quoted 10 lines
ioengines.c +6
-1- return dlopen(engine_path, RTLD_LAZY); + dlhandle =dlopen (engine_path,RTLD_LAZY ); +if (!dlhandle) +log_info ("Engine not available; Install the fio-engine-%s package\n" , + engine); + + return dlhandle; }#else #define dlopen_external (td, engine) (NULL)This assumes fio is part of a package, and that's not always (often?) the case. It may be that the engine simply wasn't built.
Quoted 6 lines
I agree.
This patch is more of a showcase of how to help package maintainers transition users to the new packaging model.
I will drop it from the next patchset version.
This patch might have made more sense if I had implemented a whitelist of engines that were compiled dynamically.
I'd say keep it, but make it a bit more generic so it applies to self built installs too.
"IO Engine %s not available. Either the engine name is invalid, or you need
to Install the fio-engine-%s package, or build fio with the necessary libraries available."
Something like that.
Signature · 1 line
Jens Axboe
Re: [PATCH v1 2/3] configure: new --dynamic-libengines build option
In reply to Jens AxboeQuoted 81 lines · Jens Axboe
Quoted 73 lines · Yigal Korman
Quoted 11 lines · Jens Axboe
Quoted 5 lines · Yigal Korman
When enabled, some of the more dependency-heavy internal engines are converted to "plugin" engines, i.e. they are built into separate object files and are loaded by fio on demand.
This helps downstream distros package these engines separately and not force a long list of package dependencies from the base fio package.How does this impact the performance of the engine? It'd be interesting to run a test with something ala:
Quoted 8 lines
fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
with the current build, then apply these patches (and turn the null engine into an externally loadable engine, of course), and re-run the test case.
For what it's worth, I like the change in general, as dependencies do pile on. But I'd like to ensure that we're not taking a performance hit for something like this.
Great to hear.
Here are the results of the run you suggested:
current build (statically linked) -
[root@host fio]# ./fio.static --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3910MiB/s][r=1001k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=155: Tue Jun 30 06:55:19 2020
read: IOPS=1000k, BW=3906MiB/s (4095MB/s)(100GiB/26219msec)
bw ( MiB/s): min= 3786, max= 3967, per=100.00%, avg=3909.96,
stdev=38.59, samples=52
iops : min=969293, max=1015596, avg=1000951.42,
stdev=9879.80, samples=52cpu : usr=61.66%, sys=38.31%, ctx=103, majf=8, minf=5 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1Run status group 0 (all jobs):
READ: bw=3906MiB/s (4095MB/s), 3906MiB/s-3906MiB/s(4095MB/s-4095MB/s), io=100GiB (107GB), run=26219-26219msec
With patches applied[0] -
[root@host fio]# ./fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3905MiB/s][r=1000k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=158: Tue Jun 30 06:55:49 2020
read: IOPS=1006k, BW=3929MiB/s (4120MB/s)(100GiB/26060msec)
bw ( MiB/s): min= 3753, max= 3988, per=100.00%, avg=3933.86,
stdev=45.93, samples=52
iops : min=960962, max=1021038, avg=1007067.92,
stdev=11758.92, samples=52cpu : usr=62.14%, sys=37.81%, ctx=117, majf=8, minf=5 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1Quoted 6 lines
Run status group 0 (all jobs):
READ: bw=3929MiB/s (4120MB/s), 3929MiB/s-3929MiB/s(4120MB/s-4120MB/s), io=100GiB (107GB), run=26060-26060msec
I wasn't expecting dynamic linking to have a performance impact and the results seem to agree.
Quoted 7 lines
That's nice to see. I'd probably add --cpus_allowed=0 to it for better locality, and then run 10 tests back-to-back with each just to be sure. There will be some fluctuations, but that should be enough for me to feel comfortable.
1000K IOPS is pretty slow though, what are you running this on? Pretty sure my laptop does 10x that.
Ran the testing here, and nothing statistically significant.
Signature · 1 line
Jens Axboe
Re: [PATCH v1 2/3] configure: new --dynamic-libengines build option
Quoted 83 lines · Jens Axboe
Quoted 81 lines · Jens Axboe
Quoted 79 lines · Yigal Korman
Quoted 11 lines · Jens Axboe
Quoted 5 lines · Yigal Korman
When enabled, some of the more dependency-heavy internal engines are converted to "plugin" engines, i.e. they are built into separate object files and are loaded by fio on demand.
This helps downstream distros package these engines separately and not force a long list of package dependencies from the base fio package.How does this impact the performance of the engine? It'd be interesting to run a test with something ala:
Quoted 8 lines
fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
with the current build, then apply these patches (and turn the null engine into an externally loadable engine, of course), and re-run the test case.
For what it's worth, I like the change in general, as dependencies do pile on. But I'd like to ensure that we're not taking a performance hit for something like this.
Great to hear.
Here are the results of the run you suggested:
current build (statically linked) -
[root@host fio]# ./fio.static --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3910MiB/s][r=1001k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=155: Tue Jun 30 06:55:19 2020
read: IOPS=1000k, BW=3906MiB/s (4095MB/s)(100GiB/26219msec)
bw ( MiB/s): min= 3786, max= 3967, per=100.00%, avg=3909.96,
stdev=38.59, samples=52
iops : min=969293, max=1015596, avg=1000951.42,
stdev=9879.80, samples=52cpu : usr=61.66%, sys=38.31%, ctx=103, majf=8, minf=5 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1Run status group 0 (all jobs):
READ: bw=3906MiB/s (4095MB/s), 3906MiB/s-3906MiB/s(4095MB/s-4095MB/s), io=100GiB (107GB), run=26219-26219msec
With patches applied[0] -
[root@host fio]# ./fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3905MiB/s][r=1000k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=158: Tue Jun 30 06:55:49 2020
read: IOPS=1006k, BW=3929MiB/s (4120MB/s)(100GiB/26060msec)
bw ( MiB/s): min= 3753, max= 3988, per=100.00%, avg=3933.86,
stdev=45.93, samples=52
iops : min=960962, max=1021038, avg=1007067.92,
stdev=11758.92, samples=52cpu : usr=62.14%, sys=37.81%, ctx=117, majf=8, minf=5 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1Run status group 0 (all jobs):
READ: bw=3929MiB/s (4120MB/s), 3929MiB/s-3929MiB/s(4120MB/s-4120MB/s), io=100GiB (107GB), run=26060-26060msec
I wasn't expecting dynamic linking to have a performance impact and the results seem to agree.
Quoted 7 lines
Quoted 7 lines
That's nice to see. I'd probably add --cpus_allowed=0 to it for better locality, and then run 10 tests back-to-back with each just to be sure. There will be some fluctuations, but that should be enough for me to feel comfortable.
1000K IOPS is pretty slow though, what are you running this on? Pretty sure my laptop does 10x that.
Yeah, a tiny VM on my laptop for playing around with the package manager, not a good candidate for perf testing.
I re-ran as you suggested on the host (i5-6200U @ 2.30GHz), see results here[0].
Quoted 2 lines
Ran the testing here, and nothing statistically significant.
Yes, I got the same. Thanks!
Would you like a pull request for the patchset? (after I fix the last patch)
Regards,
Yigal
[0] https://gist.github.com/ykorman/da92200cd79b22f441b98a57ea28726c
Quoted 6 lines
--
Jens Axboe
Re: [PATCH v1 2/3] configure: new --dynamic-libengines build option
Quoted 97 lines · Yigal Korman
Quoted 83 lines · Jens Axboe
Quoted 81 lines · Jens Axboe
Quoted 79 lines · Yigal Korman
Quoted 11 lines · Jens Axboe
Quoted 5 lines · Yigal Korman
When enabled, some of the more dependency-heavy internal engines are converted to "plugin" engines, i.e. they are built into separate object files and are loaded by fio on demand.
This helps downstream distros package these engines separately and not force a long list of package dependencies from the base fio package.How does this impact the performance of the engine? It'd be interesting to run a test with something ala:
Quoted 8 lines
fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
with the current build, then apply these patches (and turn the null engine into an externally loadable engine, of course), and re-run the test case.
For what it's worth, I like the change in general, as dependencies do pile on. But I'd like to ensure that we're not taking a performance hit for something like this.
Great to hear.
Here are the results of the run you suggested:
current build (statically linked) -
[root@host fio]# ./fio.static --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3910MiB/s][r=1001k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=155: Tue Jun 30 06:55:19 2020
read: IOPS=1000k, BW=3906MiB/s (4095MB/s)(100GiB/26219msec)
bw ( MiB/s): min= 3786, max= 3967, per=100.00%, avg=3909.96,
stdev=38.59, samples=52
iops : min=969293, max=1015596, avg=1000951.42,
stdev=9879.80, samples=52cpu : usr=61.66%, sys=38.31%, ctx=103, majf=8, minf=5 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1Run status group 0 (all jobs):
READ: bw=3906MiB/s (4095MB/s), 3906MiB/s-3906MiB/s(4095MB/s-4095MB/s), io=100GiB (107GB), run=26219-26219msec
With patches applied[0] -
[root@host fio]# ./fio --name=test --ioengine=null --size=100g --rw=randread --norandommap --gtod_reduce=1
test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=null, iodepth=1
fio-3.20-70-g9888
Starting 1 process
Jobs: 1 (f=1): [r(1)][100.0%][r=3905MiB/s][r=1000k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=158: Tue Jun 30 06:55:49 2020
read: IOPS=1006k, BW=3929MiB/s (4120MB/s)(100GiB/26060msec)
bw ( MiB/s): min= 3753, max= 3988, per=100.00%, avg=3933.86,
stdev=45.93, samples=52
iops : min=960962, max=1021038, avg=1007067.92,
stdev=11758.92, samples=52cpu : usr=62.14%, sys=37.81%, ctx=117, majf=8, minf=5 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% submit : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% issued rwts: total=26214400,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1Run status group 0 (all jobs):
READ: bw=3929MiB/s (4120MB/s), 3929MiB/s-3929MiB/s(4120MB/s-4120MB/s), io=100GiB (107GB), run=26060-26060msec
I wasn't expecting dynamic linking to have a performance impact and the results seem to agree.
Quoted 7 lines
Quoted 7 lines
That's nice to see. I'd probably add --cpus_allowed=0 to it for better locality, and then run 10 tests back-to-back with each just to be sure. There will be some fluctuations, but that should be enough for me to feel comfortable.
1000K IOPS is pretty slow though, what are you running this on? Pretty sure my laptop does 10x that.
Yeah, a tiny VM on my laptop for playing around with the package manager, not a good candidate for perf testing.
I re-ran as you suggested on the host (i5-6200U @ 2.30GHz), see results here[0].Quoted 1 line
Quoted 6 lines
Quoted 1 line
Ran the testing here, and nothing statistically significant.
Yes, I got the same. Thanks!
Would you like a pull request for the patchset? (after I fix the last patch)
Either that, or just resend the patches, I'm pretty happy with either approach. GitHub pull requests I do manually anyway, so it's about the same amount of work. I tend to prefer patches as they are easier to review, I really don't like viewing patches on GH at all.
Signature · 1 line
Jens Axboe