Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-8]: src/sys Pull up following revision(s) (requested by knakahara...
details: https://anonhg.NetBSD.org/src/rev/e679972b9097
branches: netbsd-8
changeset: 434082:e679972b9097
user: snj <snj%NetBSD.org@localhost>
date: Wed Jul 05 20:19:21 2017 +0000
description:
Pull up following revision(s) (requested by knakahara in ticket #97):
sys/opencrypto/crypto.c: 1.87-1.91
sys/opencrypto/cryptodev.c: 1.93-1.95
sys/opencrypto/cryptodev.h: 1.37
sys/opencrypto/cryptosoft.c: 1.52
sys/rump/dev/lib/libopencrypto/opencrypto_component.c: 1.5
sanitize count used for kmem_alloc size.
Hmm, who uses CIOCNGSESSION, CIOCNFSESSION, CIOCNCRYPTM or CIOCNFKEYM?
--
sanitize in CIOCNCRYPTM and initialize comp_alg in CIOCNGSESSION
--
must release cap->cc_lock before calling cap->cc_newsession() because of spinlock.
--
refactor crypto_newsession() like FreeBSD.
--
support multiple encryption drivers (port from FreeBSD).
--
Divide crp_devflags from crp_flags to write exclusively.
CRYPTO_F_DQRETQ(new name is CRYPTODEV_F_RET) is used by cryptodev.c only.
It should be divided to other member.
--
Reduce crypto_ret_q_mtx lock regions.
crypto.c does not access the members of crp when the crp is in crp_q or
crp_ret_q. Furthermore, crp_q and crp_ret_q are protected by each mutex,
so the members of crp is not shared. That means crp_flags is not required
mutex in crypto.c.
--
fix cryptosoft.c:r1.51 mistake. swcrypto_attach() must not be called from module_init_class().
swcrypto_attach() will call softint_establish(), it must be called after cpus
attached. module_init_class() is too early to call softint_establish().
--
simplify mutex_enter/exit(crypto_q_mtx), and fix missing exit.
--
reduce rump waring message. pointed out by ozaki-r@n.o, thanks.
diffstat:
sys/opencrypto/crypto.c | 186 +++++++++++------
sys/opencrypto/cryptodev.c | 45 +++-
sys/opencrypto/cryptodev.h | 13 +-
sys/opencrypto/cryptosoft.c | 92 +++++---
sys/rump/dev/lib/libopencrypto/opencrypto_component.c | 19 +-
5 files changed, 244 insertions(+), 111 deletions(-)
diffs (truncated from 691 to 300 lines):
diff -r 39221336e9ad -r e679972b9097 sys/opencrypto/crypto.c
--- a/sys/opencrypto/crypto.c Wed Jul 05 20:15:33 2017 +0000
+++ b/sys/opencrypto/crypto.c Wed Jul 05 20:19:21 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: crypto.c,v 1.78.2.1 2017/06/22 05:36:41 snj Exp $ */
+/* $NetBSD: crypto.c,v 1.78.2.2 2017/07/05 20:19: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,7 +53,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.78.2.1 2017/06/22 05:36:41 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.78.2.2 2017/07/05 20:19:21 snj Exp $");
#include <sys/param.h>
#include <sys/reboot.h>
@@ -501,27 +501,50 @@
return 0;
}
-/*
- * Create a new session.
- */
-int
-crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
+static bool
+crypto_driver_suitable(struct cryptocap *cap, struct cryptoini *cri)
{
struct cryptoini *cr;
- struct cryptocap *cap;
- u_int32_t hid, lid;
- int err = EINVAL;
+
+ for (cr = cri; cr; cr = cr->cri_next)
+ if (cap->cc_alg[cr->cri_alg] == 0) {
+ DPRINTF("alg %d not supported\n", cr->cri_alg);
+ return false;
+ }
+
+ return true;
+}
- mutex_enter(&crypto_drv_mtx);
+#define CRYPTO_ACCEPT_HARDWARE 0x1
+#define CRYPTO_ACCEPT_SOFTWARE 0x2
+/*
+ * The algorithm we use here is pretty stupid; just use the
+ * first driver that supports all the algorithms we need.
+ * If there are multiple drivers we choose the driver with
+ * the fewest active sessions. We prefer hardware-backed
+ * drivers to software ones.
+ *
+ * XXX We need more smarts here (in real life too, but that's
+ * XXX another story altogether).
+ */
+static struct cryptocap *
+crypto_select_driver_lock(struct cryptoini *cri, int hard)
+{
+ u_int32_t hid;
+ int accept;
+ struct cryptocap *cap, *best;
+ best = NULL;
/*
- * The algorithm we use here is pretty stupid; just use the
- * first driver that supports all the algorithms we need.
- *
- * XXX We need more smarts here (in real life too, but that's
- * XXX another story altogether).
+ * hard == 0 can use both hardware and software drivers.
+ * We use hardware drivers prior to software drivers, so search
+ * hardware drivers at first time.
*/
-
+ if (hard >= 0)
+ accept = CRYPTO_ACCEPT_HARDWARE;
+ else
+ accept = CRYPTO_ACCEPT_SOFTWARE;
+again:
for (hid = 0; hid < crypto_drivers_num; hid++) {
cap = crypto_checkdriver(hid);
if (cap == NULL)
@@ -540,54 +563,85 @@
}
/* Hardware required -- ignore software drivers. */
- if (hard > 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE)) {
+ if ((accept & CRYPTO_ACCEPT_SOFTWARE) == 0
+ && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE)) {
crypto_driver_unlock(cap);
continue;
}
/* Software required -- ignore hardware drivers. */
- if (hard < 0 && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE) == 0) {
+ if ((accept & CRYPTO_ACCEPT_HARDWARE) == 0
+ && (cap->cc_flags & CRYPTOCAP_F_SOFTWARE) == 0) {
crypto_driver_unlock(cap);
continue;
}
/* See if all the algorithms are supported. */
- for (cr = cri; cr; cr = cr->cri_next)
- if (cap->cc_alg[cr->cri_alg] == 0) {
- DPRINTF("alg %d not supported\n", cr->cri_alg);
- break;
+ if (crypto_driver_suitable(cap, cri)) {
+ if (best == NULL) {
+ /* keep holding crypto_driver_lock(cap) */
+ best = cap;
+ continue;
+ } else if (cap->cc_sessions < best->cc_sessions) {
+ crypto_driver_unlock(best);
+ /* keep holding crypto_driver_lock(cap) */
+ best = cap;
+ continue;
}
-
- if (cr == NULL) {
- /* Ok, all algorithms are supported. */
-
- /*
- * Can't do everything in one session.
- *
- * XXX Fix this. We need to inject a "virtual" session layer right
- * XXX about here.
- */
-
- /* Call the driver initialization routine. */
- lid = hid; /* Pass the driver ID. */
- err = cap->cc_newsession(cap->cc_arg, &lid, cri);
- if (err == 0) {
- (*sid) = hid;
- (*sid) <<= 32;
- (*sid) |= (lid & 0xffffffff);
- (cap->cc_sessions)++;
- } else {
- DPRINTF("crypto_drivers[%d].cc_newsession() failed. error=%d\n",
- hid, err);
- }
- crypto_driver_unlock(cap);
- goto done;
- /*break;*/
}
crypto_driver_unlock(cap);
}
-done:
+ if (best == NULL && hard == 0
+ && (accept & CRYPTO_ACCEPT_SOFTWARE) == 0) {
+ accept = CRYPTO_ACCEPT_SOFTWARE;
+ goto again;
+ }
+
+ return best;
+}
+
+/*
+ * Create a new session.
+ */
+int
+crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard)
+{
+ struct cryptocap *cap;
+ int err = EINVAL;
+
+ mutex_enter(&crypto_drv_mtx);
+
+ cap = crypto_select_driver_lock(cri, hard);
+ if (cap != NULL) {
+ u_int32_t hid, lid;
+
+ hid = cap - crypto_drivers;
+ /*
+ * Can't do everything in one session.
+ *
+ * XXX Fix this. We need to inject a "virtual" session layer right
+ * XXX about here.
+ */
+
+ /* Call the driver initialization routine. */
+ lid = hid; /* Pass the driver ID. */
+ crypto_driver_unlock(cap);
+ err = cap->cc_newsession(cap->cc_arg, &lid, cri);
+ crypto_driver_lock(cap);
+ if (err == 0) {
+ (*sid) = hid;
+ (*sid) <<= 32;
+ (*sid) |= (lid & 0xffffffff);
+ (cap->cc_sessions)++;
+ } else {
+ DPRINTF("crypto_drivers[%d].cc_newsession() failed. error=%d\n",
+ hid, err);
+ }
+ crypto_driver_unlock(cap);
+ }
+
mutex_exit(&crypto_drv_mtx);
+
return err;
}
@@ -1063,8 +1117,8 @@
* to other drivers in cryptointr() later.
*/
TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
- mutex_exit(&crypto_q_mtx);
- return 0;
+ result = 0;
+ goto out;
}
if (cap->cc_qblocked != 0) {
@@ -1074,8 +1128,8 @@
* it unblocks and the swi thread gets kicked.
*/
TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
- mutex_exit(&crypto_q_mtx);
- return 0;
+ result = 0;
+ goto out;
}
/*
@@ -1105,6 +1159,7 @@
result = 0;
}
+out:
mutex_exit(&crypto_q_mtx);
return result;
}
@@ -1132,8 +1187,8 @@
*/
if (cap == NULL) {
TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
- mutex_exit(&crypto_q_mtx);
- return 0;
+ result = 0;
+ goto out;
}
if (cap->cc_kqblocked != 0) {
@@ -1143,8 +1198,8 @@
* it unblocks and the swi thread gets kicked.
*/
TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
- mutex_exit(&crypto_q_mtx);
- return 0;
+ result = 0;
+ goto out;
}
crypto_driver_unlock(cap);
@@ -1160,7 +1215,6 @@
crypto_driver_unlock(cap);
TAILQ_INSERT_HEAD(&crp_kq, krp, krp_next);
cryptostats.cs_kblocks++;
- mutex_exit(&crypto_q_mtx);
/*
* The krp is enqueued to crp_kq, that is,
@@ -1170,6 +1224,8 @@
result = 0;
}
+out:
+ mutex_exit(&crypto_q_mtx);
return result;
}
@@ -1440,7 +1496,6 @@
void
crypto_done(struct cryptop *crp)
{
- int wasempty;
KASSERT(crp != NULL);
@@ -1466,9 +1521,7 @@
* callback routine does very little (e.g. the
* /dev/crypto callback method just does a wakeup).
*/
- mutex_spin_enter(&crypto_ret_q_mtx);
crp->crp_flags |= CRYPTO_F_DONE;
- mutex_spin_exit(&crypto_ret_q_mtx);
#ifdef CRYPTO_TIMING
if (crypto_timing) {
@@ -1485,7 +1538,6 @@
#endif
crp->crp_callback(crp);
} else {
- mutex_spin_enter(&crypto_ret_q_mtx);
crp->crp_flags |= CRYPTO_F_DONE;
#if 0
if (crp->crp_flags & CRYPTO_F_USER) {
@@ -1501,6 +1553,9 @@
} else
Home |
Main Index |
Thread Index |
Old Index