From 8e054749e4505c83733044620fcba6ebec0da588 Mon Sep 17 00:00:00 2001 From: dyoung Date: Tue, 3 May 2011 16:00:29 +0000 Subject: [PATCH] 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. --- sys/netinet/if_arp.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/sys/netinet/if_arp.c b/sys/netinet/if_arp.c index 8d623a9a7c5b..f1863a6201c6 100644 --- a/sys/netinet/if_arp.c +++ b/sys/netinet/if_arp.c @@ -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 -__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