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);