Re: softraid iopoolification

2011-04-04 Thread David Gwynne
comments inline...

On 04/04/2011, at 9:01 AM, Kenneth R Westerback wrote:

 Works on my crypto volume. People with other volume types would be nice
 to hear from.

  Ken

 Index: softraid.c
 ===
 RCS file: /cvs/src/sys/dev/softraid.c,v
 retrieving revision 1.222
 diff -u -p -r1.222 softraid.c
 --- softraid.c15 Mar 2011 13:29:41 -  1.222
 +++ softraid.c3 Apr 2011 21:07:48 -
 @@ -1805,7 +1805,7 @@ sr_wu_alloc(struct sr_discipline *sd)
   for (i = 0; i  no_wu; i++) {
   wu = sd-sd_wu[i];
   wu-swu_dis = sd;
 - sr_wu_put(wu);
 + sr_wu_put(sd, wu);
   }

   return (0);
 @@ -1833,17 +1833,15 @@ sr_wu_free(struct sr_discipline *sd)
 }

 void
 -sr_wu_put(struct sr_workunit *wu)
 +sr_wu_put(void *xsd, void *xwu)
 {
 - struct sr_discipline*sd = wu-swu_dis;
 + struct sr_discipline*sd = (struct sr_discipline *)xsd;
 + struct sr_workunit  *wu = (struct sr_workunit *)xwu;
   struct sr_ccb   *ccb;
 -
   int s;

   DNPRINTF(SR_D_WU, %s: sr_wu_put: %p\n, DEVNAME(sd-sd_sc), wu);

 - s = splbio();
 -
   wu-swu_xs = NULL;
   wu-swu_state = SR_WU_FREE;
   wu-swu_ios_complete = 0;
 @@ -1864,9 +1862,12 @@ sr_wu_put(struct sr_workunit *wu)
   }
   TAILQ_INIT(wu-swu_ccb);

 + mtx_enter(sd-sd_wu_mtx);
   TAILQ_INSERT_TAIL(sd-sd_wu_freeq, wu, swu_link);
   sd-sd_wu_pending--;
 + mtx_leave(sd-sd_wu_mtx);

 + s = splbio();
   /* wake up sleepers */
 #ifdef DIAGNOSTIC
   if (sd-sd_wu_sleep  0)
 @@ -1874,34 +1875,23 @@ sr_wu_put(struct sr_workunit *wu)
 #endif /* DIAGNOSTIC */
   if (sd-sd_wu_sleep)
   wakeup(sd-sd_wu_sleep);
 -
   splx(s);
 }

 -struct sr_workunit *
 -sr_wu_get(struct sr_discipline *sd, int canwait)
 +void *
 +sr_wu_get(void *xsd)
 {
 + struct sr_discipline*sd = (struct sr_discipline *)xsd;
   struct sr_workunit  *wu;
 - int s;
 -
 - s = splbio();

 - for (;;) {
 - wu = TAILQ_FIRST(sd-sd_wu_freeq);
 - if (wu) {
 - TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
 - wu-swu_state = SR_WU_INPROGRESS;
 - sd-sd_wu_pending++;
 - break;
 - } else if (wu == NULL  canwait) {
 - sd-sd_wu_sleep++;
 - tsleep(sd-sd_wu_sleep, PRIBIO, sr_wu_get, 0);
 - sd-sd_wu_sleep--;
 - } else
 - break;
 + mtx_enter(sd-sd_wu_mtx);
 + wu = TAILQ_FIRST(sd-sd_wu_freeq);
 + if (wu) {
 + TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
 + wu-swu_state = SR_WU_INPROGRESS;
 + sd-sd_wu_pending++;
   }
 -
 - splx(s);
 + mtx_leave(sd-sd_wu_mtx);

   DNPRINTF(SR_D_WU, %s: sr_wu_get: %p\n, DEVNAME(sd-sd_sc), wu);

 @@ -1949,19 +1939,9 @@ sr_scsi_cmd(struct scsi_xfer *xs)
   goto stuffup;
   }

 - /*
 -  * we'll let the midlayer deal with stalls instead of being clever
 -  * and sending sr_wu_get !(xs-flags  SCSI_NOSLEEP) in cansleep
 -  */
 - if ((wu = sr_wu_get(sd, 0)) == NULL) {
 - DNPRINTF(SR_D_CMD, %s: sr_scsi_cmd no wu\n, DEVNAME(sc));
 - xs-error = XS_NO_CCB;
 - sr_scsi_done(sd, xs);
 - return;
 - }
 -
 - xs-error = XS_NOERROR;
 + wu = xs-io;
   wu-swu_xs = xs;
 + xs-error = XS_NOERROR;

scsi_xs_exec sets xs-error to XS_NOERROR before giving it to this func, so
this is technically unnecessary. not an issue with this diff exactly, just an
interesting factoid.


   /* the midlayer will query LUNs so report sense to stop scanning */
   if (link-target != 0 || link-lun != 0) {
 @@ -2049,10 +2029,9 @@ stuffup:
   xs-error = XS_DRIVER_STUFFUP;
   }
 complete:
 - if (wu)
 - sr_wu_put(wu);
   sr_scsi_done(sd, xs);
 }
 +
 int
 sr_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag)
 {
 @@ -3042,6 +3021,8 @@ sr_ioctl_createraid(struct sr_softc *sc,
   }

   /* setup scsi midlayer */
 + mtx_init(sd-sd_wu_mtx, IPL_BIO);
 + scsi_iopool_init(sd-sd_iopool, sd, sr_wu_get, sr_wu_put);
   if (sd-sd_openings)
   sd-sd_link.openings = sd-sd_openings(sd);
   else
 @@ -3051,6 +3032,7 @@ sr_ioctl_createraid(struct sr_softc *sc,
   sd-sd_link.adapter = sr_switch;
   sd-sd_link.adapter_target = SR_MAX_LD;
   sd-sd_link.adapter_buswidth = 1;
 + sd-sd_link.pool = sd-sd_iopool;
   bzero(saa, sizeof(saa));
   saa.saa_sc_link = sd-sd_link;

 @@ -3953,11 +3935,17 @@ sr_rebuild_thread(void *arg)
   mysize += sz;
   lba = blk * sz;

 -

Re: softraid iopoolification

2011-04-04 Thread Kenneth R Westerback
On Sun, Apr 03, 2011 at 07:01:04PM -0400, Kenneth R Westerback wrote:
 Works on my crypto volume. People with other volume types would be nice
 to hear from.
 
  Ken

v2. Use scsi_io_[get|put](), stop trying so hard to avoid calling scsi_done()
at SPLBIO as this is nice but not necessary, remove random 'improvements' to
make diff as small as possible.

Tests still desired!

 Ken

Index: softraid.c
===
RCS file: /cvs/src/sys/dev/softraid.c,v
retrieving revision 1.222
diff -u -p -r1.222 softraid.c
--- softraid.c  15 Mar 2011 13:29:41 -  1.222
+++ softraid.c  4 Apr 2011 14:36:04 -
@@ -1805,7 +1805,7 @@ sr_wu_alloc(struct sr_discipline *sd)
for (i = 0; i  no_wu; i++) {
wu = sd-sd_wu[i];
wu-swu_dis = sd;
-   sr_wu_put(wu);
+   sr_wu_put(sd, wu);
}
 
return (0);
@@ -1833,9 +1833,10 @@ sr_wu_free(struct sr_discipline *sd)
 }
 
 void
-sr_wu_put(struct sr_workunit *wu)
+sr_wu_put(void *xsd, void *xwu)
 {
-   struct sr_discipline*sd = wu-swu_dis;
+   struct sr_discipline*sd = (struct sr_discipline *)xsd;
+   struct sr_workunit  *wu = (struct sr_workunit *)xwu;
struct sr_ccb   *ccb;
 
int s;
@@ -1864,9 +1865,14 @@ sr_wu_put(struct sr_workunit *wu)
}
TAILQ_INIT(wu-swu_ccb);
 
+   splx(s);
+
+   mtx_enter(sd-sd_wu_mtx);
TAILQ_INSERT_TAIL(sd-sd_wu_freeq, wu, swu_link);
sd-sd_wu_pending--;
+   mtx_leave(sd-sd_wu_mtx);
 
+   s = splbio();
/* wake up sleepers */
 #ifdef DIAGNOSTIC
if (sd-sd_wu_sleep  0)
@@ -1878,30 +1884,20 @@ sr_wu_put(struct sr_workunit *wu)
splx(s);
 }
 
