Source-Changes-HG archive

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

[src/trunk]: src/sys/opencrypto divide crp_ret_{, k}q by CPU to avoid reordering.



details:   https://anonhg.NetBSD.org/src/rev/07a744d5315e
branches:  trunk
changeset: 825636:07a744d5315e
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Wed Jul 26 06:44:01 2017 +0000

description:
divide crp_ret_{,k}q by CPU to avoid reordering.

update locking note later.

diffstat:

 sys/opencrypto/crypto.c |  389 ++++++++++++++++++++++++++++++++++-------------
 1 files changed, 282 insertions(+), 107 deletions(-)

diffs (truncated from 630 to 300 lines):

diff -r 601efa83471a -r 07a744d5315e sys/opencrypto/crypto.c
--- a/sys/opencrypto/crypto.c   Wed Jul 26 06:40:42 2017 +0000
+++ b/sys/opencrypto/crypto.c   Wed Jul 26 06:44:01 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: crypto.c,v 1.95 2017/07/26 06:40:42 knakahara Exp $ */
+/*     $NetBSD: crypto.c,v 1.96 2017/07/26 06:44:01 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.95 2017/07/26 06:40:42 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: crypto.c,v 1.96 2017/07/26 06:44:01 knakahara Exp $");
 
 #include <sys/param.h>
 #include <sys/reboot.h>
@@ -69,7 +69,9 @@
 #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"
@@ -78,8 +80,6 @@
 #include <opencrypto/cryptodev.h>
 #include <opencrypto/xform.h>                  /* XXX for M_XDATA */
 
-static kmutex_t crypto_ret_q_mtx;
-
 /* below are kludges for residual code wrtitten to FreeBSD interfaces */
   #define SWI_CRYPTO 17
   #define register_swi(lvl, fn)  \
@@ -104,7 +104,6 @@
 static struct cryptocap *crypto_drivers;
 static int crypto_drivers_num;
 static void *softintr_cookie;
-static int crypto_exit_flag;
 
 static void *crypto_ret_si;
 
@@ -166,50 +165,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
@@ -217,60 +217,155 @@
 #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;
+       struct sysctlnode node = *rnode;
+
+       /* each crp_ret_kq_maxlen is the same. */
+       qs = crypto_get_crp_ret_qs(curcpu());
+       maxlen = qs->crp_ret_q_maxlen;
+       crypto_put_crp_ret_qs(curcpu());
+
+       node.sysctl_data = &maxlen;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL)
+               return error;
+
+       for (int i = 0; i < ncpu; i++) {
+               struct cpu_info *ci = cpu_lookup(i);
 
-       error = sysctl_lookup(SYSCTLFN_CALL(rnode));
+               qs = crypto_get_crp_ret_qs(ci);
+               qs->crp_ret_q_maxlen = maxlen;
+               crypto_put_crp_ret_qs(ci);
+       }
+
+       return 0;
+}
+
+static int
+sysctl_opencrypto_kq_len(SYSCTLFN_ARGS)
+{
+       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_kq_len;
+               crypto_put_crp_ret_qs(ci);
+       }
+
+       node.sysctl_data = &len;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
        if (error || newp == NULL)
                return error;
 
        return 0;
 }
 
-/*
- * need to make percpu?
- */
 static int
-sysctl_opencrypto_q_maxlen(SYSCTLFN_ARGS)
+sysctl_opencrypto_kq_drops(SYSCTLFN_ARGS)
 {
-       int error;
+       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);
 
-       error = sysctl_lookup(SYSCTLFN_CALL(rnode));
+               qs = crypto_get_crp_ret_qs(ci);
+               drops += qs->crp_ret_kq_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;
 }
 
+static int
+sysctl_opencrypto_kq_maxlen(SYSCTLFN_ARGS)
+{
+       int error, maxlen;
+       struct crypto_crp_ret_qs *qs;
+       struct sysctlnode node = *rnode;
+
+       /* each crp_ret_kq_maxlen is the same. */
+       qs = crypto_get_crp_ret_qs(curcpu());
+       maxlen = qs->crp_ret_kq_maxlen;
+       crypto_put_crp_ret_qs(curcpu());
+
+       node.sysctl_data = &maxlen;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL)
+               return error;
+



Home | Main Index | Thread Index | Old Index