Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 4 Nov 2019 13:30:37 +0000 (UTC)
From:      Andriy Gapon <avg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r354333 - in head/sys/cddl: compat/opensolaris/kern compat/opensolaris/sys contrib/opensolaris/uts/common/fs/zfs contrib/opensolaris/uts/common/fs/zfs/sys
Message-ID:  <201911041330.xA4DUbnB059737@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: avg
Date: Mon Nov  4 13:30:37 2019
New Revision: 354333
URL: https://svnweb.freebsd.org/changeset/base/354333

Log:
  zfs: enable SPA_PROCESS on the kernel side
  
  The purpose of this change is to group kernelthreads specific to a
  particular ZFS pool under a kernel process.  There can be many dozens of
  threads per pool.  This change improves observability of those threads.
  
  This change consists of several subchanges:
  1. illumos taskq_create_proc can now pass its process parameter to
  taskqueue.  Also, use zfsproc instead of NULL for taskq_create.  Caveat:
  zfsproc might not be initialized yet.  But in that case it is still NULL,
  so not worse than before.
  
  2. illumos sys/proc.h: kthread id is stored in t_did field, not t_tid.
  
  3. zfs: enable SPA_PROCESS on the kernel side.  The change is a bit hairy
  as newproc() is implemented privately to spa.c.  I couldn't think of a
  better way to populate process name than to poke inside the argument for
  the process routine.
  
  4. illumos thread_create: allow assigning thread to process other than
  zfsproc.
  
  5. zfs: expose spa_proc to other users, assign sync and quiesce threads
  to it.
  
  Pool-specific threads created using (relatively new) zthr mechanism are
  still assigned to the zfskern process rather than to a respective
  zpool-xxx process.  I am going to address this a bit later.
  
  Reviewed by:	no one
  MFC after:	5 weeks
  Relnotes:	perhaps
  Differential Revision: https://reviews.freebsd.org/D9720

Modified:
  head/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
  head/sys/cddl/compat/opensolaris/sys/proc.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c

Modified: head/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
==============================================================================
--- head/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c	Mon Nov  4 12:20:19 2019	(r354332)
+++ head/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c	Mon Nov  4 13:30:37 2019	(r354333)
@@ -62,9 +62,9 @@ system_taskq_fini(void *arg)
 }
 SYSUNINIT(system_taskq_fini, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_fini, NULL);
 
