Module Name: src Committed By: snj Date: Sat Jan 13 05:45:06 UTC 2018
Modified Files: src/sys/netinet [netbsd-8]: in.c Log Message: Pull up following revision(s) (requested by ozaki-r in ticket #488): sys/netinet/in.c: revision 1.213 Don't pass rwlock to callout_halt To generate a diff of this commit: cvs rdiff -u -r1.203.2.5 -r1.203.2.6 src/sys/netinet/in.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/in.c diff -u src/sys/netinet/in.c:1.203.2.5 src/sys/netinet/in.c:1.203.2.6 --- src/sys/netinet/in.c:1.203.2.5 Tue Jan 2 10:56:58 2018 +++ src/sys/netinet/in.c Sat Jan 13 05:45:06 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: in.c,v 1.203.2.5 2018/01/02 10:56:58 snj Exp $ */ +/* $NetBSD: in.c,v 1.203.2.6 2018/01/13 05:45:06 snj Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.203.2.5 2018/01/02 10:56:58 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.203.2.6 2018/01/13 05:45:06 snj Exp $"); #include "arp.h" @@ -1953,6 +1953,7 @@ in_lltable_free_entry(struct lltable *ll { struct ifnet *ifp __diagused; size_t pkts_dropped; + bool locked = false; LLE_WLOCK_ASSERT(lle); KASSERT(llt != NULL); @@ -1962,15 +1963,32 @@ in_lltable_free_entry(struct lltable *ll ifp = llt->llt_ifp; IF_AFDATA_WLOCK_ASSERT(ifp); lltable_unlink_entry(llt, lle); + locked = true; } + /* + * We need to release the lock here to lle_timer proceeds; + * lle_timer should stop immediately if LLE_LINKED isn't set. + * Note that we cannot pass lle->lle_lock to callout_halt + * because it's a rwlock. + */ + LLE_ADDREF(lle); + LLE_WUNLOCK(lle); + if (locked) + IF_AFDATA_WUNLOCK(ifp); + /* cancel timer */ - if (callout_halt(&lle->lle_timer, &lle->lle_lock)) - LLE_REMREF(lle); + callout_halt(&lle->lle_timer, NULL); + + LLE_WLOCK(lle); + LLE_REMREF(lle); /* Drop hold queue */ pkts_dropped = llentry_free(lle); arp_stat_add(ARP_STAT_DFRDROPPED, (uint64_t)pkts_dropped); + + if (locked) + IF_AFDATA_WLOCK(ifp); } static int