From c996428c32b3daebd4aef54b6179eccb566924ca Mon Sep 17 00:00:00 2001 From: Jeffrey Hsu Date: Fri, 17 Jan 2003 07:59:35 +0000 Subject: [PATCH] SMP locking for ARP. --- sys/netinet/if_ether.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index f5e23d5856d4..16780b1f7cc8 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -130,6 +130,13 @@ static struct llinfo_arp static void in_arpinput(struct mbuf *); #endif +static struct mtx arp_mtx; + +#define ARP_LOCK_INIT() \ + mtx_init(&arp_mtx, "arp mutex", NULL, MTX_DEF | MTX_RECURSE) +#define ARP_LOCK() mtx_lock(&arp_mtx) +#define ARP_UNLOCK() mtx_unlock(&arp_mtx) + /* * Timeout routine. Age arp_tab entries periodically. */ @@ -138,17 +145,20 @@ static void arptimer(ignored_arg) void *ignored_arg; { + struct llinfo_arp *la, *ola; int s = splnet(); - register struct llinfo_arp *la = LIST_FIRST(&llinfo_arp); - struct llinfo_arp *ola; - timeout(arptimer, (caddr_t)0, arpt_prune * hz); - while ((ola = la) != 0) { - register struct rtentry *rt = la->la_rt; + ARP_LOCK(); + la = LIST_FIRST(&llinfo_arp); + timeout(arptimer, NULL, arpt_prune * hz); + while (la != NULL) { + struct rtentry *rt = la->la_rt; + ola = la; la = LIST_NEXT(la, la_le); if (rt->rt_expire && rt->rt_expire <= time_second) - arptfree(ola); /* timer has expired, clear */ + arptfree(ola); /* timer has expired, clear */ } + ARP_UNLOCK(); splx(s); } @@ -225,7 +235,9 @@ arp_rtrequest(req, rt, info) Bzero(la, sizeof(*la)); la->la_rt = rt; rt->rt_flags |= RTF_LLINFO; + ARP_LOCK(); LIST_INSERT_HEAD(&llinfo_arp, la, la_le); + ARP_UNLOCK(); #ifdef INET /* @@ -273,7 +285,9 @@ arp_rtrequest(req, rt, info) if (la == 0) break; arp_inuse--; + ARP_LOCK(); LIST_REMOVE(la, la_le); + ARP_UNLOCK(); rt->rt_llinfo = 0; rt->rt_flags &= ~RTF_LLINFO; if (la->la_hold) @@ -951,6 +965,7 @@ arp_init(void) arpintrq.ifq_maxlen = 50; mtx_init(&arpintrq.ifq_mtx, "arp_inq", NULL, MTX_DEF); LIST_INIT(&llinfo_arp); + ARP_LOCK_INIT(); register_netisr(NETISR_ARP, arpintr); }