On 04/12/15(Fri) 11:54, Martin Pieuchot wrote:
> Now that in_arpinput() only uses the routing table, if_get()/if_put()
> and carp_iamatch being already mpsafe we can kill the ARP input queue.
> 
> This moves the ARP input path processing from the softnet interrupt
> context (under KERNEL_LOCK) to the sofnettask (without KERNEL_LOCK).

Updated diff after trailer removal, I'm still interested in test
reports.

Index: net/if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.231
diff -u -p -r1.231 if_ethersubr.c
--- net/if_ethersubr.c  2 Dec 2015 08:47:00 -0000       1.231
+++ net/if_ethersubr.c  22 Dec 2015 12:34:28 -0000
@@ -372,14 +372,14 @@ decapsulate:
        case ETHERTYPE_ARP:
                if (ifp->if_flags & IFF_NOARP)
                        goto dropanyway;
-               inq = &arpintrq;
-               break;
+               arpinput(m);
+               return (1);
 
        case ETHERTYPE_REVARP:
                if (ifp->if_flags & IFF_NOARP)
                        goto dropanyway;
-               inq = &rarpintrq;
-               break;
+               revarpinput(m);
+               return (1);
 
 #ifdef INET6
        /*
Index: net/netisr.c
===================================================================
RCS file: /cvs/src/sys/net/netisr.c,v
retrieving revision 1.9
diff -u -p -r1.9 netisr.c
--- net/netisr.c        5 Dec 2015 10:07:55 -0000       1.9
+++ net/netisr.c        22 Dec 2015 12:34:28 -0000
@@ -20,7 +20,6 @@
 
 #include <machine/intr.h>
 
-#include "ether.h"
 #include "ppp.h"
 #include "bridge.h"
 #include "pppoe.h"
@@ -39,10 +38,6 @@ netintr(void *unused)
        while ((n = netisr) != 0) {
                atomic_clearbits_int(&netisr, n);
 
-#if NETHER > 0
-               if (n & (1 << NETISR_ARP))
-                       arpintr();
-#endif
                if (n & (1 << NETISR_IP))
                        ipintr();
 #ifdef INET6
Index: net/netisr.h
===================================================================
RCS file: /cvs/src/sys/net/netisr.h,v
retrieving revision 1.43
diff -u -p -r1.43 netisr.h
--- net/netisr.h        3 Dec 2015 12:27:33 -0000       1.43
+++ net/netisr.h        22 Dec 2015 12:34:28 -0000
@@ -53,7 +53,6 @@
 #define        NETISR_IP       2               /* same as AF_INET */
 #define        NETISR_TX       3               /* for if_snd processing */
 #define        NETISR_PFSYNC   5               /* for pfsync "immediate" tx */
-#define        NETISR_ARP      18              /* same as AF_LINK */
 #define        NETISR_IPV6     24              /* same as AF_INET6 */
 #define        NETISR_ISDN     26              /* same as AF_E164 */
 #define        NETISR_PPP      28              /* for PPP processing */
@@ -64,7 +63,6 @@
 #ifdef _KERNEL
 extern int     netisr;                 /* scheduling bits for network */
 
-void   arpintr(void);
 void   ipintr(void);
 void   ip6intr(void);
 void   pppintr(void);
Index: netinet/if_ether.c
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.c,v
retrieving revision 1.198
diff -u -p -r1.198 if_ether.c
--- netinet/if_ether.c  17 Dec 2015 16:05:30 -0000      1.198
+++ netinet/if_ether.c  22 Dec 2015 12:41:12 -0000
@@ -82,14 +82,10 @@ void arptfree(struct rtentry *);
 void arptimer(void *);
 struct rtentry *arplookup(u_int32_t, int, int, u_int);
 void in_arpinput(struct mbuf *);
-void revarpinput(struct mbuf *);
 void in_revarpinput(struct mbuf *);
 
 LIST_HEAD(, llinfo_arp) arp_list;
 struct pool arp_pool;          /* pool for llinfo_arp structures */
-/* XXX hate magic numbers */
-struct niqueue arpintrq = NIQUEUE_INITIALIZER(50, NETISR_ARP);
-struct niqueue rarpintrq = NIQUEUE_INITIALIZER(50, NETISR_ARP);
 int    arp_inuse, arp_allocated;
 int    arp_maxtries = 5;
 int    arpinit_done;
