Module Name: src Committed By: thorpej Date: Sat Apr 18 15:56:26 UTC 2020
Modified Files: src/sys/net: if.c Log Message: In _if_down(), release the link state change lock before calling workqueue_wait(). Add a comment explaining how the locking here works. PR kern/55018. To generate a diff of this commit: cvs rdiff -u -r1.473 -r1.474 src/sys/net/if.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/net/if.c diff -u src/sys/net/if.c:1.473 src/sys/net/if.c:1.474 --- src/sys/net/if.c:1.473 Fri Feb 21 00:26:23 2020 +++ src/sys/net/if.c Sat Apr 18 15:56:26 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: if.c,v 1.473 2020/02/21 00:26:23 joerg Exp $ */ +/* $NetBSD: if.c,v 1.474 2020/04/18 15:56:26 thorpej Exp $ */ /*- * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc. @@ -90,7 +90,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.473 2020/02/21 00:26:23 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.474 2020/04/18 15:56:26 thorpej Exp $"); #if defined(_KERNEL_OPT) #include "opt_inet.h" @@ -2519,11 +2519,22 @@ _if_down(struct ifnet *ifp) pserialize_read_exit(s); curlwp_bindx(bound); + /* + * Modification of if_link_cansched is serialized with the + * ifnet ioctl lock. + * + * The link state change lock is taken to synchronize with the + * read in if_link_state_change_work_schedule(). Once we set + * this to false, our if_link_work won't be scheduled. But + * we need to wait for our if_link_work to drain in case we + * lost that race. + */ IF_LINK_STATE_CHANGE_LOCK(ifp); ifp->if_link_cansched = false; - workqueue_wait(ifnet_link_state_wq, &ifp->if_link_work); IF_LINK_STATE_CHANGE_UNLOCK(ifp); + workqueue_wait(ifnet_link_state_wq, &ifp->if_link_work); + IFQ_PURGE(&ifp->if_snd); #if NCARP > 0 if (ifp->if_carp)