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 -0000 1.222 +++ softraid.c 4 Apr 2011 14:36:04 -0000 @@ -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) panic("%s: rebuild exhausted wu_w", DEVNAME(sc)); /* setup read io */ @@ -4026,8 +4012,8 @@ queued: if (slept == 0) tsleep(sc, PWAIT, "sr_yield", 1); - sr_wu_put(wu_r); - sr_wu_put(wu_w); + scsi_io_put(&sd->sd_iopool, wu_r); + scsi_io_put(&sd->sd_iopool, wu_w); sd->sd_meta->ssd_rebuild = lba; Index: softraid_aoe.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_aoe.c,v retrieving revision 1.17 diff -u -p -r1.17 softraid_aoe.c --- softraid_aoe.c 2 Jul 2010 15:49:25 -0000 1.17 +++ softraid_aoe.c 4 Apr 2011 14:36:05 -0000 @@ -576,9 +576,6 @@ sr_aoe_input(struct aoe_handler *ah, str break; } } - - /* do not change the order of these 2 functions */ - sr_wu_put(wu); sr_scsi_done(sd, xs); } Index: softraid_crypto.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_crypto.c,v retrieving revision 1.63 diff -u -p -r1.63 softraid_crypto.c --- softraid_crypto.c 6 Mar 2011 21:41:57 -0000 1.63 +++ softraid_crypto.c 4 Apr 2011 14:36:06 -0000 @@ -1345,8 +1345,6 @@ sr_crypto_finish_io(struct sr_workunit * sr_crypto_putcryptop(ccb->ccb_opaque); } - /* do not change the order of these 2 functions */ - sr_wu_put(wu); sr_scsi_done(sd, xs); if (sd->sd_sync && sd->sd_wu_pending == 0) Index: softraid_raid0.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_raid0.c,v retrieving revision 1.22 diff -u -p -r1.22 softraid_raid0.c --- softraid_raid0.c 2 Jul 2010 09:20:26 -0000 1.22 +++ softraid_raid0.c 4 Apr 2011 14:36:06 -0000 @@ -456,8 +456,6 @@ sr_raid0_intr(struct buf *bp) printf("%s: wu: %p not on pending queue\n", DEVNAME(sc), wu); - /* do not change the order of these 2 functions */ - sr_wu_put(wu); sr_scsi_done(sd, xs); if (sd->sd_sync && sd->sd_wu_pending == 0) @@ -468,7 +466,6 @@ sr_raid0_intr(struct buf *bp) return; bad: xs->error = XS_DRIVER_STUFFUP; - sr_wu_put(wu); sr_scsi_done(sd, xs); splx(s); } Index: softraid_raid1.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_raid1.c,v retrieving revision 1.26 diff -u -p -r1.26 softraid_raid1.c --- softraid_raid1.c 6 Nov 2010 23:01:56 -0000 1.26 +++ softraid_raid1.c 4 Apr 2011 14:36:06 -0000 @@ -615,8 +615,6 @@ sr_raid1_intr(struct buf *bp) wakeup(wu); } } else { - /* do not change the order of these 2 functions */ - sr_wu_put(wu); scsi_done(xs); } @@ -633,8 +631,6 @@ bad: wu->swu_flags |= SR_WUF_REBUILDIOCOMP; wakeup(wu); } else { - /* do not change the order of these 2 functions */ - sr_wu_put(wu); scsi_done(xs); } Index: softraid_raid6.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_raid6.c,v retrieving revision 1.19 diff -u -p -r1.19 softraid_raid6.c --- softraid_raid6.c 7 Aug 2010 03:50:01 -0000 1.19 +++ softraid_raid6.c 4 Apr 2011 14:36:06 -0000 @@ -480,7 +480,7 @@ sr_raid6_rw(struct sr_workunit *wu) rwmode = (xs->flags & SCSI_DATA_IN) ? M_RFLG : M_WFLG; if (xs->flags & SCSI_DATA_OUT) /* create write workunit */ - if ((wu_w = sr_wu_get(sd, 0)) == NULL) { + if ((wu_w = scsi_io_get(&sd->sd_iopool, SCSI_NOSLEEP)) == NULL){ printf("%s: can't get wu_w", DEVNAME(sd->sd_sc)); goto bad; } @@ -744,7 +744,7 @@ queued: bad: /* wu is unwound by sr_wu_put */ if (wu_w) - sr_wu_put(wu_w); + scsi_io_put(&sd->sd_iopool, wu_w); return (1); } @@ -889,10 +889,10 @@ sr_raid6_intr(struct buf *bp) wakeup(wu); } } else { - /* do not change the order of these 2 functions */ - sr_wu_put(wu); if (xs != NULL) scsi_done(xs); + else + scsi_io_put(&sd->sd_iopool, wu); } if (sd->sd_sync && sd->sd_wu_pending == 0) @@ -908,8 +908,6 @@ bad: wu->swu_flags |= SR_WUF_REBUILDIOCOMP; wakeup(wu); } else { - /* do not change the order of these 2 functions */ - sr_wu_put(wu); scsi_done(xs); } Index: softraid_raidp.c =================================================================== RCS file: /cvs/src/sys/dev/softraid_raidp.c,v retrieving revision 1.19 diff -u -p -r1.19 softraid_raidp.c --- softraid_raidp.c 7 Aug 2010 03:50:01 -0000 1.19 +++ softraid_raidp.c 4 Apr 2011 14:36:07 -0000 @@ -396,7 +396,7 @@ sr_raidp_rw(struct sr_workunit *wu) if (xs->flags & SCSI_DATA_OUT) /* create write workunit */ - if ((wu_w = sr_wu_get(sd, 0)) == NULL) { + if ((wu_w = scsi_io_get(&sd->sd_iopool, SCSI_NOSLEEP)) == NULL){ printf("%s: can't get wu_w", DEVNAME(sd->sd_sc)); goto bad; } @@ -553,7 +553,7 @@ queued: bad: /* wu is unwound by sr_wu_put */ if (wu_w) - sr_wu_put(wu_w); + scsi_io_put(&sd->sd_iopool, wu_w); return (1); } @@ -669,10 +669,10 @@ sr_raidp_intr(struct buf *bp) wakeup(wu); } } else { - /* do not change the order of these 2 functions */ - sr_wu_put(wu); if (xs != NULL) scsi_done(xs); + else + scsi_io_put(&sd->sd_iopool, wu); } if (sd->sd_sync && sd->sd_wu_pending == 0) @@ -688,8 +688,6 @@ bad: wu->swu_flags |= SR_WUF_REBUILDIOCOMP; wakeup(wu); } else { - /* do not change the order of these 2 functions */ - sr_wu_put(wu); scsi_done(xs); } @@ -831,9 +829,9 @@ sr_raidp_scrub(struct sr_discipline *sd) int s, slept; void *xorbuf; - if ((wu_r = sr_wu_get(sd, 1)) == NULL) + if ((wu_w = scsi_io_get(&sd->sd_iopool, 0)) == NULL) goto done; - if ((wu_w = sr_wu_get(sd, 1)) == NULL) + if ((wu_r = scsi_io_get(&sd->sd_iopool, 0)) == NULL) goto done; no_chunk = sd->sd_meta->ssdi.ssd_chunk_no - 1; Index: softraidvar.h =================================================================== RCS file: /cvs/src/sys/dev/softraidvar.h,v retrieving revision 1.98 diff -u -p -r1.98 softraidvar.h --- softraidvar.h 15 Mar 2011 13:29:41 -0000 1.98 +++ softraidvar.h 4 Apr 2011 14:36:07 -0000 @@ -526,6 +526,9 @@ struct sr_discipline { struct sr_wu_list sd_wu_defq; /* deferred wu queue */ int sd_wu_sleep; /* wu sleepers counter */ + struct mutex sd_wu_mtx; + struct scsi_iopool sd_iopool; + /* discipline stats */ int sd_wu_pending; u_int64_t sd_wu_collisions; @@ -604,8 +607,8 @@ struct sr_ccb *sr_ccb_get(struct sr_dis void sr_ccb_put(struct sr_ccb *); int sr_wu_alloc(struct sr_discipline *); void sr_wu_free(struct sr_discipline *); -struct sr_workunit *sr_wu_get(struct sr_discipline *, int); -void sr_wu_put(struct sr_workunit *); +void *sr_wu_get(void *); +void sr_wu_put(void *, void *); /* misc functions */ int32_t sr_validate_stripsize(u_int32_t);