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/58b5f382ad8f
branches:  trunk
changeset: 825494:58b5f382ad8f
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 eff96b5edb8b -r 58b5f382ad8f 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 eff96b5edb8b -r 58b5f382ad8f 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