-struct sr_workunit *
-sr_wu_get(struct sr_discipline *sd, int canwait)
+void *
+sr_wu_get(void *xsd)
 {
+   struct sr_discipline*sd = (struct sr_discipline *)xsd;
struct sr_workunit  *wu;
-   int s;
 
-   s = splbio();
-
-   for (;;) {
-   wu = TAILQ_FIRST(sd-sd_wu_freeq);
-   if (wu) {
-   TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
-   wu-swu_state = SR_WU_INPROGRESS;
-   sd-sd_wu_pending++;
-   break;
-   } else if (wu == NULL  canwait) {
-   sd-sd_wu_sleep++;
-   tsleep(sd-sd_wu_sleep, PRIBIO, sr_wu_get, 0);
-   sd-sd_wu_sleep--;
-   } else
-   break;
+   mtx_enter(sd-sd_wu_mtx);
+   wu = TAILQ_FIRST(sd-sd_wu_freeq);
+   if (wu) {
+   TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
+   wu-swu_state = SR_WU_INPROGRESS;
+   sd-sd_wu_pending++;
}
-
-   splx(s);
+   mtx_leave(sd-sd_wu_mtx);
 
DNPRINTF(SR_D_WU, %s: sr_wu_get: %p\n, DEVNAME(sd-sd_sc), wu);
 
@@ -1949,18 +1945,7 @@ sr_scsi_cmd(struct scsi_xfer *xs)
goto stuffup;
}
 
-   /*
-* we'll let the midlayer deal with stalls instead of being clever
-* and sending sr_wu_get !(xs-flags  SCSI_NOSLEEP) in cansleep
-*/
-   if ((wu = sr_wu_get(sd, 0)) == NULL) {
-   DNPRINTF(SR_D_CMD, %s: sr_scsi_cmd no wu\n, DEVNAME(sc));
-   xs-error = XS_NO_CCB;
-   sr_scsi_done(sd, xs);
-   return;
-   }
-
-   xs-error = XS_NOERROR;
+   wu = xs-io;
wu-swu_xs = xs;
 
/* the midlayer will query LUNs so report sense to stop scanning */
@@ -2049,8 +2034,6 @@ stuffup:
xs-error = XS_DRIVER_STUFFUP;
}
 complete:
