diff options
author | Jan Klemkow <jan@cvs.openbsd.org> | 2023-07-19 20:22:06 +0000 |
---|---|---|
committer | Jan Klemkow <jan@cvs.openbsd.org> | 2023-07-19 20:22:06 +0000 |
commit | 807be46d23c02394a5b2b0ea02994b42d38276e2 (patch) | |
tree | 528bbaaca2b0d8e1e4471945460e7ef6b43d878d /sys/dev/pci/if_ixl.c | |
parent | 16cf5b2ab630d0ed4c68332b1503e798de408a92 (diff) |
Protect ixl(4) admin queue with mutex(9).
with tweaks from bluhm
tested by bluhm
ok bluhm@
Diffstat (limited to 'sys/dev/pci/if_ixl.c')
-rw-r--r-- | sys/dev/pci/if_ixl.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/sys/dev/pci/if_ixl.c b/sys/dev/pci/if_ixl.c index 3aa9c226c57..5f42dd53953 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.87 2023/02/06 20:27:45 jan Exp $ */ +/* $OpenBSD: if_ixl.c,v 1.88 2023/07/19 20:22:05 jan Exp $ */ /* * Copyright (c) 2013-2015, Intel Corporation @@ -1274,6 +1274,7 @@ struct ixl_softc { unsigned int sc_atq_prod; unsigned int sc_atq_cons; + struct mutex sc_atq_mtx; struct ixl_dmamem sc_arq; struct task sc_arq_task; struct ixl_aq_bufs sc_arq_idle; @@ -1723,6 +1724,8 @@ ixl_attach(struct device *parent, struct device *self, void *aux) /* initialise the adminq */ + mtx_init(&sc->sc_atq_mtx, IPL_NET); + if (ixl_dmamem_alloc(sc, &sc->sc_atq, sizeof(struct ixl_aq_desc) * IXL_AQ_NUM, IXL_AQ_ALIGN) != 0) { printf("\n" "%s: unable to allocate atq\n", DEVNAME(sc)); @@ -3599,7 +3602,7 @@ ixl_atq_post(struct ixl_softc *sc, struct ixl_atq *iatq) struct ixl_aq_desc *atq, *slot; unsigned int prod; - /* assert locked */ + mtx_enter(&sc->sc_atq_mtx); atq = IXL_DMA_KVA(&sc->sc_atq); prod = sc->sc_atq_prod; @@ -3618,6 +3621,8 @@ ixl_atq_post(struct ixl_softc *sc, struct ixl_atq *iatq) prod &= IXL_AQ_MASK; sc->sc_atq_prod = prod; ixl_wr(sc, sc->sc_aq_regs->atq_tail, prod); + + mtx_leave(&sc->sc_atq_mtx); } static void @@ -3628,11 +3633,15 @@ ixl_atq_done(struct ixl_softc *sc) unsigned int cons; unsigned int prod; + mtx_enter(&sc->sc_atq_mtx); + prod = sc->sc_atq_prod; cons = sc->sc_atq_cons; - if (prod == cons) + if (prod == cons) { + mtx_leave(&sc->sc_atq_mtx); return; + } atq = IXL_DMA_KVA(&sc->sc_atq); @@ -3645,6 +3654,7 @@ ixl_atq_done(struct ixl_softc *sc) if (!ISSET(slot->iaq_flags, htole16(IXL_AQ_DD))) break; + KASSERT(slot->iaq_cookie != 0); iatq = (struct ixl_atq *)slot->iaq_cookie; iatq->iatq_desc = *slot; @@ -3661,6 +3671,8 @@ ixl_atq_done(struct ixl_softc *sc) BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); sc->sc_atq_cons = cons; + + mtx_leave(&sc->sc_atq_mtx); } static void @@ -3691,6 +3703,8 @@ ixl_atq_poll(struct ixl_softc *sc, struct ixl_aq_desc *iaq, unsigned int tm) unsigned int prod; unsigned int t = 0; + mtx_enter(&sc->sc_atq_mtx); + atq = IXL_DMA_KVA(&sc->sc_atq); prod = sc->sc_atq_prod; slot = atq + prod; @@ -3712,8 +3726,10 @@ ixl_atq_poll(struct ixl_softc *sc, struct ixl_aq_desc *iaq, unsigned int tm) while (ixl_rd(sc, sc->sc_aq_regs->atq_head) != prod) { delaymsec(1); - if (t++ > tm) + if (t++ > tm) { + mtx_leave(&sc->sc_atq_mtx); return (ETIMEDOUT); + } } bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), @@ -3724,6 +3740,7 @@ ixl_atq_poll(struct ixl_softc *sc, struct ixl_aq_desc *iaq, unsigned int tm) sc->sc_atq_cons = prod; + mtx_leave(&sc->sc_atq_mtx); return (0); } |