-taskq_t *
-taskq_create(const char *name, int nthreads, pri_t pri, int minalloc __unused,
-    int maxalloc __unused, uint_t flags)
+static taskq_t *
+taskq_create_impl(const char *name, int nthreads, pri_t pri, proc_t *proc,
+    uint_t flags)
 {
 	taskq_t *tq;
 
@@ -74,17 +74,24 @@ taskq_create(const char *name, int nthreads, pri_t pri
 	tq = kmem_alloc(sizeof(*tq), KM_SLEEP);
 	tq->tq_queue = taskqueue_create(name, M_WAITOK, taskqueue_thread_enqueue,
 	    &tq->tq_queue);
-	(void) taskqueue_start_threads(&tq->tq_queue, nthreads, pri, "%s", name);
+	(void) taskqueue_start_threads_in_proc(&tq->tq_queue, nthreads, pri,
+	    proc, "%s", name);
 
 	return ((taskq_t *)tq);
 }
 
 taskq_t *
-taskq_create_proc(const char *name, int nthreads, pri_t pri, int minalloc,
-    int maxalloc, proc_t *proc __unused, uint_t flags)
+taskq_create(const char *name, int nthreads, pri_t pri, int minalloc __unused,
+    int maxalloc __unused, uint_t flags)
 {
+	return (taskq_create_impl(name, nthreads, pri, zfsproc, flags));
+}
 
-	return (taskq_create(name, nthreads, pri, minalloc, maxalloc, flags));
+taskq_t *
+taskq_create_proc(const char *name, int nthreads, pri_t pri, int minalloc,
+    int maxalloc, proc_t *proc, uint_t flags)
+{
+	return (taskq_create_impl(name, nthreads, pri, proc, flags));
 }
 
 void

Modified: head/sys/cddl/compat/opensolaris/sys/proc.h
==============================================================================
--- head/sys/cddl/compat/opensolaris/sys/proc.h	Mon Nov  4 12:20:19 2019	(r354332)
+++ head/sys/cddl/compat/opensolaris/sys/proc.h	Mon Nov  4 13:30:37 2019	(r354333)
@@ -47,12 +47,13 @@
 #define	maxclsyspri	PVM
 #define	max_ncpus	(mp_maxid + 1)
 #define	boot_max_ncpus	(mp_maxid + 1)
+#define	syscid		1
 
 #define	TS_RUN	0
 
 #define	p0	proc0
 
-#define	t_tid	td_tid
+#define	t_did	td_tid
 
 typedef	short		pri_t;
 typedef	struct thread	_kthread;
@@ -67,6 +68,7 @@ do_thread_create(caddr_t stk, size_t stksize, void (*p
     size_t len, proc_t *pp, int state, pri_t pri)
 {
 	kthread_t *td = NULL;
+	proc_t **ppp;
 	int error;
 
 	/*
@@ -75,9 +77,13 @@ do_thread_create(caddr_t stk, size_t stksize, void (*p
 	ASSERT(stk == NULL);
 	ASSERT(len == 0);
 	ASSERT(state == TS_RUN);
-	ASSERT(pp == &p0);
+	ASSERT(pp != NULL);
 
-	error = kproc_kthread_add(proc, arg, &zfsproc, &td, RFSTOPPED,
+	if (pp == &p0)
+		ppp = &zfsproc;
+	else
+		ppp = &pp;
+	error = kproc_kthread_add(proc, arg, ppp, &td, RFSTOPPED,
 	    stksize / PAGE_SIZE, "zfskern", "solthread %p", proc);
 	if (error == 0) {
 		thread_lock(td);

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c	Mon Nov  4 12:20:19 2019	(r354332)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c	Mon Nov  4 13:30:37 2019	(r354333)
@@ -176,7 +176,11 @@ boolean_t	zio_taskq_sysdc = B_TRUE;	/* use SDC schedul
 uint_t		zio_taskq_basedc = 80;		/* base duty cycle */
 #endif
 
+#ifdef _KERNEL
+#define SPA_PROCESS
+#endif
 boolean_t	spa_create_process = B_TRUE;	/* no process ==> no sysdc */
+
 extern int	zfs_sync_pass_deferred_free;
 
 /*
@@ -1090,23 +1094,49 @@ spa_create_zio_taskqs(spa_t *spa)
 	}
 }
 
-#ifdef _KERNEL
 #ifdef SPA_PROCESS
+static int
+newproc(void (*pc)(void *), void *arg, id_t cid, int pri,
+    void **ct, pid_t pid)
+{
+	va_list ap;
+	spa_t *spa = (spa_t *)arg;	/* XXX */
+	struct proc *newp;
+	struct thread *td;
+	int error;
+
+	ASSERT(ct == NULL);
+	ASSERT(pid == 0);
+	ASSERT(cid == syscid);
+
+	error = kproc_create(pc, arg, &newp, 0, 0, "zpool-%s", spa->spa_name);
+	if (error != 0)
+		return (error);
+	td = FIRST_THREAD_IN_PROC(newp);
+	thread_lock(td);
+	sched_prio(td, pri);
+	thread_unlock(td);
+	return (0);
+}
+
 static void
 spa_thread(void *arg)
 {
 	callb_cpr_t cprinfo;
 
 	spa_t *spa = arg;
+#ifdef illumos
 	user_t *pu = PTOU(curproc);
-
+#endif
 	CALLB_CPR_INIT(&cprinfo, &spa->spa_proc_lock, callb_generic_cpr,
 	    spa->spa_name);
 
 	ASSERT(curproc != &p0);
+#ifdef illumos
 	(void) snprintf(pu->u_psargs, sizeof (pu->u_psargs),
 	    "zpool-%s", spa->spa_name);
 	(void) strlcpy(pu->u_comm, pu->u_psargs, sizeof (pu->u_comm));
+#endif
 
 #ifdef PSRSET_BIND
 	/* bind this thread to the requested psrset */
@@ -1160,11 +1190,14 @@ spa_thread(void *arg)
 	cv_broadcast(&spa->spa_proc_cv);
 	CALLB_CPR_EXIT(&cprinfo);	/* drops spa_proc_lock */
 
+#ifdef illumos
 	mutex_enter(&curproc->p_lock);
 	lwp_exit();
+#else
+	kthread_exit();
+#endif
 }
 #endif	/* SPA_PROCESS */
-#endif
 
 /*
  * Activate an uninitialized pool.
@@ -1211,7 +1244,9 @@ spa_activate(spa_t *spa, int mode)
 	mutex_exit(&spa->spa_proc_lock);
 
 	/* If we didn't create a process, we need to create our taskqs. */
+#ifndef SPA_PROCESS
 	ASSERT(spa->spa_proc == &p0);
+#endif	/* SPA_PROCESS */
 	if (spa->spa_proc == &p0) {
 		spa_create_zio_taskqs(spa);
 	}
@@ -1315,6 +1350,7 @@ spa_deactivate(spa_t *spa)
 	mutex_exit(&spa->spa_proc_lock);
 
 #ifdef SPA_PROCESS
+#ifdef illumos
 	/*
 	 * We want to make sure spa_thread() has actually exited the ZFS
 	 * module, so that the module can't be unloaded out from underneath
@@ -1324,6 +1360,7 @@ spa_deactivate(spa_t *spa)
 		thread_join(spa->spa_did);
 		spa->spa_did = 0;
 	}
+#endif
 #endif	/* SPA_PROCESS */
 }
 

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c	Mon Nov  4 12:20:19 2019	(r354332)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c	Mon Nov  4 13:30:37 2019	(r354333)
@@ -1935,6 +1935,12 @@ spa_deadman_synctime(spa_t *spa)
 	return (spa->spa_deadman_synctime);
 }
 
