From owner-svn-src-all@FreeBSD.ORG Wed Aug 11 17:25:14 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A979B106564A; Wed, 11 Aug 2010 17:25:14 +0000 (UTC) (envelope-from mjacob@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 8CA3F8FC0C; Wed, 11 Aug 2010 17:25:14 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o7BHPEe7021299; Wed, 11 Aug 2010 17:25:14 GMT (envelope-from mjacob@svn.freebsd.org) Received: (from mjacob@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7BHPEmN021296; Wed, 11 Aug 2010 17:25:14 GMT (envelope-from mjacob@svn.freebsd.org) Message-Id: <201008111725.o7BHPEmN021296@svn.freebsd.org> From: Matt Jacob Date: Wed, 11 Aug 2010 17:25:14 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r211183 - in head/tools/tools/vhba: . mptest X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Aug 2010 17:25:14 -0000 Author: mjacob Date: Wed Aug 11 17:25:14 2010 New Revision: 211183 URL: http://svn.freebsd.org/changeset/base/211183 Log: Consistently set us to be SPC3 for our inquiry data. For mptest, add delays to I/O that simulate real disks better. This also allows us to simulate what happens when a device goes away with active transactions. It's pretty spectacular. Sponsored by: Panasas MFC after: 1 month Modified: head/tools/tools/vhba/mptest/vhba_mptest.c head/tools/tools/vhba/vhba.c Modified: head/tools/tools/vhba/mptest/vhba_mptest.c ============================================================================== --- head/tools/tools/vhba/mptest/vhba_mptest.c Wed Aug 11 16:56:38 2010 (r211182) +++ head/tools/tools/vhba/mptest/vhba_mptest.c Wed Aug 11 17:25:14 2010 (r211183) @@ -31,6 +31,17 @@ #include "vhba.h" #include +static int vhba_stop_lun; +static int vhba_start_lun = 0; +static int vhba_notify_stop = 1; +static int vhba_notify_start = 1; +static int vhba_inject_hwerr = 0; +SYSCTL_INT(_debug, OID_AUTO, vhba_stop_lun, CTLFLAG_RW, &vhba_stop_lun, 0, "stop lun bitmap"); +SYSCTL_INT(_debug, OID_AUTO, vhba_start_lun, CTLFLAG_RW, &vhba_start_lun, 0, "start lun bitmap"); +SYSCTL_INT(_debug, OID_AUTO, vhba_notify_stop, CTLFLAG_RW, &vhba_notify_stop, 1, "notify when luns go away"); +SYSCTL_INT(_debug, OID_AUTO, vhba_notify_start, CTLFLAG_RW, &vhba_notify_start, 1, "notify when luns arrive"); +SYSCTL_INT(_debug, OID_AUTO, vhba_inject_hwerr, CTLFLAG_RW, &vhba_inject_hwerr, 0, "inject hardware error on lost luns"); + #define MAX_TGT 1 #define MAX_LUN 2 #define VMP_TIME hz @@ -49,8 +60,11 @@ typedef struct { int luns[2]; struct callout tick; struct task qt; + TAILQ_HEAD(, ccb_hdr) inproc; + int nact, nact_high; } mptest_t; +static timeout_t vhba_iodelay; static timeout_t vhba_timer; static void vhba_task(void *, int); static void mptest_act(mptest_t *, struct ccb_scsiio *); @@ -59,13 +73,17 @@ void vhba_init(vhba_softc_t *vhba) { static mptest_t vhbastatic; + vhbastatic.vhba = vhba; vhbastatic.disk_size = DISK_SIZE << 20; vhbastatic.disk = malloc(vhbastatic.disk_size, M_DEVBUF, M_WAITOK|M_ZERO); vhba->private = &vhbastatic; callout_init_mtx(&vhbastatic.tick, &vhba->lock, 0); callout_reset(&vhbastatic.tick, VMP_TIME, vhba_timer, vhba); + TAILQ_INIT(&vhbastatic.inproc); TASK_INIT(&vhbastatic.qt, 0, vhba_task, &vhbastatic); + vhbastatic.luns[0] = 1; + vhbastatic.luns[1] = 1; } void @@ -89,15 +107,23 @@ vhba_task(void *arg, int pending) { mptest_t *vhbas = arg; struct ccb_hdr *ccbh; + int nadded = 0; mtx_lock(&vhbas->vhba->lock); while ((ccbh = TAILQ_FIRST(&vhbas->vhba->actv)) != NULL) { TAILQ_REMOVE(&vhbas->vhba->actv, ccbh, sim_links.tqe); mptest_act(vhbas, (struct ccb_scsiio *)ccbh); + nadded++; + ccbh->sim_priv.entries[0].ptr = vhbas; + callout_handle_init(&ccbh->timeout_ch); } - while ((ccbh = TAILQ_FIRST(&vhbas->vhba->done)) != NULL) { - TAILQ_REMOVE(&vhbas->vhba->done, ccbh, sim_links.tqe); - xpt_done((union ccb *)ccbh); + if (nadded) { + vhba_kick(vhbas->vhba); + } else { + while ((ccbh = TAILQ_FIRST(&vhbas->vhba->done)) != NULL) { + TAILQ_REMOVE(&vhbas->vhba->done, ccbh, sim_links.tqe); + xpt_done((union ccb *)ccbh); + } } mtx_unlock(&vhbas->vhba->lock); } @@ -108,10 +134,10 @@ mptest_act(mptest_t *vhbas, struct ccb_s char junk[128]; cam_status camstatus; uint8_t *cdb, *ptr, status; - uint32_t data_len; + uint32_t data_len, blkcmd; uint64_t off; - data_len = 0; + blkcmd = data_len = 0; status = SCSI_STATUS_OK; memset(&csio->sense_data, 0, sizeof (csio->sense_data)); @@ -122,6 +148,11 @@ mptest_act(mptest_t *vhbas, struct ccb_s TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe); return; } + if (vhba_inject_hwerr && csio->ccb_h.target_lun < MAX_LUN && vhbas->luns[csio->ccb_h.target_lun] == 0) { + vhba_fill_sense(csio, SSD_KEY_HARDWARE_ERROR, 0x44, 0x0); + TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe); + return; + } if ((csio->ccb_h.target_lun >= MAX_LUN || vhbas->luns[csio->ccb_h.target_lun] == 0) && cdb[0] != INQUIRY && cdb[0] != REPORT_LUNS && cdb[0] != REQUEST_SENSE) { vhba_fill_sense(csio, SSD_KEY_ILLEGAL_REQUEST, 0x25, 0x0); TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe); @@ -284,6 +315,11 @@ mptest_act(mptest_t *vhbas, struct ccb_s vhba_fill_sense(csio, SSD_KEY_ILLEGAL_REQUEST, 0x24, 0x0); break; } + blkcmd++; + if (++vhbas->nact > vhbas->nact_high) { + vhbas->nact_high = vhbas->nact; + printf("%s: high block count now %d\n", __func__, vhbas->nact); + } if (data_len) { if ((cdb[0] & 0xf) == 8) { memcpy(csio->data_ptr, &vhbas->disk[off], data_len); @@ -339,17 +375,36 @@ mptest_act(mptest_t *vhbas, struct ccb_s camstatus = CAM_REQ_CMP; } vhba_set_status(&csio->ccb_h, camstatus); - TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe); + if (blkcmd) { + int ticks; + struct timeval t; + + TAILQ_INSERT_TAIL(&vhbas->inproc, &csio->ccb_h, sim_links.tqe); + t.tv_sec = 0; + t.tv_usec = (500 + arc4random()); + if (t.tv_usec > 10000) { + t.tv_usec = 10000; + } + ticks = tvtohz(&t); + csio->ccb_h.timeout_ch = timeout(vhba_iodelay, &csio->ccb_h, ticks); + } else { + TAILQ_INSERT_TAIL(&vhbas->vhba->done, &csio->ccb_h, sim_links.tqe); + } } -static int vhba_stop_lun; -SYSCTL_INT(_debug, OID_AUTO, vhba_stop_lun, CTLFLAG_RW, &vhba_stop_lun, 0, "stop this lun"); -static int vhba_start_lun = 3; -SYSCTL_INT(_debug, OID_AUTO, vhba_start_lun, CTLFLAG_RW, &vhba_start_lun, 3, "start this lun"); -static int vhba_notify_stop = 1; -SYSCTL_INT(_debug, OID_AUTO, vhba_notify_stop, CTLFLAG_RW, &vhba_notify_stop, 1, "notify when luns go away"); -static int vhba_notify_start = 1; -SYSCTL_INT(_debug, OID_AUTO, vhba_notify_start, CTLFLAG_RW, &vhba_notify_start, 1, "notify when luns arrive"); +static void +vhba_iodelay(void *arg) +{ + struct ccb_hdr *ccbh = arg; + mptest_t *vhbas = ccbh->sim_priv.entries[0].ptr; + + mtx_lock(&vhbas->vhba->lock); + TAILQ_REMOVE(&vhbas->inproc, ccbh, sim_links.tqe); + TAILQ_INSERT_TAIL(&vhbas->vhba->done, ccbh, sim_links.tqe); + vhbas->nact -= 1; + vhba_kick(vhbas->vhba); + mtx_unlock(&vhbas->vhba->lock); +} static void vhba_timer(void *arg) Modified: head/tools/tools/vhba/vhba.c ============================================================================== --- head/tools/tools/vhba/vhba.c Wed Aug 11 16:56:38 2010 (r211182) +++ head/tools/tools/vhba/vhba.c Wed Aug 11 17:25:14 2010 (r211183) @@ -106,7 +106,7 @@ vhba_action(struct cam_sim *sim, union c case XPT_GET_TRAN_SETTINGS: cts = &ccb->cts; - cts->protocol_version = SCSI_REV_SPC2; + cts->protocol_version = SCSI_REV_SPC3; cts->protocol = PROTO_SCSI; cts->transport_version = 0; cts->transport = XPORT_PPB; @@ -133,7 +133,7 @@ vhba_action(struct cam_sim *sim, union c cpi->transport = XPORT_PPB; cpi->base_transfer_speed = 1000000; cpi->protocol = PROTO_SCSI; - cpi->protocol_version = SCSI_REV_SPC2; + cpi->protocol_version = SCSI_REV_SPC3; strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); strlcpy(cpi->hba_vid, "FakeHBA", HBA_IDLEN); strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); @@ -235,14 +235,14 @@ vhba_default_cmd(struct ccb_scsiio *csio { char junk[128]; const uint8_t niliqd[SHORT_INQUIRY_LENGTH] = { - 0x7f, 0x0, 0x5, 0x2, 32, 0, 0, 0x32, + 0x7f, 0x0, SCSI_REV_SPC3, 0x2, 32, 0, 0, 0x32, 'P', 'A', 'N', 'A', 'S', 'A', 'S', ' ', 'N', 'U', 'L', 'L', ' ', 'D', 'E', 'V', 'I', 'C', 'E', ' ', ' ', ' ', ' ', ' ', '0', '0', '0', '1' }; const uint8_t iqd[SHORT_INQUIRY_LENGTH] = { - 0, 0x0, 0x5, 0x2, 32, 0, 0, 0x32, + 0, 0x0, SCSI_REV_SPC3, 0x2, 32, 0, 0, 0x32, 'P', 'A', 'N', 'A', 'S', 'A', 'S', ' ', 'V', 'I', 'R', 'T', ' ', 'M', 'E', 'M', 'O', 'R', 'Y', ' ', 'D', 'I', 'S', 'K',