arp_drain() may be called with locks held, so instead of doing any work

in arp_drain(), set a drain-needed flag.  Do the work in the fasttimo
handler.

Contributed by Coyote Point Systems, Inc.
This commit is contained in:
dyoung 2011-05-03 16:00:29 +00:00
parent cb861154c1
commit 8e054749e4

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_arp.c,v 1.150 2011/02/01 01:39:21 matt Exp $ */
/* $NetBSD: if_arp.c,v 1.151 2011/05/03 16:00:29 dyoung Exp $ */
/*-
* Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.150 2011/02/01 01:39:21 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.151 2011/05/03 16:00:29 dyoung Exp $");
#include "opt_ddb.h"
#include "opt_inet.h"
@ -151,6 +151,7 @@ static struct llinfo_arp *arplookup1(struct mbuf *, const struct in_addr *,
static struct llinfo_arp *arplookup(struct mbuf *, const struct in_addr *,
int, int);
static void in_arpinput(struct mbuf *);
static void arp_drainstub(void);
LIST_HEAD(, llinfo_arp) llinfo_arp;
struct ifqueue arpintrq = {
@ -188,6 +189,8 @@ static void db_print_llinfo(void *);
static int db_show_rtentry(struct rtentry *, void *);
#endif
static int arp_drainwanted;
/*
* this should be elsewhere.
*/
@ -224,6 +227,15 @@ lla_snprintf(u_int8_t *adrp, int len)
DOMAIN_DEFINE(arpdomain); /* forward declare and add to link set */
static void
arp_fasttimo(void)
{
if (arp_drainwanted) {
arp_drain();
arp_drainwanted = 0;
}
}
const struct protosw arpsw[] = {
{ .pr_type = 0,
.pr_domain = &arpdomain,
@ -235,9 +247,9 @@ const struct protosw arpsw[] = {
.pr_ctloutput = 0,
.pr_usrreq = 0,
.pr_init = arp_init,
.pr_fasttimo = 0,
.pr_fasttimo = arp_fasttimo,
.pr_slowtimo = 0,
.pr_drain = arp_drain,
.pr_drain = arp_drainstub,
}
};
@ -328,6 +340,12 @@ arp_init(void)
arpstat_percpu = percpu_alloc(sizeof(uint64_t) * ARP_NSTATS);
}
static void
arp_drainstub(void)
{
arp_drainwanted = 1;
}
/*
* ARP protocol drain routine. Called when memory is in short supply.
* Called at splvm(); don't acquire softnet_lock as can be called from