+struct proc *
+spa_proc(spa_t *spa)
+{
+	return (spa->spa_proc);
+}
+
 uint64_t
 dva_get_dsize_sync(spa_t *spa, const dva_t *dva)
 {

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h	Mon Nov  4 12:20:19 2019	(r354332)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/spa.h	Mon Nov  4 13:30:37 2019	(r354333)
@@ -833,6 +833,7 @@ extern uint64_t spa_bootfs(spa_t *spa);
 extern uint64_t spa_delegation(spa_t *spa);
 extern objset_t *spa_meta_objset(spa_t *spa);
 extern uint64_t spa_deadman_synctime(spa_t *spa);
+extern struct proc *spa_proc(spa_t *spa);
 extern uint64_t spa_dirty_data(spa_t *spa);
 
 /* Miscellaneous support routines */

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c	Mon Nov  4 12:20:19 2019	(r354332)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c	Mon Nov  4 13:30:37 2019	(r354333)
@@ -209,7 +209,7 @@ txg_sync_start(dsl_pool_t *dp)
 	tx->tx_threads = 2;
 
 	tx->tx_quiesce_thread = thread_create(NULL, 0, txg_quiesce_thread,
-	    dp, 0, &p0, TS_RUN, minclsyspri);
+	    dp, 0, spa_proc(dp->dp_spa), TS_RUN, minclsyspri);
 
 	/*
 	 * The sync thread can need a larger-than-default stack size on
@@ -217,7 +217,7 @@ txg_sync_start(dsl_pool_t *dp)
 	 * scrub_visitbp() recursion.
 	 */
 	tx->tx_sync_thread = thread_create(NULL, 32<<10, txg_sync_thread,
-	    dp, 0, &p0, TS_RUN, minclsyspri);
+	    dp, 0, spa_proc(dp->dp_spa), TS_RUN, minclsyspri);
 
 	mutex_exit(&tx->tx_sync_lock);
 }



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