Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-8]: src/sys/opencrypto Pull up following revision(s) (requested b...
details: https://anonhg.NetBSD.org/src/rev/740db8ecd691
branches: netbsd-8
changeset: 850903:740db8ecd691
user: snj <snj%NetBSD.org@localhost>
date: Sat Aug 05 03:59:21 2017 +0000
description:
Pull up following revision(s) (requested by knakahara in ticket #178):
sys/opencrypto/crypto.c: 1.92-1.100
sys/opencrypto/cryptodev.h: 1.38-1.39
sys/opencrypto/ocryptodev.c: 1.9-1.11
sys/opencrypto/xform.c: revision 1.29
sys/opencrypto/xform.h: revision 1.20
KNF
--
Apply C99-style struct initialization to enc_xform, auth_hash and comp_algo
--
make cryptoret() context softint to balance dequeuing crypto_ret_q with enqueuing it.
--
fix panic when using ecryption devices attached earlier than ipi_sysinit().
pointed out and tested by martin@n.o, thanks.
--
fix typo
--
make crp_{,k}q percpu to scale crypto_dispatch().
update locking note later.
--
divide crp_ret_{,k}q by CPU to avoid reordering.
update locking note later.
--
update locking notes of opencrypto(9)
--
Don't disclose uninitialized 32-bit word if cryptodev_session fails.
>From Ilja Van Sprundel.
--
Avert userland-controlled integer overflow.
>From Ilja Van Sprundel.
--
Avoid another userland-controlled integer overflow.
>From Ilja Van Sprundel.
--
refactor: remove glue macros for FreeBSD code.
--
pack crypto_drivers variables to struct and add cacheline_aligned qualifier.
--
use kmem_alloc KPI instead of malloc KPI.
--
use pool_cache(9) instead of pool(9) as they can be called concurrently.
diffstat:
sys/opencrypto/crypto.c | 714 +++++++++++++++++++++++++++++--------------
sys/opencrypto/cryptodev.h | 32 +-
sys/opencrypto/ocryptodev.c | 18 +-
sys/opencrypto/xform.c | 259 +++++++++++----
sys/opencrypto/xform.h | 8 +-
5 files changed, 713 insertions(+), 318 deletions(-)
diffs (truncated from 1747 to 300 lines):
diff -r c0e466c0f81b -r 740db8ecd691 sys/opencrypto/crypto.c
--- a/sys/opencrypto/crypto.c Sat Aug 05 03:52:57 2017 +0000
+++ b/sys/opencrypto/crypto.c Sat Aug 05 03:59:21 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: crypto.c,v 1.78.2.2 2017/07/05 20:19:21 snj Exp $ */
+/* $NetBSD: crypto.c,v 1.78.2.3 2017/08/05 03:59:21 snj 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,12 +53,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.78.2.2 2017/07/05 20:19:21 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.78.2.3 2017/08/05 03:59:21 snj Exp $");
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/systm.h>
-#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/pool.h>
#include <sys/kthread.h>
@@ -67,6 +66,11 @@
#include <sys/intr.h>
#include <sys/errno.h>
#include <sys/module.h>
+#include <sys/xcall.h>
+#include <sys/device.h>
+#include <sys/cpu.h>
+#include <sys/percpu.h>
+#include <sys/kmem.h>
#if defined(_KERNEL_OPT)
#include "opt_ocf.h"
@@ -75,45 +79,75 @@
#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;
-static kcondvar_t cryptoret_cv;
-
-/* below are kludges for residual code wrtitten to FreeBSD interfaces */
- #define SWI_CRYPTO 17
- #define register_swi(lvl, fn) \
- softint_establish(SOFTINT_NET|SOFTINT_MPSAFE, (void (*)(void *))fn, NULL)
- #define unregister_swi(lvl, fn) softint_disestablish(softintr_cookie)
- #define setsoftcrypto(x) \
- do{ \
- kpreempt_disable(); \
- softint_schedule(x); \
- kpreempt_enable(); \
- }while(0)
-
-int crypto_ret_q_check(struct cryptop *);
-
/*
* Crypto drivers register themselves by allocating a slot in the
* crypto_drivers table with crypto_get_driverid() and then registering
* each algorithm they support with crypto_register() and crypto_kregister().
*/
-static kmutex_t crypto_drv_mtx;
/* Don't directly access crypto_drivers[i], use crypto_checkdriver(i). */
-static struct cryptocap *crypto_drivers;
-static int crypto_drivers_num;
-static void *softintr_cookie;
-static int crypto_exit_flag;
+static struct {
+ kmutex_t mtx;
+ int num;
+ struct cryptocap *list;
+} crypto_drv __cacheline_aligned;
+#define crypto_drv_mtx (crypto_drv.mtx)
+#define crypto_drivers_num (crypto_drv.num)
+#define crypto_drivers (crypto_drv.list)
+
+static void *crypto_q_si;
+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.
* 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
@@ -121,50 +155,51 @@
* but have two to avoid type futzing (cryptop vs. cryptkop). See below
* for how synchronization is handled.
*/
-static TAILQ_HEAD(crprethead, cryptop) crp_ret_q = /* callback queues */
- TAILQ_HEAD_INITIALIZER(crp_ret_q);
-static TAILQ_HEAD(krprethead, cryptkop) crp_ret_kq =
- TAILQ_HEAD_INITIALIZER(crp_ret_kq);
-
-#define DEFINIT_CRYPTO_Q_LEN(name) \
- static int crypto_##name##_len = 0
+TAILQ_HEAD(crypto_crp_ret_q, cryptop);
+TAILQ_HEAD(crypto_crp_ret_kq, cryptkop);
+struct crypto_crp_ret_qs {
+ kmutex_t crp_ret_q_mtx;
+ bool crp_ret_q_exit_flag;
-#define DEFINIT_CRYPTO_Q_DROPS(name) \
- static int crypto_##name##_drops = 0
+ struct crypto_crp_ret_q crp_ret_q;
+ int crp_ret_q_len;
+ int crp_ret_q_maxlen; /* queue length limit. <=0 means unlimited. */
+ int crp_ret_q_drops;
-#define DEFINIT_CRYPTO_Q_MAXLEN(name, defval) \
- static int crypto_##name##_maxlen = defval
+ struct crypto_crp_ret_kq crp_ret_kq;
+ int crp_ret_kq_len;
+ int crp_ret_kq_maxlen; /* queue length limit. <=0 means unlimited. */
+ int crp_ret_kq_drops;
+};
+struct crypto_crp_ret_qs **crypto_crp_ret_qs_list;
-#define CRYPTO_Q_INC(name) \
- do { \
- crypto_##name##_len++; \
- } while(0);
-#define CRYPTO_Q_DEC(name) \
- do { \
- crypto_##name##_len--; \
- } while(0);
+static inline struct crypto_crp_ret_qs *
+crypto_get_crp_ret_qs(struct cpu_info *ci)
+{
+ u_int cpuid;
+ struct crypto_crp_ret_qs *qs;
-#define CRYPTO_Q_INC_DROPS(name) \
- do { \
- crypto_##name##_drops++; \
- } while(0);
+ KASSERT(ci != NULL);
-#define CRYPTO_Q_IS_FULL(name) \
- (crypto_##name##_maxlen > 0 \
- && (crypto_##name##_len > crypto_##name##_maxlen))
+ cpuid = cpu_index(ci);
+ qs = crypto_crp_ret_qs_list[cpuid];
+ mutex_enter(&qs->crp_ret_q_mtx);
+ return qs;
+}
-/*
- * current queue length.
- */
-DEFINIT_CRYPTO_Q_LEN(crp_ret_q);
-DEFINIT_CRYPTO_Q_LEN(crp_ret_kq);
+static inline void
+crypto_put_crp_ret_qs(struct cpu_info *ci)
+{
+ u_int cpuid;
+ struct crypto_crp_ret_qs *qs;
-/*
- * queue dropped count.
- */
-DEFINIT_CRYPTO_Q_DROPS(crp_ret_q);
-DEFINIT_CRYPTO_Q_DROPS(crp_ret_kq);
+ KASSERT(ci != NULL);
+
+ cpuid = cpu_index(ci);
+ qs = crypto_crp_ret_qs_list[cpuid];
+ mutex_exit(&qs->crp_ret_q_mtx);
+}
#ifndef CRYPTO_RET_Q_MAXLEN
#define CRYPTO_RET_Q_MAXLEN 0
@@ -172,67 +207,162 @@
#ifndef CRYPTO_RET_KQ_MAXLEN
#define CRYPTO_RET_KQ_MAXLEN 0
#endif
-/*
- * queue length limit.
- * default value is 0. <=0 means unlimited.
- */
-DEFINIT_CRYPTO_Q_MAXLEN(crp_ret_q, CRYPTO_RET_Q_MAXLEN);
-DEFINIT_CRYPTO_Q_MAXLEN(crp_ret_kq, CRYPTO_RET_KQ_MAXLEN);
-/*
- * TODO:
- * make percpu
- */
static int
sysctl_opencrypto_q_len(SYSCTLFN_ARGS)
{
- int error;
+ int error, len = 0;
+ struct sysctlnode node = *rnode;
+
+ for (int i = 0; i < ncpu; i++) {
+ struct crypto_crp_ret_qs *qs;
+ struct cpu_info *ci = cpu_lookup(i);
+
+ qs = crypto_get_crp_ret_qs(ci);
+ len += qs->crp_ret_q_len;
+ crypto_put_crp_ret_qs(ci);
+ }
+
+ node.sysctl_data = &len;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return error;
- error = sysctl_lookup(SYSCTLFN_CALL(rnode));
+ return 0;
+}
+
+static int
+sysctl_opencrypto_q_drops(SYSCTLFN_ARGS)
+{
+ int error, drops = 0;
+ struct sysctlnode node = *rnode;
+
+ for (int i = 0; i < ncpu; i++) {
+ struct crypto_crp_ret_qs *qs;
+ struct cpu_info *ci = cpu_lookup(i);
+
+ qs = crypto_get_crp_ret_qs(ci);
+ drops += qs->crp_ret_q_drops;
+ crypto_put_crp_ret_qs(ci);
+ }
+
+ node.sysctl_data = &drops;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
if (error || newp == NULL)
return error;
return 0;
}
-/*
- * TODO:
- * make percpu
- */
static int
-sysctl_opencrypto_q_drops(SYSCTLFN_ARGS)
+sysctl_opencrypto_q_maxlen(SYSCTLFN_ARGS)
{
- int error;
+ int error, maxlen;
+ struct crypto_crp_ret_qs *qs;
Home |
Main Index |
Thread Index |
Old Index