Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Aug 2018 16:27:24 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r338205 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
Message-ID:  <201808221627.w7MGROx5065205@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Wed Aug 22 16:27:24 2018
New Revision: 338205
URL: https://svnweb.freebsd.org/changeset/base/338205

Log:
  Create separate taskqueue to call zfs_unlinked_drain().
  
  r334810 introduced zfs_unlinked_drain() dispatch to taskqueue on every
  deletion of a file with extended attributes.  Using system_taskq for that
  with its multiple threads in case of multiple files deletion caused all
  available CPU threads to uselessly spin on busy locks, completely blocking
  the system.
  
  Use of single dedicated taskqueue is the only easy solution I've found,
  while in would be great if we could specify that some task should be
  executed only once at a time, but never in parallel, while many tasks
  could use different threads same time.
  
  Sponsored by:	iXsystems, Inc.

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c	Wed Aug 22 15:55:23 2018	(r338204)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c	Wed Aug 22 16:27:24 2018	(r338205)
@@ -402,6 +402,10 @@ zfs_purgedir(znode_t *dzp)
 	return (skipped);
 }
 
+#if defined(__FreeBSD__)
+extern taskq_t *zfsvfs_taskq;
+#endif
+
 void
 zfs_rmnode(znode_t *zp)
 {
@@ -520,15 +524,17 @@ zfs_rmnode(znode_t *zp)
 
 	dmu_tx_commit(tx);
 
+#if defined(__FreeBSD__)
 	if (xattr_obj) {
 		/*
 		 * We're using the FreeBSD taskqueue API here instead of
 		 * the Solaris taskq API since the FreeBSD API allows for a
 		 * task to be enqueued multiple times but executed once.
 		 */
-		taskqueue_enqueue(system_taskq->tq_queue,
+		taskqueue_enqueue(zfsvfs_taskq->tq_queue,
 		    &zfsvfs->z_unlinked_drain_task);
 	}
+#endif
 }
 
 static uint64_t

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Wed Aug 22 15:55:23 2018	(r338204)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Wed Aug 22 16:27:24 2018	(r338205)
@@ -1130,6 +1130,8 @@ zfsvfs_init(zfsvfs_t *zfsvfs, objset_t *os)
 }
 
 #if defined(__FreeBSD__)
+taskq_t *zfsvfs_taskq;
+
 static void
 zfsvfs_task_unlinked_drain(void *context, int pending __unused)
 {
@@ -2185,9 +2187,9 @@ zfs_umount(vfs_t *vfsp, int fflag)
 	}
 #endif
 
-	while (taskqueue_cancel(system_taskq->tq_queue,
+	while (taskqueue_cancel(zfsvfs_taskq->tq_queue,
 	    &zfsvfs->z_unlinked_drain_task, NULL) != 0)
-		taskqueue_drain(system_taskq->tq_queue,
+		taskqueue_drain(zfsvfs_taskq->tq_queue,
 		    &zfsvfs->z_unlinked_drain_task);
 
 	VERIFY(zfsvfs_teardown(zfsvfs, B_TRUE) == 0);
@@ -2554,11 +2556,17 @@ zfs_init(void)
 	zfs_vnodes_adjust();
 
 	dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb);
+#if defined(__FreeBSD__)
+	zfsvfs_taskq = taskq_create("zfsvfs", 1, minclsyspri, 0, 0, 0);
+#endif
 }
 
 void
 zfs_fini(void)
 {
+#if defined(__FreeBSD__)
+	taskq_destroy(zfsvfs_taskq);
+#endif
 	zfsctl_fini();
 	zfs_znode_fini();
 	zfs_vnodes_adjust_back();



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201808221627.w7MGROx5065205>