summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2020-07-16 03:04:51 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2020-07-16 03:04:51 +0000
commit99bc9843ed242e4ce3034d340f48926d3691eb99 (patch)
tree1738d929d36b6e13bdb213f585bd17a7f99eeb14 /sys
parent90f97685dd718bdd8376620fb28a335edd092779 (diff)
use a mutex to serialise the test and set of ifp->if_link_state.
this was serialised by NET_LOCK, but now i get link state change information in an interrupt context, so i shouldn't (can't) do that anymore. ok jmatthew@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_ixl.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/dev/pci/if_ixl.c b/sys/dev/pci/if_ixl.c
index 89783aa9c7c..35c5545f8d9 100644
--- a/sys/dev/pci/if_ixl.c
+++ b/sys/dev/pci/if_ixl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ixl.c,v 1.67 2020/07/16 00:58:02 dlg Exp $ */
+/* $OpenBSD: if_ixl.c,v 1.68 2020/07/16 03:04:50 dlg Exp $ */
/*
* Copyright (c) 2013-2015, Intel Corporation
@@ -1268,6 +1268,7 @@ struct ixl_softc {
unsigned int sc_arq_prod;
unsigned int sc_arq_cons;
+ struct mutex sc_link_state_mtx;
struct task sc_link_state_task;
struct ixl_atq sc_link_state_atq;
@@ -1933,6 +1934,7 @@ ixl_attach(struct device *parent, struct device *self, void *aux)
if_attach_queues(ifp, nqueues);
if_attach_iqueues(ifp, nqueues);
+ mtx_init(&sc->sc_link_state_mtx, IPL_NET);
task_set(&sc->sc_link_state_task, ixl_link_state_update, sc);
ixl_wr(sc, I40E_PFINT_ICR0_ENA,
I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK |
@@ -3349,6 +3351,7 @@ ixl_link_state_update_iaq(struct ixl_softc *sc, void *arg)
struct ixl_aq_desc *iaq = arg;
uint16_t retval;
int link_state;
+ int change = 0;
retval = lemtoh16(&iaq->iaq_retval);
if (retval != IXL_AQ_RC_OK) {
@@ -3356,13 +3359,16 @@ ixl_link_state_update_iaq(struct ixl_softc *sc, void *arg)
return;
}
- NET_LOCK();
link_state = ixl_set_link_status(sc, iaq);
+ mtx_enter(&sc->sc_link_state_mtx);
if (ifp->if_link_state != link_state) {
ifp->if_link_state = link_state;
- if_link_state_change(ifp);
+ change = 1;
}
- NET_UNLOCK();
+ mtx_leave(&sc->sc_link_state_mtx);
+
+ if (change)
+ if_link_state_change(ifp);
}
static void