And make sure the hotspare kicks in. You HAVE to create the hotspare
under heavy io.
On Tue, Jun 01, 2010 at 11:09:53AM +1000, David Gwynne wrote:
> you cant test a variable and then sleep on it without blocking
> interrupts, cos a completion could change the variables state between
> those two actions.
>
> could anyone test setting a hotspare on ami(4) while doing io?
>
> dlg
>
> Index: ami.c
> ===
> RCS file: /cvs/src/sys/dev/ic/ami.c,v
> retrieving revision 1.204
> diff -u -p ami.c
> --- ami.c 20 May 2010 00:55:17 - 1.204
> +++ ami.c 31 May 2010 12:42:47 -
> @@ -186,11 +186,8 @@ ami_remove_runq(struct ami_ccb *ccb)
> splassert(IPL_BIO);
>
> TAILQ_REMOVE(&ccb->ccb_sc->sc_ccb_runq, ccb, ccb_link);
> - if (TAILQ_EMPTY(&ccb->ccb_sc->sc_ccb_runq)) {
> - ccb->ccb_sc->sc_drained = 1;
> - if (ccb->ccb_sc->sc_drainio)
> - wakeup(ccb->ccb_sc);
> - }
> + if (ccb->ccb_sc->sc_drainio && TAILQ_EMPTY(&ccb->ccb_sc->sc_ccb_runq))
> + wakeup(ccb->ccb_sc);
> }
>
> void
> @@ -198,7 +195,6 @@ ami_insert_runq(struct ami_ccb *ccb)
> {
> splassert(IPL_BIO);
>
> - ccb->ccb_sc->sc_drained = 0;
> TAILQ_INSERT_TAIL(&ccb->ccb_sc->sc_ccb_runq, ccb, ccb_link);
> }
>
> @@ -539,7 +535,6 @@ ami_attach(struct ami_softc *sc)
> /* error already printed */
> goto free_mbox;
> }
> - sc->sc_drained = 1;
>
> /* hack for hp netraid version encoding */
> if ('A' <= sc->sc_fwver[2] && sc->sc_fwver[2] <= 'Z' &&
> @@ -1016,7 +1011,6 @@ ami_runqueue(struct ami_softc *sc)
>
> while ((ccb = TAILQ_FIRST(&sc->sc_ccb_preq)) != NULL) {
> if (sc->sc_exec(sc, &ccb->ccb_cmd) != 0) {
> - /* this is now raceable too with other incoming io */
> timeout_add(&sc->sc_run_tmo, 1);
> break;
> }
> @@ -1895,10 +1889,8 @@ ami_mgmt(struct ami_softc *sc, u_int8_t opcode, u_int8
> goto err;
> }
> ccb->ccb_done = ami_done_ioctl;
> - } else {
> + } else
> ccb = sc->sc_mgmtccb;
> - ccb->ccb_done = ami_done_dummy;
> - }
>
> if (size) {
> if ((am = ami_allocmem(sc, size)) == NULL) {
> @@ -1930,22 +1922,29 @@ ami_mgmt(struct ami_softc *sc, u_int8_t opcode, u_int8
>
> if (opcode != AMI_CHSTATE) {
> ami_start(sc, ccb);
> + s = splbio();
> while (ccb->ccb_state != AMI_CCB_READY)
> tsleep(ccb, PRIBIO,"ami_mgmt", 0);
> + splx(s);
> } else {
> /* change state must be run with id 0xfe and MUST be polled */
> + s = splbio();
> sc->sc_drainio = 1;
> - while (sc->sc_drained != 1)
> + while (!TAILQ_EMPTY(&sc->sc_ccb_runq)) {
> if (tsleep(sc, PRIBIO, "ami_mgmt_drain", hz * 60) ==
> EWOULDBLOCK) {
> printf("%s: drain io timeout\n", DEVNAME(sc));
> ccb->ccb_flags |= AMI_CCB_F_ERR;
> goto restartio;
> }
> - ami_poll(sc, ccb);
> + }
> +
> + error = sc->sc_poll(sc, &ccb->ccb_cmd);
> + if (error == -1)
> + ccb->ccb_flags |= AMI_CCB_F_ERR;
> +
> restartio:
> /* restart io */
> - s = splbio();
> sc->sc_drainio = 0;
> ami_runqueue(sc);
> splx(s);
> @@ -1966,7 +1965,6 @@ memerr:
> } else {
> ccb->ccb_flags = 0;
> ccb->ccb_state = AMI_CCB_FREE;
> - ccb->ccb_done = NULL;
> }
>
> err:
> Index: amivar.h
> ===
> RCS file: /cvs/src/sys/dev/ic/amivar.h,v
> retrieving revision 1.54
> diff -u -p amivar.h
> --- amivar.h 28 Oct 2008 11:43:10 - 1.54
> +++ amivar.h 31 May 2010 12:42:47 -
> @@ -149,7 +149,6 @@ struct ami_softc {
> charsc_plist[AMI_BIG_MAX_PDRIVES];
>
> struct ami_ccb *sc_mgmtccb;
> - int sc_drained;
> int sc_drainio;
> u_int8_tsc_drvinscnt;
> };