@@ -420,42 +416,32 @@ bad:
  * then the protocol-specific routine is called.
  */
 void
-arpintr(void)
+arpinput(struct mbuf *m)
 {
-       struct mbuf *m;
        struct arphdr *ar;
        int len;
 
-       while ((m = niq_dequeue(&arpintrq)) != NULL) {
 #ifdef DIAGNOSTIC
-               if ((m->m_flags & M_PKTHDR) == 0)
-                       panic("arpintr");
+       if ((m->m_flags & M_PKTHDR) == 0)
+               panic("arpintr");
 #endif
 
-               len = sizeof(struct arphdr);
-               if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
-                       continue;
-
-               ar = mtod(m, struct arphdr *);
-               if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) {
-                       m_freem(m);
-                       continue;
-               }
-
-               len += 2 * (ar->ar_hln + ar->ar_pln);
-               if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
-                       continue;
+       len = sizeof(struct arphdr);
+       if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
+               return;
 
-               switch (ntohs(ar->ar_pro)) {
-               case ETHERTYPE_IP:
-                       in_arpinput(m);
-                       continue;
-               }
+       ar = mtod(m, struct arphdr *);
+       if (ntohs(ar->ar_hrd) != ARPHRD_ETHER ||
+           ntohs(ar->ar_pro) != ETHERTYPE_IP) {
                m_freem(m);
+               return;
        }
 
-       while ((m = niq_dequeue(&rarpintrq)) != NULL)
-               revarpinput(m);
+       len += 2 * (ar->ar_hln + ar->ar_pln);
+       if (m->m_len < len && (m = m_pullup(m, len)) == NULL)
+               return;
+
+       in_arpinput(m);
 }
 
 /*
Index: netinet/if_ether.h
===================================================================
RCS file: /cvs/src/sys/netinet/if_ether.h,v
retrieving revision 1.65
diff -u -p -r1.65 if_ether.h
--- netinet/if_ether.h  9 Dec 2015 15:05:51 -0000       1.65
+++ netinet/if_ether.h  22 Dec 2015 12:34:28 -0000
@@ -182,11 +182,20 @@ extern u_int8_t etherbroadcastaddr[ETHER
 extern u_int8_t etheranyaddr[ETHER_ADDR_LEN];
 extern u_int8_t ether_ipmulticast_min[ETHER_ADDR_LEN];
 extern u_int8_t ether_ipmulticast_max[ETHER_ADDR_LEN];
-extern struct niqueue arpintrq;
-extern struct niqueue rarpintrq;
 
+#ifdef NFSCLIENT
+extern unsigned int revarp_ifidx;
+#endif /* NFSCLIENT */
+
+void   revarpinput(struct mbuf *);
+void   revarprequest(struct ifnet *);
+int    revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *);
+int    revarpwhoami(struct in_addr *, struct ifnet *);
+
+void   arpinput(struct mbuf *);
+void   arprequest(struct ifnet *, u_int32_t *, u_int32_t *, u_int8_t *);
 void   arpwhohas(struct arpcom *, struct in_addr *);
-void   arpintr(void);
+int    arpproxy(struct in_addr, unsigned int);
 int    arpresolve(struct ifnet *, struct rtentry *, struct mbuf *,
            struct sockaddr *, u_char *);
 void   arp_rtrequest(struct ifnet *, int, struct rtentry *);
@@ -270,17 +279,6 @@ do {                                                       
                \
        (step).e_enm = LIST_FIRST(&(ac)->ac_multiaddrs);                \
        ETHER_NEXT_MULTI((step), (enm));                                \
 } while (/* CONSTCOND */ 0)
-
-#ifdef NFSCLIENT
-extern unsigned int revarp_ifidx;
-#endif /* NFSCLIENT */
-
-void arprequest(struct ifnet *, u_int32_t *, u_int32_t *, u_int8_t *);
-int arpproxy(struct in_addr, unsigned int);
-void revarprequest(struct ifnet *);
-int revarpwhoarewe(struct ifnet *, struct in_addr *, struct in_addr *);
-int revarpwhoami(struct in_addr *, struct ifnet *);
-int db_show_arptab(void);
 
 u_int32_t ether_crc32_le_update(u_int32_t crc, const u_int8_t *, size_t);
 u_int32_t ether_crc32_be_update(u_int32_t crc, const u_int8_t *, size_t);

Reply via email to