diff options
author | mav <mav@FreeBSD.org> | 2010-03-03 17:58:41 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2010-03-03 17:58:41 +0000 |
commit | e3c00ddca2867c8720e62e1bbb896673b6dedc93 (patch) | |
tree | 188024e4219f563735ea3eb3c262199e7c4b9ded /sys/dev/ciss/ciss.c | |
parent | 06472b9695cbc871cff421e16a2dd8ff09d79cf7 (diff) | |
download | FreeBSD-src-e3c00ddca2867c8720e62e1bbb896673b6dedc93.zip FreeBSD-src-e3c00ddca2867c8720e62e1bbb896673b6dedc93.tar.gz |
Several changes to fix livelock under high load, introduced by r203489:
- change the way in which command queue overflow is handled;
- do not expose to CAM two command slots, used for driver's internal purposes;
- allow driver to use up to 1024 command slots, instead of 256 before.
Diffstat (limited to 'sys/dev/ciss/ciss.c')
-rw-r--r-- | sys/dev/ciss/ciss.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index 66a046d..7293bb1 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -1353,7 +1353,7 @@ ciss_init_logical(struct ciss_softc *sc) /* sanity-check reply */ ndrives = (ntohl(cll->list_size) / sizeof(union ciss_device_address)); - if ((ndrives < 0) || (ndrives >= CISS_MAX_LOGICAL)) { + if ((ndrives < 0) || (ndrives > CISS_MAX_LOGICAL)) { ciss_printf(sc, "adapter claims to report absurd number of logical drives (%d > %d)\n", ndrives, CISS_MAX_LOGICAL); error = ENXIO; @@ -2791,7 +2791,7 @@ ciss_cam_init(struct ciss_softc *sc) * Allocate a devq. We can reuse this for the masked physical * devices if we decide to export these as well. */ - if ((sc->ciss_cam_devq = cam_simq_alloc(sc->ciss_max_requests)) == NULL) { + if ((sc->ciss_cam_devq = cam_simq_alloc(sc->ciss_max_requests - 2)) == NULL) { ciss_printf(sc, "can't allocate CAM SIM queue\n"); return(ENOMEM); } @@ -3065,7 +3065,7 @@ ciss_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio) */ if ((error = ciss_get_request(sc, &cr)) != 0) { xpt_freeze_simq(sim, 1); - csio->ccb_h.status |= CAM_RELEASE_SIMQ; + sc->ciss_flags |= CISS_FLAG_BUSY; csio->ccb_h.status |= CAM_REQUEUE_REQ; return(error); } @@ -3275,6 +3275,13 @@ ciss_cam_complete(struct ciss_request *cr) ciss_cam_complete_fixup(sc, csio); ciss_release_request(cr); + if (sc->ciss_flags & CISS_FLAG_BUSY) { + sc->ciss_flags &= ~CISS_FLAG_BUSY; + if (csio->ccb_h.status & CAM_RELEASE_SIMQ) + xpt_release_simq(xpt_path_sim(csio->ccb_h.path), 0); + else + csio->ccb_h.status |= CAM_RELEASE_SIMQ; + } xpt_done((union ccb *)csio); } |