From 2dae45ea8e8911f85c4b5a9bc9580b5edfed8a4c Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 30 May 2019 14:57:00 +0200 Subject: [PATCH] UBUNTU: SAUCE: (noup) Update zfs to 0.7.5-1ubuntu16.6 BugLink: https://bugs.launchpad.net/bugs/1772412 Sync from zfs 0.7.5-1ubuntu16.6 that contains a backport of upstream zfs commit 77d8a0f1a4d0b2f59cee63088f7987cb38e66538 ("Fix hung z_zvol tasks during 'zfs receive'"). Adds a dedicated, per-pool, prefetch taskq to prevent the traverse code from monopolizing the global (and limited) system_taskq by inappropriately scheduling long running tasks on it. This fixes z_zvol hung tasks when performing large I/O operations, for example when performing huge ZFS send/receives (on slow media). Signed-off-by: Colin Ian King Acked-by: Thadeu Lima de Souza Cascardo Acked-by: Andrea Righi Acked-by: Connor Kuehl Signed-off-by: Kleber Sacilotto de Souza --- zfs/META | 2 +- zfs/include/sys/spa_impl.h | 1 + zfs/module/zfs/dmu_traverse.c | 3 ++- zfs/module/zfs/spa.c | 13 +++++++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/zfs/META b/zfs/META index 7e598b52dca6..08238596120a 100644 --- a/zfs/META +++ b/zfs/META @@ -2,7 +2,7 @@ Meta: 1 Name: zfs Branch: 1.0 Version: 0.7.5 -Release: 1ubuntu16.5 +Release: 1ubuntu16.6 Release-Tags: relext License: CDDL Author: OpenZFS on Linux diff --git a/zfs/include/sys/spa_impl.h b/zfs/include/sys/spa_impl.h index 06de244218f3..34b11992242c 100644 --- a/zfs/include/sys/spa_impl.h +++ b/zfs/include/sys/spa_impl.h @@ -275,6 +275,7 @@ struct spa { spa_stats_t spa_stats; /* assorted spa statistics */ hrtime_t spa_ccw_fail_time; /* Conf cache write fail time */ taskq_t *spa_zvol_taskq; /* Taskq for minor management */ + taskq_t *spa_prefetch_taskq; /* Taskq for prefetch threads */ uint64_t spa_multihost; /* multihost aware (mmp) */ mmp_thread_t spa_mmp; /* multihost mmp thread */ diff --git a/zfs/module/zfs/dmu_traverse.c b/zfs/module/zfs/dmu_traverse.c index 62f770e9fc22..c9171eeff59f 100644 --- a/zfs/module/zfs/dmu_traverse.c +++ b/zfs/module/zfs/dmu_traverse.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -626,7 +627,7 @@ traverse_impl(spa_t *spa, dsl_dataset_t *ds, uint64_t objset, blkptr_t *rootbp, } if (!(flags & TRAVERSE_PREFETCH_DATA) || - taskq_dispatch(system_taskq, traverse_prefetch_thread, + taskq_dispatch(spa->spa_prefetch_taskq, traverse_prefetch_thread, td, TQ_NOQUEUE) == TASKQID_INVALID) pd->pd_exited = B_TRUE; diff --git a/zfs/module/zfs/spa.c b/zfs/module/zfs/spa.c index 00587d8e88d1..b777afc60242 100644 --- a/zfs/module/zfs/spa.c +++ b/zfs/module/zfs/spa.c @@ -1182,6 +1182,14 @@ spa_activate(spa_t *spa, int mode) spa->spa_zvol_taskq = taskq_create("z_zvol", 1, defclsyspri, 1, INT_MAX, 0); + /* + * Taskq dedicated to prefetcher threads: this is used to prevent the + * pool traverse code from monopolizing the global (and limited) + * system_taskq by inappropriately scheduling long running tasks on it. + */ + spa->spa_prefetch_taskq = taskq_create("z_prefetch", boot_ncpus, + defclsyspri, 1, INT_MAX, TASKQ_DYNAMIC); + /* * The taskq to upgrade datasets in this pool. Currently used by * feature SPA_FEATURE_USEROBJ_ACCOUNTING. @@ -1211,6 +1219,11 @@ spa_deactivate(spa_t *spa) spa->spa_zvol_taskq = NULL; } + if (spa->spa_prefetch_taskq) { + taskq_destroy(spa->spa_prefetch_taskq); + spa->spa_prefetch_taskq = NULL; + } + if (spa->spa_upgrade_taskq) { taskq_destroy(spa->spa_upgrade_taskq); spa->spa_upgrade_taskq = NULL; -- 2.39.2