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/2625c4800645
branches:  netbsd-8
changeset: 850806:2625c4800645
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 f257d97025e8 -r 2625c4800645 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