Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/opencrypto Re-work the module init and destroy code to a...



details:   https://anonhg.NetBSD.org/src/rev/5ae1726cec27
branches:  trunk
changeset: 341893:5ae1726cec27
user:      pgoyette <pgoyette%NetBSD.org@localhost>
date:      Sat Nov 28 03:06:45 2015 +0000

description:
Re-work the module init and destroy code to allow it to be unloaded and
then reloaded.

Should fix PR kern/49842

diffstat:

 sys/opencrypto/crypto.c    |  87 +++++++++++++++++++++++++++++++++++++--------
 sys/opencrypto/cryptodev.h |   4 +-
 2 files changed, 72 insertions(+), 19 deletions(-)

diffs (192 lines):

diff -r 89566544295b -r 5ae1726cec27 sys/opencrypto/crypto.c
--- a/sys/opencrypto/crypto.c   Fri Nov 27 22:02:15 2015 +0000
+++ b/sys/opencrypto/crypto.c   Sat Nov 28 03:06:45 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: crypto.c,v 1.45 2014/02/25 18:30:12 pooka Exp $ */
+/*     $NetBSD: crypto.c,v 1.46 2015/11/28 03:06:45 pgoyette 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.45 2014/02/25 18:30:12 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.46 2015/11/28 03:06:45 pgoyette Exp $");
 
 #include <sys/param.h>
 #include <sys/reboot.h>
@@ -97,6 +97,7 @@
 static struct cryptocap *crypto_drivers;
 static int crypto_drivers_num;
 static void *softintr_cookie;
+static int crypto_exit_flag;
 
 /*
  * There are two queues for crypto requests; one for symmetric (e.g.
@@ -236,7 +237,7 @@
 static void cryptointr(void);          /* swi thread to dispatch ops */
 static void cryptoret(void);           /* kernel thread for callbacks*/
 static struct lwp *cryptothread;
-static void crypto_destroy(void);
+static int crypto_destroy(bool);
 static int crypto_invoke(struct cryptop *crp, int hint);
 static int crypto_kinvoke(struct cryptkop *krp, int hint);
 
@@ -269,7 +270,7 @@
            sizeof(struct cryptocap), M_CRYPTO_DATA, M_NOWAIT | M_ZERO);
        if (crypto_drivers == NULL) {
                printf("crypto_init: cannot malloc driver table\n");
-               return 0;
+               return ENOMEM;
        }
        crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
 
@@ -279,7 +280,7 @@
        if (error) {
                printf("crypto_init: cannot start cryptoret thread; error %d",
                        error);
-               crypto_destroy();
+               return crypto_destroy(false);
        }
 
 #ifdef _MODULE
@@ -288,21 +289,60 @@
        return 0;
 }
 
-void
+int
 crypto_init(void)
 {
        static ONCE_DECL(crypto_init_once);
 
-       RUN_ONCE(&crypto_init_once, crypto_init0);
+       return RUN_ONCE(&crypto_init_once, crypto_init0);
 }
 
-static void
-crypto_destroy(void)
+static int
+crypto_destroy(bool exit_kthread)
 {
-       /* XXX no wait to reclaim zones */
+       int i;
+
+       if (exit_kthread) {
+               mutex_spin_enter(&crypto_ret_q_mtx);
+
+               /* if we have any in-progress requests, don't unload */
+               if (!TAILQ_EMPTY(&crp_q) || !TAILQ_EMPTY(&crp_kq))
+                       return EBUSY;
+
+               for (i = 0; i < crypto_drivers_num; i++)
+                       if (crypto_drivers[i].cc_sessions != 0)
+                               break;
+               if (i < crypto_drivers_num)
+                       return EBUSY;
+
+               /* 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);
+       }
+
+       if (sysctl_opencrypto_clog != NULL)
+               sysctl_teardown(&sysctl_opencrypto_clog);
+
+       unregister_swi(SWI_CRYPTO, cryptointr);
+
        if (crypto_drivers != NULL)
                free(crypto_drivers, M_CRYPTO_DATA);
-       unregister_swi(SWI_CRYPTO, cryptointr);
+
+       pool_destroy(&cryptop_pool);
+       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_mtx);
+
+       return 0;
 }
 
 /*
@@ -441,7 +481,7 @@
        struct cryptocap *newdrv;
        int i;
 
-       crypto_init();          /* XXX oh, this is foul! */
+       (void)crypto_init();            /* XXX oh, this is foul! */
 
        mutex_enter(&crypto_mtx);
        for (i = 0; i < crypto_drivers_num; i++)
@@ -1306,6 +1346,17 @@
 
                /* 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;
@@ -1345,19 +1396,21 @@
 static int
 opencrypto_modcmd(modcmd_t cmd, void *opaque)
 {
+       int error = 0;
 
        switch (cmd) {
        case MODULE_CMD_INIT:
 #ifdef _MODULE
-               crypto_init();
+               error = crypto_init();
 #endif
-               return 0;
+               break;
        case MODULE_CMD_FINI:
 #ifdef _MODULE
-               sysctl_teardown(&sysctl_opencrypto_clog);
+               error = crypto_destroy(true);
 #endif
-               return 0;
+               break;
        default:
-               return ENOTTY;
+               error = ENOTTY;
        }
+       return error;
 }
diff -r 89566544295b -r 5ae1726cec27 sys/opencrypto/cryptodev.h
--- a/sys/opencrypto/cryptodev.h        Fri Nov 27 22:02:15 2015 +0000
+++ b/sys/opencrypto/cryptodev.h        Sat Nov 28 03:06:45 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cryptodev.h,v 1.25 2011/06/09 14:41:24 drochner Exp $ */
+/*     $NetBSD: cryptodev.h,v 1.26 2015/11/28 03:06:45 pgoyette 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 $      */
 
@@ -625,7 +625,7 @@
  * (This declaration doesnt really belong here but there's no header
  * for the raw framework.)
  */
-void   crypto_init(void);
+int    crypto_init(void);
 
 /*
  * Crypto-related utility routines used mainly by drivers.



Home | Main Index | Thread Index | Old Index