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 -0000      1.204
> +++ ami.c     31 May 2010 12:42:47 -0000
> @@ -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 -0000      1.54
> +++ amivar.h  31 May 2010 12:42:47 -0000
> @@ -149,7 +149,6 @@ struct ami_softc {
>       char                    sc_plist[AMI_BIG_MAX_PDRIVES];
>  
>       struct ami_ccb          *sc_mgmtccb;
> -     int                     sc_drained;
>       int                     sc_drainio;
>       u_int8_t                sc_drvinscnt;
>  };

Reply via email to