svn commit: r204648 - head/sys/dev/ciss
Alexander Motin
mav at FreeBSD.org
Wed Mar 3 17:58:41 UTC 2010
Author: mav
Date: Wed Mar 3 17:58:41 2010
New Revision: 204648
URL: http://svn.freebsd.org/changeset/base/204648
Log:
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.
Modified:
head/sys/dev/ciss/ciss.c
head/sys/dev/ciss/cissvar.h
Modified: head/sys/dev/ciss/ciss.c
==============================================================================
--- head/sys/dev/ciss/ciss.c Wed Mar 3 17:56:52 2010 (r204647)
+++ head/sys/dev/ciss/ciss.c Wed Mar 3 17:58:41 2010 (r204648)
@@ -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,
*/
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 *c
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);
}
Modified: head/sys/dev/ciss/cissvar.h
==============================================================================
--- head/sys/dev/ciss/cissvar.h Wed Mar 3 17:56:52 2010 (r204647)
+++ head/sys/dev/ciss/cissvar.h Wed Mar 3 17:58:41 2010 (r204648)
@@ -41,7 +41,7 @@ typedef STAILQ_HEAD(, ciss_request) cr_q
* commands an adapter may claim to support. Cap it at a reasonable
* value.
*/
-#define CISS_MAX_REQUESTS 256
+#define CISS_MAX_REQUESTS 1024
/*
* Maximum number of logical drives we support.
@@ -251,6 +251,7 @@ struct ciss_softc
#define CISS_FLAG_CONTROL_OPEN (1<<1) /* control device is open */
#define CISS_FLAG_ABORTING (1<<2) /* driver is going away */
#define CISS_FLAG_RUNNING (1<<3) /* driver is running (interrupts usable) */
+#define CISS_FLAG_BUSY (1<<4) /* no free commands */
#define CISS_FLAG_FAKE_SYNCH (1<<16) /* needs SYNCHRONISE_CACHE faked */
#define CISS_FLAG_BMIC_ABORT (1<<17) /* use BMIC command to abort Notify on Event */
More information about the svn-src-all
mailing list