-   if (wu)
-   sr_wu_put(wu);
sr_scsi_done(sd, xs);
 }
 int
@@ -3042,6 +3025,8 @@ sr_ioctl_createraid(struct sr_softc *sc,
}
 
/* setup scsi midlayer */
+   mtx_init(sd-sd_wu_mtx, IPL_BIO);
+   scsi_iopool_init(sd-sd_iopool, sd, sr_wu_get, sr_wu_put);
if (sd-sd_openings)
sd-sd_link.openings = sd-sd_openings(sd);
else
@@ -3051,6 +3036,7 @@ sr_ioctl_createraid(struct sr_softc *sc,
sd-sd_link.adapter = sr_switch;
sd-sd_link.adapter_target = SR_MAX_LD;
sd-sd_link.adapter_buswidth = 1;
+   sd-sd_link.pool = sd-sd_iopool;
bzero(saa, sizeof(saa));
saa.saa_sc_link = sd-sd_link;
 
@@ -3954,9 +3940,9 @@ sr_rebuild_thread(void *arg)
lba = blk * sz;
 
/* get some wu */
-   if ((wu_r = sr_wu_get(sd, 1)) == NULL)
+   if ((wu_r = scsi_io_get(sd-sd_iopool, 0)) == NULL)
panic(%s: rebuild exhausted wu_r, DEVNAME(sc));
-   if ((wu_w = sr_wu_get(sd, 1)) == NULL)
+   if ((wu_w = scsi_io_get(sd-sd_iopool, 0)) == NULL)

Re: softraid iopoolification

2011-04-04 Thread David Gwynne
this reads fine by me, except for one thing. i worry that it looks like wu's
get lists of ccbs attached to them that are released when the wu is released.
before iopools there was a wu per call to softraids scsi_cmd handler, but now
the same wu can be given to scsi_cmd multiple times. sr_scsi_done should
probably clean up the ccb list before the xs and wu are given back to the
midlayer.

if this isnt a problem and testing goes well, then it has my ok.

the wakeups in sr_wu_put are no longer necessary as the iopool code takes over
responsibility for sleeping for resources. its just extra code, but it doesnt
affect my ok above.

dlg

On 05/04/2011, at 12:47 AM, Kenneth R Westerback wrote:

 On Sun, Apr 03, 2011 at 07:01:04PM -0400, Kenneth R Westerback wrote:
 Works on my crypto volume. People with other volume types would be nice
 to hear from.

  Ken

 v2. Use scsi_io_[get|put](), stop trying so hard to avoid calling
scsi_done()
 at SPLBIO as this is nice but not necessary, remove random 'improvements'
to
 make diff as small as possible.

 Tests still desired!

  Ken

 Index: softraid.c
 ===
 RCS file: /cvs/src/sys/dev/softraid.c,v
 retrieving revision 1.222
 diff -u -p -r1.222 softraid.c
 --- softraid.c15 Mar 2011 13:29:41 -  1.222
 +++ softraid.c4 Apr 2011 14:36:04 -
 @@ -1805,7 +1805,7 @@ sr_wu_alloc(struct sr_discipline *sd)
   for (i = 0; i  no_wu; i++) {
   wu = sd-sd_wu[i];
   wu-swu_dis = sd;
 - sr_wu_put(wu);
 + sr_wu_put(sd, wu);
   }

   return (0);
 @@ -1833,9 +1833,10 @@ sr_wu_free(struct sr_discipline *sd)
 }

 void
 -sr_wu_put(struct sr_workunit *wu)
 +sr_wu_put(void *xsd, void *xwu)
 {
 - struct sr_discipline*sd = wu-swu_dis;
 + struct sr_discipline*sd = (struct sr_discipline *)xsd;
 + struct sr_workunit  *wu = (struct sr_workunit *)xwu;
   struct sr_ccb   *ccb;

   int s;
 @@ -1864,9 +1865,14 @@ sr_wu_put(struct sr_workunit *wu)
   }
   TAILQ_INIT(wu-swu_ccb);

 + splx(s);
 +
 + mtx_enter(sd-sd_wu_mtx);
   TAILQ_INSERT_TAIL(sd-sd_wu_freeq, wu, swu_link);
   sd-sd_wu_pending--;
 + mtx_leave(sd-sd_wu_mtx);

 + s = splbio();
   /* wake up sleepers */
 #ifdef DIAGNOSTIC
   if (sd-sd_wu_sleep  0)
 @@ -1878,30 +1884,20 @@ sr_wu_put(struct sr_workunit *wu)
   splx(s);
 }

 -struct sr_workunit *
 -sr_wu_get(struct sr_discipline *sd, int canwait)
 +void *
 +sr_wu_get(void *xsd)
 {
 + struct sr_discipline*sd = (struct sr_discipline *)xsd;
   struct sr_workunit  *wu;
 - int s;

 - s = splbio();
 -
 - for (;;) {
 - wu = TAILQ_FIRST(sd-sd_wu_freeq);
 - if (wu) {
 - TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
 - wu-swu_state = SR_WU_INPROGRESS;
 - sd-sd_wu_pending++;
 - break;
 - } else if (wu == NULL  canwait) {
 - sd-sd_wu_sleep++;
 - tsleep(sd-sd_wu_sleep, PRIBIO, sr_wu_get, 0);
 - sd-sd_wu_sleep--;
 - } else
 - break;
 + mtx_enter(sd-sd_wu_mtx);
 + wu = TAILQ_FIRST(sd-sd_wu_freeq);
 + if (wu) {
 + TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
 + wu-swu_state = SR_WU_INPROGRESS;
 + sd-sd_wu_pending++;
   }
 -
 - splx(s);
 + mtx_leave(sd-sd_wu_mtx);

   DNPRINTF(SR_D_WU, %s: sr_wu_get: %p\n, DEVNAME(sd-sd_sc), wu);

 @@ -1949,18 +1945,7 @@ sr_scsi_cmd(struct scsi_xfer *xs)
   goto stuffup;
   }

 - /*
 -  * we'll let the midlayer deal with stalls instead of being clever
 -  * and sending sr_wu_get !(xs-flags  SCSI_NOSLEEP) in cansleep
 -  */
 - if ((wu = sr_wu_get(sd, 0)) == NULL) {
 - DNPRINTF(SR_D_CMD, %s: sr_scsi_cmd no wu\n, DEVNAME(sc));
 - xs-error = XS_NO_CCB;
 - sr_scsi_done(sd, xs);
 - return;
 - }
 -
 - xs-error = XS_NOERROR;
 + wu = xs-io;
   wu-swu_xs = xs;

   /* the midlayer will query LUNs so report sense to stop scanning */
 @@ -2049,8 +2034,6 @@ stuffup:
   xs-error = XS_DRIVER_STUFFUP;
   }
 complete:
 - if (wu)
 - sr_wu_put(wu);
   sr_scsi_done(sd, xs);
 }
 int
 @@ -3042,6 +3025,8 @@ sr_ioctl_createraid(struct sr_softc *sc,
   }

   /* setup scsi midlayer */
 + mtx_init(sd-sd_wu_mtx, IPL_BIO);
 + scsi_iopool_init(sd-sd_iopool, sd, sr_wu_get, sr_wu_put);
   if (sd-sd_openings)
   sd-sd_link.openings = sd-sd_openings(sd);
   else
 @@ -3051,6 +3036,7 @@ sr_ioctl_createraid(struct sr_softc *sc,
   sd-sd_link.adapter = sr_switch;
   sd-sd_link.adapter_target = 

Re: softraid iopoolification

2011-04-04 Thread Kenneth R Westerback
On Mon, Apr 04, 2011 at 10:47:37AM -0400, Kenneth R Westerback wrote:
 On Sun, Apr 03, 2011 at 07:01:04PM -0400, Kenneth R Westerback wrote:
  Works on my crypto volume. People with other volume types would be nice
  to hear from.
  
   Ken
 
 v2. Use scsi_io_[get|put](), stop trying so hard to avoid calling scsi_done()
 at SPLBIO as this is nice but not necessary, remove random 'improvements' to
 make diff as small as possible.
 
 Tests still desired!
 
  Ken

v3. Since the scsi layer can optimize things and just re-use a resource
it has been told is no longer neede, make sure to re-initialize the
work units being given to sr_scsi_cmd().

 Ken

Index: softraid.c
===
RCS file: /cvs/src/sys/dev/softraid.c,v
retrieving revision 1.222
diff -u -p -r1.222 softraid.c
--- softraid.c  15 Mar 2011 13:29:41 -  1.222
+++ softraid.c  4 Apr 2011 19:56:28 -
@@ -1805,7 +1805,7 @@ sr_wu_alloc(struct sr_discipline *sd)
for (i = 0; i  no_wu; i++) {
wu = sd-sd_wu[i];
wu-swu_dis = sd;
-   sr_wu_put(wu);
+   sr_wu_put(sd, wu);
}
 
return (0);
@@ -1833,9 +1833,10 @@ sr_wu_free(struct sr_discipline *sd)
 }
 
 void
