summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChunwei Chen <[email protected]>2016-11-30 13:56:50 -0800
committerChunwei Chen <[email protected]>2016-12-01 14:52:48 -0800
commit57ddcda1647daac93057dd520a9dc5187c643264 (patch)
treed68cf5f2f862e7c48db89c4ef515798f37219b2b
parent616fa7c02b0cc373f011998f56ed53bb37742d13 (diff)
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 <[email protected]>
-rw-r--r--include/sys/zfs_context.h1
-rw-r--r--lib/libzpool/taskq.c5
-rw-r--r--module/zfs/spa.c8
-rw-r--r--module/zfs/spa_misc.c2
-rw-r--r--module/zfs/zfs_ctldir.c14
-rw-r--r--module/zfs/zfs_vfsops.c1
-rw-r--r--module/zfs/zpl_xattr.c8
7 files changed, 18 insertions, 21 deletions
diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h
index ed0a97c45..a1abe20da 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 c1f87e173..791d50981 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 05e15a2e6..9f652dc32 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 6ec05214e..42bd25980 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 c7a93edfc..53674d975 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 5417f2422..39e92ce21 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 cec870824..9ab27f1c2 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