summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2017-06-07 15:49:22 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2017-06-07 15:49:22 +0000
commit80c4e9e8419feb9a28acae4c7828a3be7c3837e0 (patch)
treeffc2f1bbec0c039e6116f3c8a188058332c6626c /sys
parente1782e85409778654f310ca3db0a72b2e60a27e8 (diff)
Acquire submit queue mutex only once per xbf_complete_cmd invocation
and remove some leftover assertions.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pv/xbf.c50
1 files changed, 19 insertions, 31 deletions
diff --git a/sys/dev/pv/xbf.c b/sys/dev/pv/xbf.c
index 8c4b8dfcf94..375ceed2638 100644
--- a/sys/dev/pv/xbf.c
+++ b/sys/dev/pv/xbf.c
@@ -1,7 +1,7 @@
-/* $OpenBSD: xbf.c,v 1.30 2017/06/06 21:12:01 mikeb Exp $ */
+/* $OpenBSD: xbf.c,v 1.31 2017/06/07 15:49:21 mikeb Exp $ */
/*
- * Copyright (c) 2016 Mike Belopuhov
+ * Copyright (c) 2016, 2017 Mike Belopuhov
* Copyright (c) 2009, 2011 Mark Kettenis
*
* Permission to use, copy, modify, and distribute this software for any
@@ -507,7 +507,6 @@ xbf_load_cmd(struct scsi_xfer *xs)
KASSERT(sge->sge_last <= 7);
}
- KASSERT(nsg > 0);
xrd->xrd_req.req_nsegs = nsg;
return (0);
@@ -698,8 +697,6 @@ xbf_submit_cmd(struct scsi_xfer *xs)
if (error)
return (-1);
} else {
- KASSERT(nblk == 0);
- KASSERT(ndesc == 1);
DPRINTF("%s: desc %u %s%s lba %llu\n", sc->sc_dev.dv_xname,
ccb->ccb_first, operation == XBF_OP_FLUSH ? "flush" :
"barrier", ISSET(xs->flags, SCSI_POLL) ? "-poll" : "",
@@ -757,37 +754,36 @@ xbf_complete_cmd(struct xbf_softc *sc, struct xbf_ccb_queue *cq, int desc)
uint32_t id, chunk;
int error;
- bus_dmamap_sync(sc->sc_dmat, sc->sc_xr_dma.dma_map, 0,
- sc->sc_xr_dma.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD |
- BUS_DMASYNC_POSTWRITE);
-
xrd = &sc->sc_xr->xr_desc[desc];
error = xrd->xrd_rsp.rsp_status == XBF_OK ? XS_NOERROR :
XS_DRIVER_STUFFUP;
- id = (uint32_t)xrd->xrd_rsp.rsp_id;
mtx_enter(&sc->sc_ccb_sqlck);
+
+ /*
+ * To find a CCB for id equal to x within an interval [a, b] we must
+ * locate a CCB such that (x - a) mod N <= (b - a) mod N, where a is
+ * the first descriptor, b is the last one and N is the ring size.
+ */
+ id = (uint32_t)xrd->xrd_rsp.rsp_id;
TAILQ_FOREACH(ccb, &sc->sc_ccb_sq, ccb_link) {
if (((id - ccb->ccb_first) & (sc->sc_xr_ndesc - 1)) <=
((ccb->ccb_last - ccb->ccb_first) & (sc->sc_xr_ndesc - 1)))
break;
}
- mtx_leave(&sc->sc_ccb_sqlck);
KASSERT(ccb != NULL);
+
+ /* Assert that this chunk belongs to this CCB */
chunk = 1 << ((id - ccb->ccb_first) & (sc->sc_xr_ndesc - 1));
-#ifdef XBF_DEBUG
- if ((ccb->ccb_want & chunk) == 0) {
- panic("%s: id %#x first %#x want %#x seen %#x chunk %#x",
- sc->sc_dev.dv_xname, id, ccb->ccb_first, ccb->ccb_want,
- ccb->ccb_seen, chunk);
- }
- if ((ccb->ccb_seen & chunk) != 0) {
- panic("%s: id %#x first %#x want %#x seen %#x chunk %#x",
- sc->sc_dev.dv_xname, id, ccb->ccb_first, ccb->ccb_want,
- ccb->ccb_seen, chunk);
- }
-#endif
+ KASSERT((ccb->ccb_want & chunk) != 0);
+ KASSERT((ccb->ccb_seen & chunk) == 0);
+
+ /* When all chunks are collected remove the CCB from the queue */
ccb->ccb_seen |= chunk;
+ if (ccb->ccb_seen == ccb->ccb_want)
+ TAILQ_REMOVE(&sc->sc_ccb_sq, ccb, ccb_link);
+
+ mtx_leave(&sc->sc_ccb_sqlck);
if (ccb->ccb_bbuf.dma_size > 0)
map = ccb->ccb_bbuf.dma_map;
@@ -806,10 +802,6 @@ xbf_complete_cmd(struct xbf_softc *sc, struct xbf_ccb_queue *cq, int desc)
xrd->xrd_req.req_id = desc;
if (ccb->ccb_seen == ccb->ccb_want) {
- mtx_enter(&sc->sc_ccb_sqlck);
- TAILQ_REMOVE(&sc->sc_ccb_sq, ccb, ccb_link);
- mtx_leave(&sc->sc_ccb_sqlck);
-
ccb->ccb_xfer->resid = 0;
ccb->ccb_xfer->error = error;
TAILQ_INSERT_TAIL(cq, ccb, ccb_link);
@@ -900,8 +892,6 @@ xbf_scsi_done(struct scsi_xfer *xs, int error)
{
int s;
- KERNEL_ASSERT_LOCKED();
-
xs->error = error;
s = splbio();
@@ -912,8 +902,6 @@ xbf_scsi_done(struct scsi_xfer *xs, int error)
int
xbf_dev_probe(struct scsi_link *link)
{
- KASSERT(link->lun == 0);
-
if (link->target == 0)
return (0);