-sr_wu_put(struct sr_workunit *wu)
+sr_wu_put(void *xsd, void *xwu)
 {
-   struct sr_discipline*sd = wu-swu_dis;
+   struct sr_discipline*sd = (struct sr_discipline *)xsd;
+   struct sr_workunit  *wu = (struct sr_workunit *)xwu;
struct sr_ccb   *ccb;
 
int s;
@@ -1843,65 +1844,37 @@ sr_wu_put(struct sr_workunit *wu)
DNPRINTF(SR_D_WU, %s: sr_wu_put: %p\n, DEVNAME(sd-sd_sc), wu);
 
s = splbio();
-
-   wu-swu_xs = NULL;
-   wu-swu_state = SR_WU_FREE;
-   wu-swu_ios_complete = 0;
-   wu-swu_ios_failed = 0;
-   wu-swu_ios_succeeded = 0;
-   wu-swu_io_count = 0;
-   wu-swu_blk_start = 0;
-   wu-swu_blk_end = 0;
-   wu-swu_collider = NULL;
-   wu-swu_fake = 0;
-   wu-swu_flags = 0;
-
if (wu-swu_cb_active == 1)
-   panic(%s: sr_wu_put, DEVNAME(sd-sd_sc));
+   panic(%s: sr_wu_put got active wu, DEVNAME(sd-sd_sc));
while ((ccb = TAILQ_FIRST(wu-swu_ccb)) != NULL) {
TAILQ_REMOVE(wu-swu_ccb, ccb, ccb_link);
sr_ccb_put(ccb);
}
+   splx(s);
+
+   bzero(wu, sizeof(*wu));
TAILQ_INIT(wu-swu_ccb);
+   wu-swu_dis = sd;
 
+   mtx_enter(sd-sd_wu_mtx);
TAILQ_INSERT_TAIL(sd-sd_wu_freeq, wu, swu_link);
sd-sd_wu_pending--;
-
-   /* wake up sleepers */
-#ifdef DIAGNOSTIC
-   if (sd-sd_wu_sleep  0)
-   panic(negative wu sleepers);
-#endif /* DIAGNOSTIC */
-   if (sd-sd_wu_sleep)
-   wakeup(sd-sd_wu_sleep);
-
-   splx(s);
+   mtx_leave(sd-sd_wu_mtx);
 }
 
