Module Name: src Committed By: christos Date: Wed Sep 12 21:58:38 UTC 2018
Modified Files: src/sys/net/npf: npf.c npf_alg.c npf_impl.h Log Message: Fix lockdebug diagnostic error of trying to acquire an rw_lock from a pserialized active context. From riastradh@ To generate a diff of this commit: cvs rdiff -u -r1.34 -r1.35 src/sys/net/npf/npf.c cvs rdiff -u -r1.16 -r1.17 src/sys/net/npf/npf_alg.c cvs rdiff -u -r1.71 -r1.72 src/sys/net/npf/npf_impl.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/npf/npf.c diff -u src/sys/net/npf/npf.c:1.34 src/sys/net/npf/npf.c:1.35 --- src/sys/net/npf/npf.c:1.34 Wed May 31 22:45:14 2017 +++ src/sys/net/npf/npf.c Wed Sep 12 17:58:38 2018 @@ -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_sysinit(unsigned nworkers) npf_bpf_sysinit(); npf_tableset_sysinit(); npf_nat_sysinit(); + npf_alg_sysinit(); return npf_worker_sysinit(nworkers); } @@ -63,6 +64,7 @@ __dso_public void npf_sysfini(void) { npf_worker_sysfini(); + npf_alg_sysfini(); npf_nat_sysfini(); npf_tableset_sysfini(); npf_bpf_sysfini(); Index: src/sys/net/npf/npf_alg.c diff -u src/sys/net/npf/npf_alg.c:1.16 src/sys/net/npf/npf_alg.c:1.17 --- src/sys/net/npf/npf_alg.c:1.16 Mon Dec 26 18:05:06 2016 +++ src/sys/net/npf/npf_alg.c Wed Sep 12 17:58:38 2018 @@ -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 @@ struct npf_algset { /* 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 @@ npf_alg_register(npf_t *npf, const char 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 @@ npf_alg_unregister(npf_t *npf, npf_alg_t 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_alg_conn(npf_cache_t *npc, int di) { 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); Index: src/sys/net/npf/npf_impl.h diff -u src/sys/net/npf/npf_impl.h:1.71 src/sys/net/npf/npf_impl.h:1.72 --- src/sys/net/npf/npf_impl.h:1.71 Fri Aug 31 10:16:06 2018 +++ src/sys/net/npf/npf_impl.h Wed Sep 12 17:58:38 2018 @@ -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_nat_t * npf_nat_import(npf_t *, prop 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 *);