Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/opencrypto make crp_{, k}q percpu to scale crypto_dispatc...
details: https://anonhg.NetBSD.org/src/rev/5c4eb3a11f14
branches: trunk
changeset: 355334:5c4eb3a11f14
user: knakahara <knakahara%NetBSD.org@localhost>
date: Wed Jul 26 06:40:42 2017 +0000
description:
make crp_{,k}q percpu to scale crypto_dispatch().
update locking note later.
diffstat:
sys/opencrypto/crypto.c | 139 +++++++++++++++++++++++++++++++++--------------
1 files changed, 98 insertions(+), 41 deletions(-)
diffs (truncated from 361 to 300 lines):
diff -r 5b4960bacb5d -r 5c4eb3a11f14 sys/opencrypto/crypto.c
--- a/sys/opencrypto/crypto.c Wed Jul 26 03:59:59 2017 +0000
+++ b/sys/opencrypto/crypto.c Wed Jul 26 06:40:42 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: crypto.c,v 1.94 2017/07/20 23:07:12 knakahara Exp $ */
+/* $NetBSD: crypto.c,v 1.95 2017/07/26 06:40:42 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.94 2017/07/20 23:07:12 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.95 2017/07/26 06:40:42 knakahara Exp $");
#include <sys/param.h>
#include <sys/reboot.h>
@@ -69,6 +69,7 @@
#include <sys/module.h>
#include <sys/xcall.h>
#include <sys/device.h>
+#include <sys/percpu.h>
#if defined(_KERNEL_OPT)
#include "opt_ocf.h"
@@ -77,7 +78,6 @@
#include <opencrypto/cryptodev.h>
#include <opencrypto/xform.h> /* XXX for M_XDATA */
-static kmutex_t crypto_q_mtx;
static kmutex_t crypto_ret_q_mtx;
/* below are kludges for residual code wrtitten to FreeBSD interfaces */
@@ -113,10 +113,52 @@
* cipher) operations and one for asymmetric (e.g. MOD) operations.
* See below for how synchronization is handled.
*/
-static TAILQ_HEAD(,cryptop) crp_q = /* request queues */
- TAILQ_HEAD_INITIALIZER(crp_q);
-static TAILQ_HEAD(,cryptkop) crp_kq =
- TAILQ_HEAD_INITIALIZER(crp_kq);
+TAILQ_HEAD(crypto_crp_q, cryptop);
+TAILQ_HEAD(crypto_crp_kq, cryptkop);
+struct crypto_crp_qs {
+ struct crypto_crp_q crp_q;
+ struct crypto_crp_kq crp_kq;
+};
+static percpu_t *crypto_crp_qs_percpu;
+
+static inline struct crypto_crp_qs *
+crypto_get_crp_qs(int *s)
+{
+
+ KASSERT(s != NULL);
+
+ *s = splsoftnet();
+ return percpu_getref(crypto_crp_qs_percpu);
+}
+
+static inline void
+crypto_put_crp_qs(int *s)
+{
+
+ KASSERT(s != NULL);
+
+ percpu_putref(crypto_crp_qs_percpu);
+ splx(*s);
+}
+
+static void
+crypto_crp_q_is_busy_pc(void *p, void *arg, struct cpu_info *ci __unused)
+{
+ struct crypto_crp_qs *qs_pc = p;
+ bool *isempty = arg;
+
+ if (!TAILQ_EMPTY(&qs_pc->crp_q) || !TAILQ_EMPTY(&qs_pc->crp_kq))
+ *isempty = true;
+}
+
+static void
+crypto_crp_qs_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
+{
+ struct crypto_crp_qs *qs = p;
+
+ TAILQ_INIT(&qs->crp_q);
+ TAILQ_INIT(&qs->crp_kq);
+}
/*
* There are two queues for processing completed crypto requests; one
@@ -397,7 +439,6 @@
{
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);
pool_init(&cryptop_pool, sizeof(struct cryptop), 0, 0,
0, "cryptop", NULL, IPL_NET);
@@ -406,6 +447,9 @@
pool_init(&cryptkop_pool, sizeof(struct cryptkop), 0, 0,
0, "cryptkop", NULL, IPL_NET);
+ crypto_crp_qs_percpu = percpu_alloc(sizeof(struct crypto_crp_qs));
+ percpu_foreach(crypto_crp_qs_percpu, crypto_crp_qs_init_pc, NULL);
+
crypto_drivers = malloc(CRYPTO_DRIVERS_INITIAL *
sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
if (crypto_drivers == NULL) {
@@ -462,14 +506,13 @@
if (exit_kthread) {
struct cryptocap *cap = NULL;
uint64_t where;
+ bool is_busy = false;
/* if we have any in-progress requests, don't unload */
- mutex_enter(&crypto_q_mtx);
- if (!TAILQ_EMPTY(&crp_q) || !TAILQ_EMPTY(&crp_kq)) {
- mutex_exit(&crypto_q_mtx);
+ percpu_foreach(crypto_crp_qs_percpu, crypto_crp_q_is_busy_pc,
+ &is_busy);
+ if (is_busy)
return EBUSY;
- }
- mutex_exit(&crypto_q_mtx);
/* FIXME:
* prohibit enqueue to crp_q and crp_kq after here.
*/
@@ -514,12 +557,13 @@
free(crypto_drivers, M_CRYPTO_DATA);
mutex_exit(&crypto_drv_mtx);
+ percpu_free(crypto_crp_qs_percpu, sizeof(struct crypto_crp_qs));
+
pool_destroy(&cryptop_pool);
pool_destroy(&cryptodesc_pool);
pool_destroy(&cryptkop_pool);
mutex_destroy(&crypto_ret_q_mtx);
- mutex_destroy(&crypto_q_mtx);
mutex_destroy(&crypto_drv_mtx);
return 0;
@@ -1094,8 +1138,10 @@
int
crypto_dispatch(struct cryptop *crp)
{
- int result;
+ int result, s;
struct cryptocap *cap;
+ struct crypto_crp_qs *crp_qs;
+ struct crypto_crp_q *crp_q;
KASSERT(crp != NULL);
@@ -1118,17 +1164,20 @@
*
* don't care list order in batch job.
*/
- mutex_enter(&crypto_q_mtx);
- wasempty = TAILQ_EMPTY(&crp_q);
- TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
- mutex_exit(&crypto_q_mtx);
+ crp_qs = crypto_get_crp_qs(&s);
+ crp_q = &crp_qs->crp_q;
+ wasempty = TAILQ_EMPTY(crp_q);
+ TAILQ_INSERT_TAIL(crp_q, crp, crp_next);
+ crypto_put_crp_qs(&s);
+ crp_q = NULL;
if (wasempty)
setsoftcrypto(softintr_cookie);
return 0;
}
- mutex_enter(&crypto_q_mtx);
+ crp_qs = crypto_get_crp_qs(&s);
+ crp_q = &crp_qs->crp_q;
cap = crypto_checkdriver_lock(CRYPTO_SESID2HID(crp->crp_sid));
/*
* TODO:
@@ -1140,7 +1189,7 @@
* The driver must be detached, so this request will migrate
* to other drivers in cryptointr() later.
*/
- TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
+ TAILQ_INSERT_TAIL(crp_q, crp, crp_next);
result = 0;
goto out;
}
@@ -1151,7 +1200,7 @@
* The driver is blocked, just queue the op until
* it unblocks and the swi thread gets kicked.
*/
- TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
+ TAILQ_INSERT_TAIL(crp_q, crp, crp_next);
result = 0;
goto out;
}
@@ -1172,7 +1221,7 @@
crypto_driver_lock(cap);
cap->cc_qblocked = 1;
crypto_driver_unlock(cap);
- TAILQ_INSERT_HEAD(&crp_q, crp, crp_next);
+ TAILQ_INSERT_HEAD(crp_q, crp, crp_next);
cryptostats.cs_blocks++;
/*
@@ -1184,7 +1233,7 @@
}
out:
- mutex_exit(&crypto_q_mtx);
+ crypto_put_crp_qs(&s);
return result;
}
@@ -1195,14 +1244,17 @@
int
crypto_kdispatch(struct cryptkop *krp)
{
+ int result, s;
struct cryptocap *cap;
- int result;
+ struct crypto_crp_qs *crp_qs;
+ struct crypto_crp_kq *crp_kq;
KASSERT(krp != NULL);
cryptostats.cs_kops++;
- mutex_enter(&crypto_q_mtx);
+ crp_qs = crypto_get_crp_qs(&s);
+ crp_kq = &crp_qs->crp_kq;
cap = crypto_checkdriver_lock(krp->krp_hid);
/*
* TODO:
@@ -1210,7 +1262,7 @@
* done crypto_unregister(), this migrate operation is not required.
*/
if (cap == NULL) {
- TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
+ TAILQ_INSERT_TAIL(crp_kq, krp, krp_next);
result = 0;
goto out;
}
@@ -1221,7 +1273,7 @@
* The driver is blocked, just queue the op until
* it unblocks and the swi thread gets kicked.
*/
- TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
+ TAILQ_INSERT_TAIL(crp_kq, krp, krp_next);
result = 0;
goto out;
}
@@ -1237,7 +1289,7 @@
crypto_driver_lock(cap);
cap->cc_kqblocked = 1;
crypto_driver_unlock(cap);
- TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next);
+ TAILQ_INSERT_HEAD(crp_kq, krp, krp_next);
cryptostats.cs_kblocks++;
/*
@@ -1249,7 +1301,7 @@
}
out:
- mutex_exit(&crypto_q_mtx);
+ crypto_put_crp_qs(&s);
return result;
}
@@ -1684,10 +1736,15 @@
struct cryptop *crp, *submit, *cnext;
struct cryptkop *krp, *knext;
struct cryptocap *cap;
- int result, hint;
+ struct crypto_crp_qs *crp_qs;
+ struct crypto_crp_q *crp_q;
+ struct crypto_crp_kq *crp_kq;
+ int result, hint, s;
cryptostats.cs_intrs++;
- mutex_enter(&crypto_q_mtx);
+ crp_qs = crypto_get_crp_qs(&s);
+ crp_q = &crp_qs->crp_q;
+ crp_kq = &crp_qs->crp_kq;
do {
/*
* Find the first element in the queue that can be
@@ -1696,7 +1753,7 @@
*/
submit = NULL;
hint = 0;
- TAILQ_FOREACH_SAFE(crp, &crp_q, crp_next, cnext) {
+ TAILQ_FOREACH_SAFE(crp, crp_q, crp_next, cnext) {
u_int32_t hid = CRYPTO_SESID2HID(crp->crp_sid);
cap = crypto_checkdriver_lock(hid);
if (cap == NULL || cap->cc_process == NULL) {
Home |
Main Index |
Thread Index |
Old Index