-struct sr_workunit *
-sr_wu_get(struct sr_discipline *sd, int canwait)
+void *
+sr_wu_get(void *xsd)
 {
+   struct sr_discipline*sd = (struct sr_discipline *)xsd;
struct sr_workunit  *wu;
-   int s;
-
-   s = splbio();
 
-   for (;;) {
-   wu = TAILQ_FIRST(sd-sd_wu_freeq);
-   if (wu) {
-   TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
-   wu-swu_state = SR_WU_INPROGRESS;
-   sd-sd_wu_pending++;
-   break;
-   } else if (wu == NULL  canwait) {
-   sd-sd_wu_sleep++;
-   tsleep(sd-sd_wu_sleep, PRIBIO, sr_wu_get, 0);
-   sd-sd_wu_sleep--;
-   } else
-   break;
+   mtx_enter(sd-sd_wu_mtx);
+   wu = TAILQ_FIRST(sd-sd_wu_freeq);
+   if (wu) {
+   TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
+   sd-sd_wu_pending++;
}
-
-   splx(s);
+   mtx_leave(sd-sd_wu_mtx);
 
DNPRINTF(SR_D_WU, %s: sr_wu_get: %p\n, DEVNAME(sd-sd_sc), wu);
 
@@ -1924,6 +1897,7 @@ sr_scsi_cmd(struct scsi_xfer *xs)
struct sr_softc *sc = link-adapter_softc;
struct sr_workunit  *wu = NULL;
struct sr_discipline*sd;
+   struct sr_ccb   *ccb;
 
DNPRINTF(SR_D_CMD, %s: sr_scsi_cmd: scsibus%d xs: %p 
flags: %#x\n, DEVNAME(sc), link-scsibus, xs, xs-flags);
@@ -1949,18 +1923,21 @@ sr_scsi_cmd(struct scsi_xfer *xs)
goto stuffup;
}
 
-   /*
-* we'll let the midlayer deal with stalls instead of being clever
-* and sending sr_wu_get !(xs-flags  SCSI_NOSLEEP) in cansleep
-*/
-   if ((wu = sr_wu_get(sd, 0)) == NULL) {
-   DNPRINTF(SR_D_CMD, %s: sr_scsi_cmd no wu\n, DEVNAME(sc));
-   xs-error = XS_NO_CCB;
-   sr_scsi_done(sd, xs);
-   return;
+   wu = xs-io;
+   /* scsi layer *can* re-send wu without calling 

softraid iopoolification

2011-04-03 Thread Kenneth R Westerback
Works on my crypto volume. People with other volume types would be nice
to hear from.

 Ken

Index: softraid.c
===
RCS file: /cvs/src/sys/dev/softraid.c,v
retrieving revision 1.222
diff -u -p -r1.222 softraid.c
--- softraid.c  15 Mar 2011 13:29:41 -  1.222
+++ softraid.c  3 Apr 2011 21:07:48 -
@@ -1805,7 +1805,7 @@ sr_wu_alloc(struct sr_discipline *sd)
for (i = 0; i  no_wu; i++) {
wu = sd-sd_wu[i];
wu-swu_dis = sd;
-   sr_wu_put(wu);
+   sr_wu_put(sd, wu);
}
 
return (0);
@@ -1833,17 +1833,15 @@ sr_wu_free(struct sr_discipline *sd)
 }
 
 void
-sr_wu_put(struct sr_workunit *wu)
+sr_wu_put(void *xsd, void *xwu)
 {
-   struct sr_discipline*sd = wu-swu_dis;
+   struct sr_discipline*sd = (struct sr_discipline *)xsd;
+   struct sr_workunit  *wu = (struct sr_workunit *)xwu;
struct sr_ccb   *ccb;
-
int s;
 
DNPRINTF(SR_D_WU, %s: sr_wu_put: %p\n, DEVNAME(sd-sd_sc), wu);
 
-   s = splbio();
-
wu-swu_xs = NULL;
wu-swu_state = SR_WU_FREE;
wu-swu_ios_complete = 0;
@@ -1864,9 +1862,12 @@ sr_wu_put(struct sr_workunit *wu)
}
TAILQ_INIT(wu-swu_ccb);
 
+   mtx_enter(sd-sd_wu_mtx);
TAILQ_INSERT_TAIL(sd-sd_wu_freeq, wu, swu_link);
sd-sd_wu_pending--;
+   mtx_leave(sd-sd_wu_mtx);
 
+   s = splbio();
/* wake up sleepers */
 #ifdef DIAGNOSTIC
if (sd-sd_wu_sleep  0)
@@ -1874,34 +1875,23 @@ sr_wu_put(struct sr_workunit *wu)
 #endif /* DIAGNOSTIC */
if (sd-sd_wu_sleep)
wakeup(sd-sd_wu_sleep);
-
splx(s);
 }
 
-struct sr_workunit *
-sr_wu_get(struct sr_discipline *sd, int canwait)
+void *
+sr_wu_get(void *xsd)
 {
+   struct sr_discipline*sd = (struct sr_discipline *)xsd;
struct sr_workunit  *wu;
-   int s;
-
-   s = splbio();
 
-   for (;;) {
-   wu = TAILQ_FIRST(sd-sd_wu_freeq);
-   if (wu) {
-   TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
-   wu-swu_state = SR_WU_INPROGRESS;
-   sd-sd_wu_pending++;
-   break;
-   } else if (wu == NULL  canwait) {
-   sd-sd_wu_sleep++;
-   tsleep(sd-sd_wu_sleep, PRIBIO, sr_wu_get, 0);
-   sd-sd_wu_sleep--;
-   } else
-   break;
+   mtx_enter(sd-sd_wu_mtx);
+   wu = TAILQ_FIRST(sd-sd_wu_freeq);
+   if (wu) {
+   TAILQ_REMOVE(sd-sd_wu_freeq, wu, swu_link);
+   wu-swu_state = SR_WU_INPROGRESS;
+   sd-sd_wu_pending++;
}
-
-   splx(s);
+   mtx_leave(sd-sd_wu_mtx);
 
DNPRINTF(SR_D_WU, %s: sr_wu_get: %p\n, DEVNAME(sd-sd_sc), wu);
 
@@ -1949,19 +1939,9 @@ sr_scsi_cmd(struct scsi_xfer *xs)
goto stuffup;
}
 
-   /*
-* we'll let the midlayer deal with stalls instead of being clever
-* and sending sr_wu_get !(xs-flags  SCSI_NOSLEEP) in cansleep
-*/
-   if ((wu = sr_wu_get(sd, 0)) == NULL) {
-   DNPRINTF(SR_D_CMD, %s: sr_scsi_cmd no wu\n, DEVNAME(sc));
-   xs-error = XS_NO_CCB;
-   sr_scsi_done(sd, xs);
-   return;
-   }
-
-   xs-error = XS_NOERROR;
+   wu = xs-io;
wu-swu_xs = xs;
+   xs-error = XS_NOERROR;
 
/* the midlayer will query LUNs so report sense to stop scanning */
if (link-target != 0 || link-lun != 0) {
@@ -2049,10 +2029,9 @@ stuffup:
xs-error = XS_DRIVER_STUFFUP;
}
 complete:
-   if (wu)
-   sr_wu_put(wu);
sr_scsi_done(sd, xs);
 }
+
 int
 sr_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag)
 {
@@ -3042,6 +3021,8 @@ sr_ioctl_createraid(struct sr_softc *sc,
}
 
/* setup scsi midlayer */
+   mtx_init(sd-sd_wu_mtx, IPL_BIO);
+   scsi_iopool_init(sd-sd_iopool, sd, sr_wu_get, sr_wu_put);
if (sd-sd_openings)
sd-sd_link.openings = sd-sd_openings(sd);
else
@@ -3051,6 +3032,7 @@ sr_ioctl_createraid(struct sr_softc *sc,
sd-sd_link.adapter = sr_switch;
sd-sd_link.adapter_target = SR_MAX_LD;
sd-sd_link.adapter_buswidth = 1;
+   sd-sd_link.pool = sd-sd_iopool;
bzero(saa, sizeof(saa));
saa.saa_sc_link = sd-sd_link;
 
@@ -3953,11 +3935,17 @@ sr_rebuild_thread(void *arg)
mysize += sz;
lba = blk * sz;
 
-   /* get some wu */
-   if ((wu_r = sr_wu_get(sd, 1)) == NULL)
-   panic(%s: rebuild exhausted wu_r, DEVNAME(sc));
-   if ((wu_w =