diff options
author | hsu <hsu@FreeBSD.org> | 2003-01-17 07:59:35 +0000 |
---|---|---|
committer | hsu <hsu@FreeBSD.org> | 2003-01-17 07:59:35 +0000 |
commit | 5ae046374b05d4168e58088c691e88c4a8f53582 (patch) | |
tree | 71ba6c3b48e1b7e7cd9de31d85bf255b3b5d6d04 /sys/netinet | |
parent | 6649853d68f62f6a22e8df2b4648924757ce9f67 (diff) | |
download | FreeBSD-src-5ae046374b05d4168e58088c691e88c4a8f53582.zip FreeBSD-src-5ae046374b05d4168e58088c691e88c4a8f53582.tar.gz |
SMP locking for ARP.
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/if_ether.c | 27 |
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); } |