Source-Changes-HG archive

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

[src/trunk]: src/sys Replace ARP cache (llinfo) with lltable/llentry



details:   https://anonhg.NetBSD.org/src/rev/a7c267d771da
branches:  trunk
changeset: 340317:a7c267d771da
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Mon Aug 31 08:05:20 2015 +0000

description:
Replace ARP cache (llinfo) with lltable/llentry

Highlights of the change are:
- Use llentry instead of llinfo to manage ARP caches
  - ARP specific data are stored in the hashed list
    of an interface instead of the global list (llinfo_arp)
- Fine-grain locking on llentry
- arptimer (callout) per ARP cache
  - the global timer callout with the big locks can be
    removed (though softnet_lock is still required for now)
- net.inet.arp.prune is now obsoleted
  - it was the interval of the global timer callout
- net.inet.arp.refresh is now obsoleted
  - it was a parameter that prevents expiration of active caches
  - Removed to simplify the timer logic, but we may be able to
    restore the feature if really needed

Proposed on tech-kern and tech-net.

diffstat:

 sys/net/if_arp.h       |    4 +-
 sys/net/if_ethersubr.c |    6 +-
 sys/net/if_llatbl.c    |    7 +-
 sys/net/if_llatbl.h    |   31 +-
 sys/net/if_tokensubr.c |   17 +-
 sys/netinet/if_arp.c   |  615 +++++++++++++++++++++++++++++-------------------
 sys/netinet/in.c       |   21 +-
 sys/netinet/in_proto.c |    9 +-
 sys/netinet/in_var.h   |    5 +-
 9 files changed, 431 insertions(+), 284 deletions(-)

diffs (truncated from 1185 to 300 lines):

diff -r d6cb829e27c4 -r a7c267d771da sys/net/if_arp.h
--- a/sys/net/if_arp.h  Mon Aug 31 08:02:44 2015 +0000
+++ b/sys/net/if_arp.h  Mon Aug 31 08:05:20 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_arp.h,v 1.29 2008/04/15 15:17:54 thorpej Exp $      */
+/*     $NetBSD: if_arp.h,v 1.30 2015/08/31 08:05:20 ozaki-r Exp $      */
 
 /*
  * Copyright (c) 1986, 1993
@@ -127,4 +127,6 @@
 
 #define        ARP_NSTATS              23
 
+void arp_stat_add(int, uint64_t);
+
 #endif /* !_NET_IF_ARP_H_ */
diff -r d6cb829e27c4 -r a7c267d771da sys/net/if_ethersubr.c
--- a/sys/net/if_ethersubr.c    Mon Aug 31 08:02:44 2015 +0000
+++ b/sys/net/if_ethersubr.c    Mon Aug 31 08:05:20 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ethersubr.c,v 1.212 2015/08/24 22:21:26 pooka Exp $ */
+/*     $NetBSD: if_ethersubr.c,v 1.213 2015/08/31 08:05:20 ozaki-r Exp $       */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.212 2015/08/24 22:21:26 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.213 2015/08/31 08:05:20 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -243,7 +243,7 @@
                else if (m->m_flags & M_MCAST)
                        ETHER_MAP_IP_MULTICAST(&satocsin(dst)->sin_addr, edst);
                else if (!arpresolve(ifp, rt, m, dst, edst))
-                       return (0);     /* if not yet resolved */
+                       return 0;       /* if not yet resolved */
                /* If broadcasting on a simplex interface, loopback a copy */
                if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
                        mcopy = m_copy(m, 0, (int)M_COPYALL);
diff -r d6cb829e27c4 -r a7c267d771da sys/net/if_llatbl.c
--- a/sys/net/if_llatbl.c       Mon Aug 31 08:02:44 2015 +0000
+++ b/sys/net/if_llatbl.c       Mon Aug 31 08:05:20 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_llatbl.c,v 1.1 2015/08/31 07:56:58 ozaki-r Exp $    */
+/*     $NetBSD: if_llatbl.c,v 1.2 2015/08/31 08:05:20 ozaki-r Exp $    */
 /*
  * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
  * Copyright (c) 2004-2008 Qing Li. All rights reserved.
@@ -373,6 +373,11 @@
        LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) {
                if (callout_stop(&lle->la_timer))
                        LLE_REMREF(lle);
+#if __NetBSD__
+               /* XXX should have callback? */
+               if (lle->la_rt != NULL)
+                       rtfree(lle->la_rt);
+#endif
                llentry_free(lle);
        }
 
