diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2020-07-16 03:04:51 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2020-07-16 03:04:51 +0000 |
commit | 99bc9843ed242e4ce3034d340f48926d3691eb99 (patch) | |
tree | 1738d929d36b6e13bdb213f585bd17a7f99eeb14 /sys | |
parent | 90f97685dd718bdd8376620fb28a335edd092779 (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.c | 14 |
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 |