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)