Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/opencrypto make cryptoret() context softint to balance d...
details: https://anonhg.NetBSD.org/src/rev/1fbed7fce172
branches: trunk
changeset: 355193:1fbed7fce172
user: knakahara <knakahara%NetBSD.org@localhost>
date: Tue Jul 18 06:01:36 2017 +0000
description:
make cryptoret() context softint to balance dequeuing crypto_ret_q with enqueuing it.
diffstat:
sys/opencrypto/crypto.c | 88 +++++++++++++++++++++------------------------
sys/opencrypto/cryptodev.h | 19 ++++++++-
2 files changed, 58 insertions(+), 49 deletions(-)
diffs (296 lines):
diff -r ec213d82b116 -r 1fbed7fce172 sys/opencrypto/crypto.c
--- a/sys/opencrypto/crypto.c Tue Jul 18 04:01:04 2017 +0000
+++ b/sys/opencrypto/crypto.c Tue Jul 18 06:01:36 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: crypto.c,v 1.91 2017/06/26 05:34:48 knakahara Exp $ */
+/* $NetBSD: crypto.c,v 1.92 2017/07/18 06:01:36 knakahara Exp $ */
/* $FreeBSD: src/sys/opencrypto/crypto.c,v 1.4.2.5 2003/02/26 00:14:05 sam Exp $ */
/* $OpenBSD: crypto.c,v 1.41 2002/07/17 23:52:38 art Exp $ */
@@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.91 2017/06/26 05:34:48 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.92 2017/07/18 06:01:36 knakahara Exp $");
#include <sys/param.h>
#include <sys/reboot.h>
@@ -67,6 +67,7 @@
#include <sys/intr.h>
#include <sys/errno.h>
#include <sys/module.h>
+#include <sys/xcall.h>
#if defined(_KERNEL_OPT)
#include "opt_ocf.h"
@@ -77,7 +78,6 @@
static kmutex_t crypto_q_mtx;
static kmutex_t crypto_ret_q_mtx;
-static kcondvar_t cryptoret_cv;
/* below are kludges for residual code wrtitten to FreeBSD interfaces */
#define SWI_CRYPTO 17
@@ -105,6 +105,8 @@
static void *softintr_cookie;
static int crypto_exit_flag;
+static void *crypto_ret_si;
+
/*
* There are two queues for crypto requests; one for symmetric (e.g.
* cipher) operations and one for asymmetric (e.g. MOD) operations.
@@ -368,8 +370,7 @@
* This scheme is not intended for SMP machines.
*/
static void cryptointr(void); /* swi thread to dispatch ops */
-static void cryptoret(void); /* kernel thread for callbacks*/
-static struct lwp *cryptothread;
+static void cryptoret_softint(void *); /* kernel thread for callbacks*/
static int crypto_destroy(bool);
static int crypto_invoke(struct cryptop *crp, int hint);
static int crypto_kinvoke(struct cryptkop *krp, int hint);
@@ -391,12 +392,10 @@
static int
crypto_init0(void)
{
- int error;
mutex_init(&crypto_drv_mtx, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&crypto_q_mtx, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&crypto_ret_q_mtx, MUTEX_DEFAULT, IPL_NET);
- cv_init(&cryptoret_cv, "crypto_w");
pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0,
0, "cryptop", NULL, IPL_NET);
pool_init(&cryptodesc_pool, sizeof(struct cryptodesc), 0, 0,
@@ -413,11 +412,15 @@
crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
softintr_cookie = register_swi(SWI_CRYPTO, cryptointr);
- error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,
- (void (*)(void *))cryptoret, NULL, &cryptothread, "cryptoret");
- if (error) {
- printf("crypto_init: cannot start cryptoret thread; error %d",
- error);
+ if (softintr_cookie == NULL) {
+ printf("crypto_init: cannot establish request queue handler\n");
+ return crypto_destroy(false);
+ }
+
+ crypto_ret_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE|SOFTINT_RCPU,
+ &cryptoret_softint, NULL);
+ if (crypto_ret_si == NULL) {
+ printf("crypto_init: cannot establish ret queue handler\n");
return crypto_destroy(false);
}
@@ -441,6 +444,7 @@
if (exit_kthread) {
struct cryptocap *cap = NULL;
+ uint64_t where;
/* if we have any in-progress requests, don't unload */
mutex_enter(&crypto_q_mtx);
@@ -468,20 +472,25 @@
* prohibit touch crypto_drivers[] and each element after here.
*/
+ /*
+ * Ensure cryptoret_softint() is never scheduled and then wait
+ * for last softint_execute().
+ */
mutex_spin_enter(&crypto_ret_q_mtx);
- /* kick the cryptoret thread and wait for it to exit */
crypto_exit_flag = 1;
- cv_signal(&cryptoret_cv);
-
- while (crypto_exit_flag != 0)
- cv_wait(&cryptoret_cv, &crypto_ret_q_mtx);
mutex_spin_exit(&crypto_ret_q_mtx);
+ where = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL);
+ xc_wait(where);
}
if (sysctl_opencrypto_clog != NULL)
sysctl_teardown(&sysctl_opencrypto_clog);
- unregister_swi(SWI_CRYPTO, cryptointr);
+ if (crypto_ret_si != NULL)
+ softint_disestablish(crypto_ret_si);
+
+ if (softintr_cookie != NULL)
+ unregister_swi(SWI_CRYPTO, cryptointr);
mutex_enter(&crypto_drv_mtx);
if (crypto_drivers != NULL)
@@ -492,8 +501,6 @@
pool_destroy(&cryptodesc_pool);
pool_destroy(&cryptkop_pool);
- cv_destroy(&cryptoret_cv);
-
mutex_destroy(&crypto_ret_q_mtx);
mutex_destroy(&crypto_q_mtx);
mutex_destroy(&crypto_drv_mtx);
@@ -1278,6 +1285,7 @@
process = cap->cc_kprocess;
arg = cap->cc_karg;
krp->krp_hid = hid;
+ krp->reqcpu = curcpu();
crypto_driver_unlock(cap);
error = (*process)(arg, krp, hint);
} else {
@@ -1346,6 +1354,7 @@
process = cap->cc_process;
arg = cap->cc_arg;
+ crp->reqcpu = curcpu();
/*
* Invoke the driver to process the request.
@@ -1546,7 +1555,7 @@
* If crp->crp_flags & CRYPTO_F_USER and the used
* encryption driver does all the processing in
* the same context, we can skip enqueueing crp_ret_q
- * and cv_signal(&cryptoret_cv).
+ * and softint_schedule(crypto_ret_si).
*/
DPRINTF("lid[%u]: crp %p CRYPTO_F_USER\n",
CRYPTO_SESID2LID(crp->crp_sid), crp);
@@ -1562,11 +1571,11 @@
crp->crp_flags |= CRYPTO_F_ONRETQ;
TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
CRYPTO_Q_INC(crp_ret_q);
- if (wasempty) {
+ if (wasempty && crypto_exit_flag == 0) {
DPRINTF("lid[%u]: waking cryptoret, "
"crp %p hit empty queue\n.",
CRYPTO_SESID2LID(crp->crp_sid), crp);
- cv_signal(&cryptoret_cv);
+ softint_schedule_cpu(crypto_ret_si, crp->reqcpu);
}
mutex_spin_exit(&crypto_ret_q_mtx);
}
@@ -1603,8 +1612,8 @@
krp->krp_flags |= CRYPTO_F_ONRETQ;
TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
CRYPTO_Q_INC(crp_ret_kq);
- if (wasempty)
- cv_signal(&cryptoret_cv);
+ if (wasempty && crypto_exit_flag == 0)
+ softint_schedule_cpu(crypto_ret_si, krp->reqcpu);
mutex_spin_exit(&crypto_ret_q_mtx);
}
}
@@ -1791,16 +1800,17 @@
}
/*
- * Kernel thread to do callbacks.
+ * softint handler to do callbacks.
*/
static void
-cryptoret(void)
+cryptoret_softint(void *arg __unused)
{
- struct cryptop *crp;
- struct cryptkop *krp;
mutex_spin_enter(&crypto_ret_q_mtx);
for (;;) {
+ struct cryptop *crp;
+ struct cryptkop *krp;
+
crp = TAILQ_FIRST(&crp_ret_q);
if (crp != NULL) {
TAILQ_REMOVE(&crp_ret_q, crp, crp_next);
@@ -1815,25 +1825,10 @@
}
/* drop before calling any callbacks. */
- if (crp == NULL && krp == NULL) {
-
- /* Check for the exit condition. */
- if (crypto_exit_flag != 0) {
-
- /* Time to die. */
- crypto_exit_flag = 0;
- cv_broadcast(&cryptoret_cv);
- mutex_spin_exit(&crypto_ret_q_mtx);
- kthread_exit(0);
- }
-
- cryptostats.cs_rets++;
- cv_wait(&cryptoret_cv, &crypto_ret_q_mtx);
- continue;
- }
+ if (crp == NULL && krp == NULL)
+ break;
mutex_spin_exit(&crypto_ret_q_mtx);
-
if (crp != NULL) {
#ifdef CRYPTO_TIMING
if (crypto_timing) {
@@ -1857,6 +1852,7 @@
mutex_spin_enter(&crypto_ret_q_mtx);
}
+ mutex_spin_exit(&crypto_ret_q_mtx);
}
/* NetBSD module interface */
diff -r ec213d82b116 -r 1fbed7fce172 sys/opencrypto/cryptodev.h
--- a/sys/opencrypto/cryptodev.h Tue Jul 18 04:01:04 2017 +0000
+++ b/sys/opencrypto/cryptodev.h Tue Jul 18 06:01:36 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cryptodev.h,v 1.37 2017/06/15 12:41:18 knakahara Exp $ */
+/* $NetBSD: cryptodev.h,v 1.38 2017/07/18 06:01:36 knakahara Exp $ */
/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.2.2.6 2003/07/02 17:04:50 sam Exp $ */
/* $OpenBSD: cryptodev.h,v 1.33 2002/07/17 23:52:39 art Exp $ */
@@ -483,7 +483,11 @@
void * crp_opaque; /* Opaque pointer, passed along */
struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
- int (*crp_callback)(struct cryptop *); /* Callback function */
+ int (*crp_callback)(struct cryptop *); /*
+ * Callback function.
+ * That must not sleep as it is
+ * called in softint context.
+ */
void * crp_mac;
@@ -504,6 +508,10 @@
struct iovec iovec[1];
struct uio uio;
uint32_t magic;
+ struct cpu_info *reqcpu; /*
+ * save requested CPU to do cryptoret
+ * softint in the same CPU.
+ */
};
#define CRYPTO_BUF_CONTIG 0x0
@@ -530,12 +538,17 @@
u_short krp_oparams; /* # of output parameters */
u_int32_t krp_hid;
struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
- int (*krp_callback)(struct cryptkop *);
+ int (*krp_callback)(struct cryptkop *); /*
+ * Callback function.
+ * That must not sleep as it is
+ * called in softint context.
+ */
int krp_flags; /* same values as crp_flags */
int krp_devflags; /* same values as crp_devflags */
kcondvar_t krp_cv;
struct fcrypt *fcrp;
struct crparam crk_param[CRK_MAXPARAM];
+ struct cpu_info *reqcpu;
};
/* Crypto capabilities structure */
Home |
Main Index |
Thread Index |
Old Index