Subject: Draining after adjusting max openings -- not necessary?
To: None <tech-kern@netbsd.org>
From: Jason Thorpe <thorpej@wasabisystems.com>
List: tech-kern
Date: 06/07/2003 20:36:59
--Apple-Mail-2--573191644
Content-Transfer-Encoding: 7bit
Content-Type: text/plain;
charset=US-ASCII;
format=flowed
Folks...
Right now, the ld(4) driver (and some associated drivers, namely
iopsp(4)) wait for commands beyond the new command window to complete
if adjusting the new # of command openings below the number of current
commands running.
I don't think this is necessary... certainly, the scsipi code can
handle the openings count going negative, and a simple change to the ld
driver allows the same thing to happen there (moving the
"wait-for-drain" to the place where it's really needed, during detach).
There is also a problem with adjusting the openings in the iopsp(4)
case. Since adapt_openings actually changes, you can't simply assign a
new value to it in iopsp_adjqparam(). Instead, you must adjust
adapt_openings by the difference between the new and old openings value.
Attached is a patch that addresses both issues. Anyone see any
problems with these changes?
-- Jason R. Thorpe <thorpej@wasabisystems.com>
--Apple-Mail-2--573191644
Content-Disposition: attachment;
filename=lddrain-patch
Content-Transfer-Encoding: 7bit
Content-Type: application/octet-stream;
x-unix-mode=0644;
name="lddrain-patch"
Index: ld.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ld.c,v
retrieving revision 1.23
diff -c -r1.23 ld.c
*** ld.c 2003/06/07 23:37:24 1.23
--- ld.c 2003/06/08 03:34:47
***************
*** 157,175 ****
int
ldadjqparam(struct ld_softc *sc, int max)
{
! int s, rv;
s = splbio();
sc->sc_maxqueuecnt = max;
- if (sc->sc_queuecnt > max) {
- sc->sc_flags |= LDF_DRAIN;
- rv = tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 30 * hz);
- sc->sc_flags &= ~LDF_DRAIN;
- } else
- rv = 0;
splx(s);
! return (rv);
}
int
--- 157,169 ----
int
ldadjqparam(struct ld_softc *sc, int max)
{
! int s;
s = splbio();
sc->sc_maxqueuecnt = max;
splx(s);
! return (0);
}
int
***************
*** 184,191 ****
return (EBUSY);
s = splbio();
sc->sc_flags |= LDF_DETACH;
! rv = ldadjqparam(sc, 0);
splx(s);
return (rv);
--- 178,189 ----
return (EBUSY);
s = splbio();
+ sc->sc_maxqueuecnt = 0;
sc->sc_flags |= LDF_DETACH;
! while (sc->sc_queuecnt > 0) {
! sc->sc_flags |= LDF_DRAIN;
! (void) tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 0);
! }
splx(s);
return (rv);
***************
*** 597,604 ****
biodone(bp);
if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) {
! if ((sc->sc_flags & LDF_DRAIN) != 0)
wakeup(&sc->sc_queuecnt);
ldstart(sc);
}
}
--- 595,604 ----
biodone(bp);
if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) {
! if ((sc->sc_flags & LDF_DRAIN) != 0) {
! sc->sc_flags &= ~LDF_DRAIN;
wakeup(&sc->sc_queuecnt);
+ }
ldstart(sc);
}
}
Index: i2o/iopsp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2o/iopsp.c,v
retrieving revision 1.17
diff -c -r1.17 iopsp.c
*** i2o/iopsp.c 2002/12/06 11:22:25 1.17
--- i2o/iopsp.c 2003/06/08 03:34:48
***************
*** 410,416 ****
struct iop_msg *im;
struct iop_softc *iop;
struct i2o_scsi_scb_exec *mf;
! int error, flags, tid, s;
u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
sc = (void *)chan->chan_adapter->adapt_dev;
--- 410,416 ----
struct iop_msg *im;
struct iop_softc *iop;
struct i2o_scsi_scb_exec *mf;
! int error, flags, tid;
u_int32_t mb[IOP_MAX_MSG_SIZE / sizeof(u_int32_t)];
sc = (void *)chan->chan_adapter->adapt_dev;
***************
*** 496,509 ****
mf->flags |= I2O_SCB_FLAG_XFER_FROM_DEVICE;
}
- s = splbio();
- sc->sc_curqd++;
- splx(s);
-
if (iop_msg_post(iop, im, mb, xs->timeout)) {
- s = splbio();
- sc->sc_curqd--;
- splx(s);
if (xs->datalen != 0)
iop_msg_unmap(iop, im);
iop_msg_free(iop, im);
--- 496,502 ----
***************
*** 631,639 ****
iop_msg_unmap(iop, im);
iop_msg_free(iop, im);
- if (--sc->sc_curqd == sc->sc_adapter.adapt_openings)
- wakeup(&sc->sc_curqd);
-
scsipi_done(xs);
}
--- 624,629 ----
***************
*** 680,687 ****
sc = (struct iopsp_softc *)dv;
s = splbio();
! sc->sc_adapter.adapt_openings = mpi;
! if (mpi < sc->sc_curqd)
! tsleep(&sc->sc_curqd, PWAIT, "iopspdrn", 0);
splx(s);
}
--- 670,676 ----
sc = (struct iopsp_softc *)dv;
s = splbio();
! sc->sc_adapter.adapt_openings += mpi - sc->sc_openings;
! sc->sc_openings = mpi;
splx(s);
}
Index: i2o/iopspvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/i2o/iopspvar.h,v
retrieving revision 1.5
diff -c -r1.5 iopspvar.h
*** i2o/iopspvar.h 2001/08/04 16:54:18 1.5
--- i2o/iopspvar.h 2003/06/08 03:34:48
***************
*** 64,70 ****
struct iop_initiator sc_ii; /* I2O initiator state */
u_short *sc_tidmap; /* Target/LUN -> TID map */
u_int sc_chgind; /* Last LCT change # */
! u_int sc_curqd; /* Current queue depth */
#ifdef I2OVERBOSE
struct iopsp_target *sc_targetmap; /* Target information */
#endif
--- 64,70 ----
struct iop_initiator sc_ii; /* I2O initiator state */
u_short *sc_tidmap; /* Target/LUN -> TID map */
u_int sc_chgind; /* Last LCT change # */
! int sc_openings; /* # command openings */
#ifdef I2OVERBOSE
struct iopsp_target *sc_targetmap; /* Target information */
#endif
--Apple-Mail-2--573191644--