Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet use pserialize(9) and psref(9) (2/2) : ip_encap ...



details:   https://anonhg.NetBSD.org/src/rev/0ef1e839f536
branches:  trunk
changeset: 346263:0ef1e839f536
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Mon Jul 04 04:31:04 2016 +0000

description:
use pserialize(9) and psref(9) (2/2) : ip_encap radix tree care

diffstat:

 sys/netinet/ip_encap.c |  44 ++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 42 insertions(+), 2 deletions(-)

diffs (106 lines):

diff -r b5d1778fbdf1 -r 0ef1e839f536 sys/netinet/ip_encap.c
--- a/sys/netinet/ip_encap.c    Mon Jul 04 04:29:11 2016 +0000
+++ b/sys/netinet/ip_encap.c    Mon Jul 04 04:31:04 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_encap.c,v 1.56 2016/07/04 04:29:11 knakahara Exp $  */
+/*     $NetBSD: ip_encap.c,v 1.57 2016/07/04 04:31:04 knakahara Exp $  */
 /*     $KAME: ip_encap.c,v 1.73 2001/10/02 08:30:58 itojun Exp $       */
 
 /*
@@ -68,7 +68,7 @@
 #define USE_RADIX
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.56 2016/07/04 04:29:11 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_encap.c,v 1.57 2016/07/04 04:31:04 knakahara Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_mrouting.h"
@@ -147,6 +147,7 @@
 
 #ifdef USE_RADIX
 struct radix_node_head *encap_head[2]; /* 0 for AF_INET, 1 for AF_INET6 */
+static bool encap_head_updating = false;
 #endif
 
 static ONCE_DECL(encap_init_control);
@@ -221,6 +222,14 @@
 
        s = pserialize_read_enter();
 #ifdef USE_RADIX
+       if (encap_head_updating) {
+               /*
+                * Update in progress. Do nothing.
+                */
+               pserialize_read_exit(s);
+               return NULL;
+       }
+
        rn = rnh->rnh_matchaddr((void *)&pack, rnh);
        if (rn && (rn->rn_flags & RNF_ROOT) == 0) {
                struct encaptab *encapp = (struct encaptab *)rn;
@@ -381,6 +390,14 @@
 
        s = pserialize_read_enter();
 #ifdef USE_RADIX
+       if (encap_head_updating) {
+               /*
+                * Update in progress. Do nothing.
+                */
+               pserialize_read_exit(s);
+               return NULL;
+       }
+
        rn = rnh->rnh_matchaddr((void *)&pack, rnh);
        if (rn && (rn->rn_flags & RNF_ROOT) == 0) {
                struct encaptab *encapp = (struct encaptab *)rn;
@@ -498,13 +515,25 @@
 
 #ifdef USE_RADIX
        if (!ep->func && rnh) {
+               /* Disable access to the radix tree for reader. */
+               encap_head_updating = true;
                /* Wait for all readers to drain. */
                pserialize_perform(encaptab.psz);
 
                if (!rnh->rnh_addaddr((void *)ep->addrpack,
                    (void *)ep->maskpack, rnh, ep->nodes)) {
+                       encap_head_updating = false;
                        return EEXIST;
                }
+
+               /*
+                * The ep added to the radix tree must be skipped while
+                * encap[46]_lookup walks encaptab list. In other words,
+                * encap_add() does not need to care whether the ep has
+                * been added encaptab list or not yet.
+                * So, we can re-enable access to the radix tree for now.
+                */
+               encap_head_updating = false;
        }
 #endif
        PSLIST_WRITER_INSERT_HEAD(&encap_table, ep, chain);
@@ -528,12 +557,23 @@
 
 #ifdef USE_RADIX
        if (!ep->func && rnh) {
+               /* Disable access to the radix tree for reader. */
+               encap_head_updating = true;
                /* Wait for all readers to drain. */
                pserialize_perform(encaptab.psz);
 
                if (!rnh->rnh_deladdr((void *)ep->addrpack,
                    (void *)ep->maskpack, rnh))
                        error = ESRCH;
+
+               /*
+                * The ep added to the radix tree must be skipped while
+                * encap[46]_lookup walks encaptab list. In other words,
+                * encap_add() does not need to care whether the ep has
+                * been added encaptab list or not yet.
+                * So, we can re-enable access to the radix tree for now.
+                */
+               encap_head_updating = false;
        }
 #endif
        PSLIST_WRITER_REMOVE(ep, chain);



Home | Main Index | Thread Index | Old Index