summaryrefslogtreecommitdiffstats
path: root/sys/netinet/if_ether.c
diff options
context:
space:
mode:
authorhsu <hsu@FreeBSD.org>2003-01-17 07:59:35 +0000
committerhsu <hsu@FreeBSD.org>2003-01-17 07:59:35 +0000
commit5ae046374b05d4168e58088c691e88c4a8f53582 (patch)
tree71ba6c3b48e1b7e7cd9de31d85bf255b3b5d6d04 /sys/netinet/if_ether.c
parent6649853d68f62f6a22e8df2b4648924757ce9f67 (diff)
downloadFreeBSD-src-5ae046374b05d4168e58088c691e88c4a8f53582.zip
FreeBSD-src-5ae046374b05d4168e58088c691e88c4a8f53582.tar.gz
SMP locking for ARP.
Diffstat (limited to 'sys/netinet/if_ether.c')
-rw-r--r--sys/netinet/if_ether.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index f5e23d5..16780b1 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);
}
OpenPOWER on IntegriCloud