From 57ddcda1647daac93057dd520a9dc5187c643264 Mon Sep 17 00:00:00 2001 From: Chunwei Chen Date: Wed, 30 Nov 2016 13:56:50 -0800 Subject: [PATCH] Use system_delay_taskq for long delay tasks Use it for spa_deadman, zpl_posix_acl_free, snapentry_expire. This free system_taskq from the above long delay tasks, and allow us to do taskq_wait_outstanding on system_taskq without being blocked forever, making system_taskq more generic and useful. Signed-off-by: Chunwei Chen --- include/sys/zfs_context.h | 1 + lib/libzpool/taskq.c | 5 +++++ module/zfs/spa.c | 8 ++++---- module/zfs/spa_misc.c | 2 +- module/zfs/zfs_ctldir.c | 14 ++------------ module/zfs/zfs_vfsops.c | 1 + module/zfs/zpl_xattr.c | 8 ++++---- 7 files changed, 18 insertions(+), 21 deletions(-) diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index ed0a97c452..a1abe20da6 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -498,6 +498,7 @@ typedef struct taskq { #define TASKQID_INVALID ((taskqid_t)0) extern taskq_t *system_taskq; +extern taskq_t *system_delay_taskq; extern taskq_t *taskq_create(const char *, int, pri_t, int, int, uint_t); #define taskq_create_proc(a, b, c, d, e, p, f) \ diff --git a/lib/libzpool/taskq.c b/lib/libzpool/taskq.c index c1f87e173d..791d509819 100644 --- a/lib/libzpool/taskq.c +++ b/lib/libzpool/taskq.c @@ -32,6 +32,7 @@ int taskq_now; taskq_t *system_taskq; +taskq_t *system_delay_taskq; #define TASKQ_ACTIVE 0x00010000 @@ -353,6 +354,8 @@ system_taskq_init(void) { system_taskq = taskq_create("system_taskq", 64, maxclsyspri, 4, 512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE); + system_delay_taskq = taskq_create("delay_taskq", 4, maxclsyspri, 4, + 512, TASKQ_DYNAMIC | TASKQ_PREPOPULATE); } void @@ -360,4 +363,6 @@ system_taskq_fini(void) { taskq_destroy(system_taskq); system_taskq = NULL; /* defensive */ + taskq_destroy(system_delay_taskq); + system_delay_taskq = NULL; } diff --git a/module/zfs/spa.c b/module/zfs/spa.c index 05e15a2e6d..9f652dc32d 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -1208,7 +1208,7 @@ spa_deactivate(spa_t *spa) list_destroy(&spa->spa_evicting_os_list); list_destroy(&spa->spa_state_dirty_list); - taskq_cancel_id(system_taskq, spa->spa_deadman_tqid); + taskq_cancel_id(system_delay_taskq, spa->spa_deadman_tqid); for (t = 0; t < ZIO_TYPES; t++) { for (q = 0; q < ZIO_TASKQ_TYPES; q++) { @@ -6517,8 +6517,8 @@ spa_sync(spa_t *spa, uint64_t txg) tx = dmu_tx_create_assigned(dp, txg); spa->spa_sync_starttime = gethrtime(); - taskq_cancel_id(system_taskq, spa->spa_deadman_tqid); - spa->spa_deadman_tqid = taskq_dispatch_delay(system_taskq, + taskq_cancel_id(system_delay_taskq, spa->spa_deadman_tqid); + spa->spa_deadman_tqid = taskq_dispatch_delay(system_delay_taskq, spa_deadman, spa, TQ_SLEEP, ddi_get_lbolt() + NSEC_TO_TICK(spa->spa_deadman_synctime)); @@ -6706,7 +6706,7 @@ spa_sync(spa_t *spa, uint64_t txg) } dmu_tx_commit(tx); - taskq_cancel_id(system_taskq, spa->spa_deadman_tqid); + taskq_cancel_id(system_delay_taskq, spa->spa_deadman_tqid); spa->spa_deadman_tqid = 0; /* diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c index 6ec05214ef..42bd259802 100644 --- a/module/zfs/spa_misc.c +++ b/module/zfs/spa_misc.c @@ -530,7 +530,7 @@ spa_deadman(void *arg) if (zfs_deadman_enabled) vdev_deadman(spa->spa_root_vdev); - spa->spa_deadman_tqid = taskq_dispatch_delay(system_taskq, + spa->spa_deadman_tqid = taskq_dispatch_delay(system_delay_taskq, spa_deadman, spa, TQ_SLEEP, ddi_get_lbolt() + NSEC_TO_TICK(spa->spa_deadman_synctime)); } diff --git a/module/zfs/zfs_ctldir.c b/module/zfs/zfs_ctldir.c index c7a93edfc2..53674d9751 100644 --- a/module/zfs/zfs_ctldir.c +++ b/module/zfs/zfs_ctldir.c @@ -111,11 +111,6 @@ static krwlock_t zfs_snapshot_lock; int zfs_expire_snapshot = ZFSCTL_EXPIRE_SNAPSHOT; int zfs_admin_snapshot = 1; -/* - * Dedicated task queue for unmounting snapshots. - */ -static taskq_t *zfs_expire_taskq; - typedef struct { char *se_name; /* full snapshot name */ char *se_path; /* full mount path */ @@ -365,7 +360,7 @@ zfsctl_snapshot_unmount_cancel(zfs_snapentry_t *se) { ASSERT(RW_LOCK_HELD(&zfs_snapshot_lock)); - if (taskq_cancel_id(zfs_expire_taskq, se->se_taskqid) == 0) { + if (taskq_cancel_id(system_delay_taskq, se->se_taskqid) == 0) { se->se_taskqid = TASKQID_INVALID; zfsctl_snapshot_rele(se); } @@ -383,7 +378,7 @@ zfsctl_snapshot_unmount_delay_impl(zfs_snapentry_t *se, int delay) return; zfsctl_snapshot_hold(se); - se->se_taskqid = taskq_dispatch_delay(zfs_expire_taskq, + se->se_taskqid = taskq_dispatch_delay(system_delay_taskq, snapentry_expire, se, TQ_SLEEP, ddi_get_lbolt() + delay * HZ); } @@ -1257,9 +1252,6 @@ zfsctl_init(void) sizeof (zfs_snapentry_t), offsetof(zfs_snapentry_t, se_node_objsetid)); rw_init(&zfs_snapshot_lock, NULL, RW_DEFAULT, NULL); - - zfs_expire_taskq = taskq_create("z_unmount", 1, defclsyspri, - 1, 8, TASKQ_PREPOPULATE); } /* @@ -1269,8 +1261,6 @@ zfsctl_init(void) void zfsctl_fini(void) { - taskq_destroy(zfs_expire_taskq); - avl_destroy(&zfs_snapshots_by_name); avl_destroy(&zfs_snapshots_by_objsetid); rw_destroy(&zfs_snapshot_lock); diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 5417f24228..39e92ce219 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -1922,6 +1922,7 @@ zfs_fini(void) /* * we don't use outstanding because zpl_posix_acl_free might add more. */ + taskq_wait(system_delay_taskq); taskq_wait(system_taskq); unregister_filesystem(&zpl_fs_type); zfs_znode_fini(); diff --git a/module/zfs/zpl_xattr.c b/module/zfs/zpl_xattr.c index cec8708246..9ab27f1c20 100644 --- a/module/zfs/zpl_xattr.c +++ b/module/zfs/zpl_xattr.c @@ -1511,8 +1511,8 @@ zpl_posix_acl_free(void *arg) } if (refire) - taskq_dispatch_delay(system_taskq, zpl_posix_acl_free, NULL, - TQ_SLEEP, new_time); + taskq_dispatch_delay(system_delay_taskq, zpl_posix_acl_free, + NULL, TQ_SLEEP, new_time); while (freelist) { a = freelist; @@ -1537,7 +1537,7 @@ zpl_posix_acl_release_impl(struct posix_acl *acl) *prev = a; /* if it was empty before, schedule the free task */ if (prev == &acl_rel_head) - taskq_dispatch_delay(system_taskq, zpl_posix_acl_free, NULL, - TQ_SLEEP, ddi_get_lbolt() + ACL_REL_SCHED); + taskq_dispatch_delay(system_delay_taskq, zpl_posix_acl_free, + NULL, TQ_SLEEP, ddi_get_lbolt() + ACL_REL_SCHED); } #endif