Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern Teach threadpool(9) to use percpu_create, mostly.
details: https://anonhg.NetBSD.org/src/rev/dd68526eb949
branches: trunk
changeset: 969157:dd68526eb949
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Feb 09 22:57:26 2020 +0000
description:
Teach threadpool(9) to use percpu_create, mostly.
diffstat:
sys/kern/kern_threadpool.c | 114 ++++++++++++++++++++++----------------------
1 files changed, 57 insertions(+), 57 deletions(-)
diffs (161 lines):
diff -r 7f84571d1ad6 -r dd68526eb949 sys/kern/kern_threadpool.c
--- a/sys/kern/kern_threadpool.c Sun Feb 09 21:15:03 2020 +0000
+++ b/sys/kern/kern_threadpool.c Sun Feb 09 22:57:26 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_threadpool.c,v 1.15 2019/01/17 10:18:52 hannken Exp $ */
+/* $NetBSD: kern_threadpool.c,v 1.16 2020/02/09 22:57:26 riastradh Exp $ */
/*-
* Copyright (c) 2014, 2018 The NetBSD Foundation, Inc.
@@ -81,7 +81,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_threadpool.c,v 1.15 2019/01/17 10:18:52 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_threadpool.c,v 1.16 2020/02/09 22:57:26 riastradh Exp $");
#include <sys/types.h>
#include <sys/param.h>
@@ -132,6 +132,9 @@
static int threadpool_percpu_create(struct threadpool_percpu **, pri_t);
static void threadpool_percpu_destroy(struct threadpool_percpu *);
+static void threadpool_percpu_init(void *, void *, struct cpu_info *);
+static void threadpool_percpu_ok(void *, void *, struct cpu_info *);
+static void threadpool_percpu_fini(void *, void *, struct cpu_info *);
static threadpool_job_fn_t threadpool_job_dead;
@@ -576,80 +579,77 @@
threadpool_percpu_create(struct threadpool_percpu **pool_percpup, pri_t pri)
{
struct threadpool_percpu *pool_percpu;
- struct cpu_info *ci;
- CPU_INFO_ITERATOR cii;
- unsigned int i, j;
- int error;
+ bool ok = true;
pool_percpu = kmem_zalloc(sizeof(*pool_percpu), KM_SLEEP);
- if (pool_percpu == NULL) {
- error = ENOMEM;
- goto fail0;
- }
pool_percpu->tpp_pri = pri;
-
- pool_percpu->tpp_percpu = percpu_alloc(sizeof(struct threadpool *));
- if (pool_percpu->tpp_percpu == NULL) {
- error = ENOMEM;
- goto fail1;
- }
+ pool_percpu->tpp_percpu = percpu_create(sizeof(struct threadpool *),
+ threadpool_percpu_init, threadpool_percpu_fini,
+ (void *)(intptr_t)pri);
- for (i = 0, CPU_INFO_FOREACH(cii, ci), i++) {
- struct threadpool *pool;
-
- pool = kmem_zalloc(sizeof(*pool), KM_SLEEP);
- error = threadpool_create(pool, ci, pri);
- if (error) {
- kmem_free(pool, sizeof(*pool));
- goto fail2;
- }
- percpu_traverse_enter();
- struct threadpool **const poolp =
- percpu_getptr_remote(pool_percpu->tpp_percpu, ci);
- *poolp = pool;
- percpu_traverse_exit();
- }
+ /*
+ * Verify that all of the CPUs were initialized.
+ *
+ * XXX What to do if we add CPU hotplug?
+ */
+ percpu_foreach(pool_percpu->tpp_percpu, &threadpool_percpu_ok, &ok);
+ if (!ok)
+ goto fail;
/* Success! */
*pool_percpup = (struct threadpool_percpu *)pool_percpu;
return 0;
-fail2: for (j = 0, CPU_INFO_FOREACH(cii, ci), j++) {
- if (i <= j)
- break;
- percpu_traverse_enter();
- struct threadpool **const poolp =
- percpu_getptr_remote(pool_percpu->tpp_percpu, ci);
- struct threadpool *const pool = *poolp;
- percpu_traverse_exit();
- threadpool_destroy(pool);
- kmem_free(pool, sizeof(*pool));
- }
- percpu_free(pool_percpu->tpp_percpu, sizeof(struct taskthread_pool *));
-fail1: kmem_free(pool_percpu, sizeof(*pool_percpu));
-fail0: return error;
+fail: percpu_free(pool_percpu->tpp_percpu, sizeof(struct threadpool *));
+ kmem_free(pool_percpu, sizeof(*pool_percpu));
+ return ENOMEM;
}
static void
threadpool_percpu_destroy(struct threadpool_percpu *pool_percpu)
{
- struct cpu_info *ci;
- CPU_INFO_ITERATOR cii;
-
- for (CPU_INFO_FOREACH(cii, ci)) {
- percpu_traverse_enter();
- struct threadpool **const poolp =
- percpu_getptr_remote(pool_percpu->tpp_percpu, ci);
- struct threadpool *const pool = *poolp;
- percpu_traverse_exit();
- threadpool_destroy(pool);
- kmem_free(pool, sizeof(*pool));
- }
percpu_free(pool_percpu->tpp_percpu, sizeof(struct threadpool *));
kmem_free(pool_percpu, sizeof(*pool_percpu));
}
+static void
+threadpool_percpu_init(void *vpoolp, void *vpri, struct cpu_info *ci)
+{
+ struct threadpool **const poolp = vpoolp;
+ pri_t pri = (intptr_t)(void *)vpri;
+ int error;
+
+ *poolp = kmem_zalloc(sizeof(**poolp), KM_SLEEP);
+ error = threadpool_create(*poolp, ci, pri);
+ if (error) {
+ KASSERT(error == ENOMEM);
+ kmem_free(*poolp, sizeof(**poolp));
+ *poolp = NULL;
+ }
+}
+
+static void
+threadpool_percpu_ok(void *vpoolp, void *vokp, struct cpu_info *ci)
+{
+ struct threadpool **const poolp = vpoolp;
+ bool *okp = vokp;
+
+ if (*poolp == NULL)
+ atomic_store_relaxed(okp, false);
+}
+
+static void
+threadpool_percpu_fini(void *vpoolp, void *vprip, struct cpu_info *ci)
+{
+ struct threadpool **const poolp = vpoolp;
+
+ if (*poolp == NULL) /* initialization failed */
+ return;
+ threadpool_destroy(*poolp);
+ kmem_free(*poolp, sizeof(**poolp));
+}
+
/* Thread pool jobs */
void __printflike(4,5)
Home |
Main Index |
Thread Index |
Old Index