Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/netinet Stop callout in arp_rtrequest(RTM_DELETE)
details: https://anonhg.NetBSD.org/src/rev/7d1c57b933ff
branches: trunk
changeset: 341138:7d1c57b933ff
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Tue Oct 20 07:46:59 2015 +0000
description:
Stop callout in arp_rtrequest(RTM_DELETE)
This change fixes arptimer panic after removing an interface
(say by drvctl -d), which is reported by Takahiro Hayashi.
This change also fixes llentry's reference counting; we have
to take into account rtentry#rt_llinfo as well as arptimer.
diffstat:
sys/netinet/if_arp.c | 30 +++++++++++++++++++-----------
1 files changed, 19 insertions(+), 11 deletions(-)
diffs (71 lines):
diff -r fe82fd8ce2b6 -r 7d1c57b933ff sys/netinet/if_arp.c
--- a/sys/netinet/if_arp.c Tue Oct 20 07:35:15 2015 +0000
+++ b/sys/netinet/if_arp.c Tue Oct 20 07:46:59 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_arp.c,v 1.190 2015/10/20 07:35:15 ozaki-r Exp $ */
+/* $NetBSD: if_arp.c,v 1.191 2015/10/20 07:46:59 ozaki-r 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.190 2015/10/20 07:35:15 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.191 2015/10/20 07:46:59 ozaki-r Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -635,6 +635,7 @@
break;
}
rt->rt_llinfo = la;
+ LLE_ADDREF(la);
switch (ifp->if_type) {
#if NTOKEN > 0
case IFT_ISO88025:
@@ -662,17 +663,14 @@
rt->rt_llinfo = NULL;
rt->rt_flags &= ~RTF_LLINFO;
+ /* Have to do before IF_AFDATA_WLOCK to avoid deadlock */
+ callout_halt(&la->la_timer, &la->lle_lock);
+ /* XXX: LOR avoidance. We still have ref on lle. */
LLE_RUNLOCK(la);
flags |= LLE_EXCLUSIVE;
IF_AFDATA_WLOCK(ifp);
-
- la = lla_lookup(LLTABLE(ifp), flags, rt_getkey(rt));
- /* This shouldn't happen */
- if (la == NULL) {
- IF_AFDATA_WUNLOCK(ifp);
- break;
- }
+ LLE_WLOCK(la);
if (la->la_opaque != NULL) {
switch (ifp->if_type) {
@@ -695,10 +693,20 @@
la->la_rt->rt_refcnt--;
la->la_rt = NULL;
}
- llentry_free(la);
+
+ /* Guard against race with other llentry_free(). */
+ if (la->la_flags & LLE_LINKED) {
+ size_t pkts_dropped;
+
+ LLE_REMREF(la);
+ pkts_dropped = llentry_free(la);
+ ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped);
+ } else {
+ LLE_FREE_LOCKED(la);
+ }
+ la = NULL;
IF_AFDATA_WUNLOCK(ifp);
- la = NULL;
}
if (la != NULL) {
Home |
Main Index |
Thread Index |
Old Index