Source-Changes-HG archive

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

[src/trunk]: src/sys/net/npf Fix lockdebug diagnostic error of trying to acqu...



details:   https://anonhg.NetBSD.org/src/rev/49f53902c8aa
branches:  trunk
changeset: 835839:49f53902c8aa
user:      christos <christos%NetBSD.org@localhost>
date:      Wed Sep 12 21:58:38 2018 +0000

description:
Fix lockdebug diagnostic error of trying to acquire an rw_lock from a
pserialized active context. From riastradh@

diffstat:

 sys/net/npf/npf.c      |   6 ++++--
 sys/net/npf/npf_alg.c  |  40 +++++++++++++++++++++++++++++++++++++---
 sys/net/npf/npf_impl.h |   4 +++-
 3 files changed, 44 insertions(+), 6 deletions(-)

diffs (153 lines):

diff -r e460ac7fc4cc -r 49f53902c8aa sys/net/npf/npf.c
--- a/sys/net/npf/npf.c Wed Sep 12 21:57:18 2018 +0000
+++ b/sys/net/npf/npf.c Wed Sep 12 21:58:38 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf.c,v 1.34 2017/06/01 02:45:14 chs Exp $     */
+/*     $NetBSD: npf.c,v 1.35 2018/09/12 21:58:38 christos Exp $        */
 
 /*-
  * Copyright (c) 2009-2013 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.34 2017/06/01 02:45:14 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.35 2018/09/12 21:58:38 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -56,6 +56,7 @@
        npf_bpf_sysinit();
        npf_tableset_sysinit();
        npf_nat_sysinit();
+       npf_alg_sysinit();
        return npf_worker_sysinit(nworkers);
 }
 
@@ -63,6 +64,7 @@
 npf_sysfini(void)
 {
        npf_worker_sysfini();
+       npf_alg_sysfini();
        npf_nat_sysfini();
        npf_tableset_sysfini();
        npf_bpf_sysfini();
diff -r e460ac7fc4cc -r 49f53902c8aa sys/net/npf/npf_alg.c
--- a/sys/net/npf/npf_alg.c     Wed Sep 12 21:57:18 2018 +0000
+++ b/sys/net/npf/npf_alg.c     Wed Sep 12 21:58:38 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_alg.c,v 1.16 2016/12/26 23:05:06 christos Exp $    */
+/*     $NetBSD: npf_alg.c,v 1.17 2018/09/12 21:58:38 christos Exp $    */
 
 /*-
  * Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
@@ -35,13 +35,14 @@
 
 #ifdef _KERNEL
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.16 2016/12/26 23:05:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.17 2018/09/12 21:58:38 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
 
 #include <sys/kmem.h>
 #include <sys/pserialize.h>
+#include <sys/psref.h>
 #include <sys/mutex.h>
 #include <net/pfil.h>
 #include <sys/module.h>
@@ -67,11 +68,31 @@
 
        /* Matching, inspection and translation functions. */
        npfa_funcs_t    alg_funcs[NPF_MAX_ALGS];
+
+       /* Passive reference until we npf conn lookup is pserialize-safe. */
+       struct psref_target     alg_psref[NPF_MAX_ALGS];
 };
 
 static const char      alg_prefix[] = "npf_alg_";
 #define        NPF_EXT_PREFLEN (sizeof(alg_prefix) - 1)
 
+__read_mostly static struct psref_class *      npf_alg_psref_class = NULL;
+
+void
+npf_alg_sysinit(void)
+{
+
+       npf_alg_psref_class = psref_class_create("npf_alg", IPL_SOFTNET);
+}
+
+void
+npf_alg_sysfini(void)
+{
+
+       psref_class_destroy(npf_alg_psref_class);
+       npf_alg_psref_class = NULL;
+}
+
 void
 npf_alg_init(npf_t *npf)
 {
@@ -160,6 +181,10 @@
        alg->na_name = name;
        alg->na_slot = i;
 
+       /* Prepare a psref target. */
+       psref_target_init(&aset->alg_psref[i], npf_alg_psref_class);
+       membar_producer();
+
        /* Assign the functions. */
        afuncs = &aset->alg_funcs[i];
        afuncs->match = funcs->match;
@@ -189,6 +214,7 @@
        afuncs->translate = NULL;
        afuncs->inspect = NULL;
        pserialize_perform(npf->qsbr);
+       psref_target_destroy(&aset->alg_psref[i], npf_alg_psref_class);
 
        /* Finally, unregister the ALG. */
        npf_ruleset_freealg(npf_config_natset(npf), alg);
@@ -246,15 +272,23 @@
 {
        npf_algset_t *aset = npc->npc_ctx->algset;
        npf_conn_t *con = NULL;
+       struct psref psref;
        int s;
 
        s = pserialize_read_enter();
        for (u_int i = 0; i < aset->alg_count; i++) {
                const npfa_funcs_t *f = &aset->alg_funcs[i];
+               struct psref_target *psref_target = &aset->alg_psref[i];
 
                if (!f->inspect)
                        continue;
-               if ((con = f->inspect(npc, di)) != NULL)
+               membar_consumer();
+               psref_acquire(&psref, psref_target, npf_alg_psref_class);
+               pserialize_read_exit(s);
+               con = f->inspect(npc, di);
+               s = pserialize_read_enter();
+               psref_release(&psref, psref_target, npf_alg_psref_class);
+               if (con != NULL)
                        break;
        }
        pserialize_read_exit(s);
diff -r e460ac7fc4cc -r 49f53902c8aa sys/net/npf/npf_impl.h
--- a/sys/net/npf/npf_impl.h    Wed Sep 12 21:57:18 2018 +0000
+++ b/sys/net/npf/npf_impl.h    Wed Sep 12 21:58:38 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: npf_impl.h,v 1.71 2018/08/31 14:16:06 maxv Exp $       */
+/*     $NetBSD: npf_impl.h,v 1.72 2018/09/12 21:58:38 christos Exp $   */
 
 /*-
  * Copyright (c) 2009-2014 The NetBSD Foundation, Inc.
@@ -405,6 +405,8 @@
                    npf_conn_t *);
 
 /* ALG interface. */
+void           npf_alg_sysinit(void);
+void           npf_alg_sysfini(void);
 void           npf_alg_init(npf_t *);
 void           npf_alg_fini(npf_t *);
 npf_alg_t *    npf_alg_register(npf_t *, const char *, const npfa_funcs_t *);



Home | Main Index | Thread Index | Old Index