diff -r d6cb829e27c4 -r a7c267d771da sys/net/if_llatbl.h
--- a/sys/net/if_llatbl.h       Mon Aug 31 08:02:44 2015 +0000
+++ b/sys/net/if_llatbl.h       Mon Aug 31 08:05:20 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_llatbl.h,v 1.1 2015/08/31 07:56:58 ozaki-r Exp $    */
+/*     $NetBSD: if_llatbl.h,v 1.2 2015/08/31 08:05:20 ozaki-r Exp $    */
 /*
  * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
  * Copyright (c) 2004-2008 Qing Li. All rights reserved.
@@ -94,10 +94,29 @@
 #endif
 };
 
-#define        LLE_WLOCK(lle)          rw_enter(&(lle)->lle_lock, RW_WRITER)
-#define        LLE_RLOCK(lle)          rw_enter(&(lle)->lle_lock, RW_READER)
-#define        LLE_WUNLOCK(lle)        rw_exit(&(lle)->lle_lock)
-#define        LLE_RUNLOCK(lle)        rw_exit(&(lle)->lle_lock)
+
+#if 0
+#define LLE_LOCK_TRACE(n)      aprint_normal("%s: " #n " line %d\n", __func__, __LINE__)
+#else
+#define LLE_LOCK_TRACE(n)
+#endif
+
+#define        LLE_WLOCK(lle)          do { \
+                                       LLE_LOCK_TRACE(WL); \
+                                       rw_enter(&(lle)->lle_lock, RW_WRITER); \
+                               } while (0)
+#define        LLE_RLOCK(lle)          do { \
+                                       LLE_LOCK_TRACE(RL); \
+                                       rw_enter(&(lle)->lle_lock, RW_READER); \
+                               } while (0)
+#define        LLE_WUNLOCK(lle)        do { \
+                                       LLE_LOCK_TRACE(WU); \
+                                       rw_exit(&(lle)->lle_lock); \
+                               } while (0)
+#define        LLE_RUNLOCK(lle)        do { \
+                                       LLE_LOCK_TRACE(RU); \
+                                       rw_exit(&(lle)->lle_lock); \
+                               } while (0)
 #define        LLE_DOWNGRADE(lle)      rw_downgrade(&(lle)->lle_lock)
 #define        LLE_TRY_UPGRADE(lle)    rw_tryupgrade(&(lle)->lle_lock)
 #ifdef __FreeBSD__
@@ -106,7 +125,7 @@
 #define        LLE_LOCK_INIT(lle)      rw_init(&(lle)->lle_lock)
 #endif
 #define        LLE_LOCK_DESTROY(lle)   rw_destroy(&(lle)->lle_lock)
-#define        LLE_WLOCK_ASSERT(lle)   KASSERT(rw_lock_held(&(lle)->lle_lock))
+#define        LLE_WLOCK_ASSERT(lle)   KASSERT(rw_write_held(&(lle)->lle_lock))
 
 #define LLE_IS_VALID(lle)      (((lle) != NULL) && ((lle) != (void *)-1))
 
diff -r d6cb829e27c4 -r a7c267d771da sys/net/if_tokensubr.c
--- a/sys/net/if_tokensubr.c    Mon Aug 31 08:02:44 2015 +0000
+++ b/sys/net/if_tokensubr.c    Mon Aug 31 08:05:20 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_tokensubr.c,v 1.70 2015/08/24 22:21:26 pooka Exp $  */
+/*     $NetBSD: if_tokensubr.c,v 1.71 2015/08/31 08:05:20 ozaki-r Exp $        */
 
 /*
  * Copyright (c) 1982, 1989, 1993
@@ -92,7 +92,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_tokensubr.c,v 1.70 2015/08/24 22:21:26 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_tokensubr.c,v 1.71 2015/08/31 08:05:20 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -114,11 +114,12 @@
 #include <sys/cpu.h>
 
 #include <net/if.h>
+#include <net/if_dl.h>
+#include <net/if_llatbl.h>
+#include <net/if_llc.h>
+#include <net/if_types.h>
 #include <net/netisr.h>
 #include <net/route.h>
-#include <net/if_llc.h>
-#include <net/if_dl.h>
-#include <net/if_types.h>
 
 #include <net/bpf.h>
 
@@ -217,9 +218,13 @@
  * XXX m->m_flags & M_MCAST   IEEE802_MAP_IP_MULTICAST ??
  */
                else {
+                       struct llentry *la;
                        if (!arpresolve(ifp, rt, m, dst, edst))
                                return (0);     /* if not yet resolved */
-                       rif = TOKEN_RIF((struct llinfo_arp *) rt->rt_llinfo);
+                       la = rt->rt_llinfo;
+                       KASSERT(la != NULL);
+                       KASSERT(la->la_opaque != NULL);
+                       rif = la->la_opaque;
                        riflen = (ntohs(rif->tr_rcf) & TOKEN_RCF_LEN_MASK) >> 8;
                }
                /* If broadcasting on a simplex interface, loopback a copy. */
