diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-02-23 20:38:00 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2015-02-23 20:38:00 +0000 |
commit | cc0edb125a9cc161577a54a06d0e0770f04e0452 (patch) | |
tree | 3ec157f10ad0a30adc31499597af434fa83d58f8 | |
parent | d8abe6df98c0decd3b7509d6e722e968df5020da (diff) | |
download | FreeBSD-src-cc0edb125a9cc161577a54a06d0e0770f04e0452.zip FreeBSD-src-cc0edb125a9cc161577a54a06d0e0770f04e0452.tar.gz |
Fix race in interrupt handling that could cause IO to hang up under heavy
load.
-rw-r--r-- | sys/powerpc/pseries/phyp_vscsi.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/sys/powerpc/pseries/phyp_vscsi.c b/sys/powerpc/pseries/phyp_vscsi.c index ed2bf08..9b638ef 100644 --- a/sys/powerpc/pseries/phyp_vscsi.c +++ b/sys/powerpc/pseries/phyp_vscsi.c @@ -931,10 +931,11 @@ vscsi_check_response_queue(struct vscsi_softc *sc) mtx_assert(&sc->io_lock, MA_OWNED); - phyp_hcall(H_VIO_SIGNAL, sc->unit, 0); - bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_POSTREAD); - while (sc->crq_queue[sc->cur_crq].valid != 0) { + /* The hypercalls at both ends of this are not optimal */ + phyp_hcall(H_VIO_SIGNAL, sc->unit, 0); + bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_POSTREAD); + crq = &sc->crq_queue[sc->cur_crq]; switch (crq->valid) { @@ -983,9 +984,9 @@ vscsi_check_response_queue(struct vscsi_softc *sc) crq->valid = 0; sc->cur_crq = (sc->cur_crq + 1) % sc->n_crqs; - }; - bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE); - phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); + bus_dmamap_sync(sc->crq_tag, sc->crq_map, BUS_DMASYNC_PREWRITE); + phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); + } } |