diff -r d6cb829e27c4 -r a7c267d771da sys/netinet/if_arp.c
--- a/sys/netinet/if_arp.c      Mon Aug 31 08:02:44 2015 +0000
+++ b/sys/netinet/if_arp.c      Mon Aug 31 08:05:20 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_arp.c,v 1.173 2015/08/24 22:21:26 pooka Exp $       */
+/*     $NetBSD: if_arp.c,v 1.174 2015/08/31 08:05:20 ozaki-r Exp $     */
 
 /*-
  * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.173 2015/08/24 22:21:26 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.174 2015/08/31 08:05:20 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -98,6 +98,7 @@
 #include <sys/socketvar.h>
 #include <sys/percpu.h>
 #include <sys/cprng.h>
+#include <sys/kmem.h>
 
 #include <net/ethertypes.h>
 #include <net/if.h>
@@ -105,6 +106,7 @@
 #include <net/if_token.h>
 #include <net/if_types.h>
 #include <net/if_ether.h>
+#include <net/if_llatbl.h>
 #include <net/net_osdep.h>
 #include <net/route.h>
 #include <net/net_stats.h>
@@ -143,6 +145,7 @@
 static int     arpt_keep = (20*60);    /* once resolved, good for 20 more minutes */
 static int     arpt_down = 20;         /* once declared down, don't send for 20 secs */
 static int     arpt_refresh = (5*60);  /* time left before refreshing */
+static int     arp_maxhold = 1;        /* number of packets to hold per ARP entry */
 #define        rt_expire rt_rmx.rmx_expire
 #define        rt_pksent rt_rmx.rmx_pksent
 
@@ -158,12 +161,10 @@
 
 static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *,
            const struct sockaddr *);
-static void arptfree(struct llinfo_arp *);
+static void arptfree(struct llentry *);
 static void arptimer(void *);
-static struct llinfo_arp *arplookup1(struct mbuf *, const struct in_addr *,
-                                     int, int, struct rtentry *);
-static struct llinfo_arp *arplookup(struct mbuf *, const struct in_addr *,
-                                         int, int);
+static struct llentry *arplookup(struct ifnet *, struct mbuf *,
+           const struct in_addr *, int, int, int, struct rtentry *);
 static void in_arpinput(struct mbuf *);
 static void in_revarpinput(struct mbuf *);
 static void revarprequest(struct ifnet *);
@@ -175,7 +176,6 @@
 static void arp_dad_stop(struct ifaddr *);
 static void arp_dad_duplicated(struct ifaddr *);
 
-LIST_HEAD(llinfo_arpq, llinfo_arp) llinfo_arp;
 struct ifqueue arpintrq = {
        .ifq_head = NULL,
        .ifq_tail = NULL,
@@ -186,7 +186,6 @@
 static int     arp_inuse, arp_allocated;
 static int     arp_maxtries = 5;
 static int     useloopback = 1;        /* use loopback interface for local traffic */
-static int     arpinit_done = 0;
 
 static percpu_t *arpstat_percpu;
 
@@ -196,8 +195,6 @@
 #define        ARP_STATINC(x)          _NET_STATINC(arpstat_percpu, x)
 #define        ARP_STATADD(x, v)       _NET_STATADD(arpstat_percpu, x, v)
 
-struct callout arptimer_ch;
-
 /* revarp state */
 static struct  in_addr myip, srv_ip;
 static int     myip_initialized = 0;
@@ -287,75 +284,6 @@
        .dom_protoswNPROTOSW = &arpsw[__arraycount(arpsw)],
 };
 
-/*
- * ARP table locking.
- *
- * to prevent lossage vs. the arp_drain routine (which may be called at
- * any time, including in a device driver context), we do two things:
- *
- * 1) manipulation of la->la_hold is done at splnet() (for all of
- * about two instructions).
- *
- * 2) manipulation of the arp table's linked list is done under the
- * protection of the ARP_LOCK; if arp_drain() or arptimer is called
- * while the arp table is locked, we punt and try again later.
- */
-
-static int     arp_locked;
-static inline int arp_lock_try(int);
-static inline void arp_unlock(void);
-
-static inline int
-arp_lock_try(int recurse)
-{
-       int s;
-
-       /*
-        * Use splvm() -- we're blocking things that would cause
-        * mbuf allocation.
-        */
-       s = splvm();
-       if (!recurse && arp_locked) {
-               splx(s);
-               return 0;
-       }
-       arp_locked++;
-       splx(s);
-       return 1;
-}
-
-static inline void
-arp_unlock(void)
-{
-       int s;
-
-       s = splvm();
-       arp_locked--;
-       splx(s);
-}
-
-#ifdef DIAGNOSTIC



Home | Main Index | Thread Index | Old Index