From owner-svn-src-stable-9@FreeBSD.ORG Wed Oct 9 18:58:30 2013 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id BE6996F5; Wed, 9 Oct 2013 18:58:30 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id AA1EF2D56; Wed, 9 Oct 2013 18:58:30 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r99IwUOI059877; Wed, 9 Oct 2013 18:58:30 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r99IwSF8059867; Wed, 9 Oct 2013 18:58:28 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201310091858.r99IwSF8059867@svn.freebsd.org> From: Alexander Motin Date: Wed, 9 Oct 2013 18:58:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r256216 - in stable/9/sys/cam: . ata ctl scsi X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 09 Oct 2013 18:58:30 -0000 Author: mav Date: Wed Oct 9 18:58:28 2013 New Revision: 256216 URL: http://svnweb.freebsd.org/changeset/base/256216 Log: MFC r249466, r249481, r250025: Remove multilevel freezing mechanism, implemented to handle specifics of the ATA/SATA error recovery, when post-reset recovery commands should be allocated when queues are already full of payload requests. Instead of removing frozen CCBs with specified range of priorities from the queue to provide free openings, use simple hack, allowing explicit CCBs over- allocation for requests with priority higher (numerically lower) then CAM_PRIORITY_OOB threshold. Simplify CCB allocation logic by removing SIM-level allocation queue. After that SIM-level queue manages only CCBs execution, while allocation logic is localized within each single device. Modified: stable/9/sys/cam/ata/ata_da.c stable/9/sys/cam/ata/ata_xpt.c stable/9/sys/cam/cam.h stable/9/sys/cam/cam_ccb.h stable/9/sys/cam/cam_periph.c stable/9/sys/cam/cam_periph.h stable/9/sys/cam/cam_queue.c stable/9/sys/cam/cam_queue.h stable/9/sys/cam/cam_xpt.c stable/9/sys/cam/cam_xpt_internal.h stable/9/sys/cam/cam_xpt_sim.h stable/9/sys/cam/ctl/scsi_ctl.c stable/9/sys/cam/scsi/scsi_cd.c stable/9/sys/cam/scsi/scsi_pass.c stable/9/sys/cam/scsi/scsi_xpt.c Modified: stable/9/sys/cam/ata/ata_da.c ============================================================================== --- stable/9/sys/cam/ata/ata_da.c Wed Oct 9 18:48:10 2013 (r256215) +++ stable/9/sys/cam/ata/ata_da.c Wed Oct 9 18:58:28 2013 (r256216) @@ -1022,8 +1022,6 @@ adaasync(void *callback_arg, u_int32_t c else break; cam_periph_acquire(periph); - cam_freeze_devq_arg(periph->path, - RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1); xpt_schedule(periph, CAM_PRIORITY_DEV); } default: @@ -1359,15 +1357,11 @@ adaregister(struct cam_periph *periph, v cgd->ident_data.support.command1 & ATA_SUPPORT_LOOKAHEAD) { softc->state = ADA_STATE_RAHEAD; cam_periph_acquire(periph); - cam_freeze_devq_arg(periph->path, - RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1); xpt_schedule(periph, CAM_PRIORITY_DEV); } else if (ADA_WC >= 0 && cgd->ident_data.support.command1 & ATA_SUPPORT_WRITECACHE) { softc->state = ADA_STATE_WCACHE; cam_periph_acquire(periph); - cam_freeze_devq_arg(periph->path, - RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1); xpt_schedule(periph, CAM_PRIORITY_DEV); } else softc->state = ADA_STATE_NORMAL; @@ -1659,8 +1653,6 @@ out: if ((periph->flags & CAM_PERIPH_INVALID) != 0) { softc->state = ADA_STATE_NORMAL; xpt_release_ccb(start_ccb); - cam_release_devq(periph->path, - RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE); adaschedule(periph); cam_periph_release_locked(periph); return; @@ -1684,6 +1676,7 @@ out: ATA_SF_ENAB_WCACHE : ATA_SF_DIS_WCACHE, 0, 0); start_ccb->ccb_h.ccb_state = ADA_CCB_WCACHE; } + start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE; xpt_action(start_ccb); break; } @@ -1696,12 +1689,14 @@ adadone(struct cam_periph *periph, union struct ada_softc *softc; struct ccb_ataio *ataio; struct ccb_getdev *cgd; + struct cam_path *path; int state; softc = (struct ada_softc *)periph->softc; ataio = &done_ccb->ataio; + path = done_ccb->ccb_h.path; - CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adadone\n")); + CAM_DEBUG(path, CAM_DEBUG_TRACE, ("adadone\n")); state = ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK; switch (state) { @@ -1718,7 +1713,7 @@ adadone(struct cam_periph *periph, union return; } if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) - cam_release_devq(done_ccb->ccb_h.path, + cam_release_devq(path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, @@ -1771,9 +1766,12 @@ adadone(struct cam_periph *periph, union { if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (adaerror(done_ccb, 0, 0) == ERESTART) { +out: + /* Drop freeze taken due to CAM_DEV_QFREEZE */ + cam_release_devq(path, 0, 0, 0, FALSE); return; } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { - cam_release_devq(done_ccb->ccb_h.path, + cam_release_devq(path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, @@ -1790,7 +1788,7 @@ adadone(struct cam_periph *periph, union * operation. */ cgd = (struct ccb_getdev *)done_ccb; - xpt_setup_ccb(&cgd->ccb_h, periph->path, CAM_PRIORITY_NORMAL); + xpt_setup_ccb(&cgd->ccb_h, path, CAM_PRIORITY_NORMAL); cgd->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action((union ccb *)cgd); if (ADA_WC >= 0 && @@ -1798,12 +1796,12 @@ adadone(struct cam_periph *periph, union softc->state = ADA_STATE_WCACHE; xpt_release_ccb(done_ccb); xpt_schedule(periph, CAM_PRIORITY_DEV); - return; + goto out; } softc->state = ADA_STATE_NORMAL; xpt_release_ccb(done_ccb); - cam_release_devq(periph->path, - RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE); + /* Drop freeze taken due to CAM_DEV_QFREEZE */ + cam_release_devq(path, 0, 0, 0, FALSE); adaschedule(periph); cam_periph_release_locked(periph); return; @@ -1812,9 +1810,9 @@ adadone(struct cam_periph *periph, union { if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (adaerror(done_ccb, 0, 0) == ERESTART) { - return; + goto out; } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { - cam_release_devq(done_ccb->ccb_h.path, + cam_release_devq(path, /*relsim_flags*/0, /*reduction*/0, /*timeout*/0, @@ -1832,8 +1830,8 @@ adadone(struct cam_periph *periph, union * operation. */ xpt_release_ccb(done_ccb); - cam_release_devq(periph->path, - RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE); + /* Drop freeze taken due to CAM_DEV_QFREEZE */ + cam_release_devq(path, 0, 0, 0, FALSE); adaschedule(periph); cam_periph_release_locked(periph); return; Modified: stable/9/sys/cam/ata/ata_xpt.c ============================================================================== --- stable/9/sys/cam/ata/ata_xpt.c Wed Oct 9 18:48:10 2013 (r256215) +++ stable/9/sys/cam/ata/ata_xpt.c Wed Oct 9 18:58:28 2013 (r256216) @@ -249,12 +249,6 @@ proberegister(struct cam_periph *periph, return (status); } CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe started\n")); - - /* - * Ensure nobody slip in until probe finish. - */ - cam_freeze_devq_arg(periph->path, - RELSIM_RELEASE_RUNLEVEL, CAM_RL_XPT + 1); probeschedule(periph); return(CAM_REQ_CMP); } @@ -661,6 +655,7 @@ negotiate: default: panic("probestart: invalid action state 0x%x\n", softc->action); } + start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE; xpt_action(start_ccb); } @@ -708,12 +703,15 @@ probedone(struct cam_periph *periph, uni if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if (cam_periph_error(done_ccb, 0, softc->restart ? (SF_NO_RECOVERY | SF_NO_RETRY) : 0, - NULL) == ERESTART) + NULL) == ERESTART) { +out: + /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */ + cam_release_devq(path, 0, 0, 0, FALSE); return; + } if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { /* Don't wedge the queue */ - xpt_release_devq(done_ccb->ccb_h.path, /*count*/1, - /*run_queue*/TRUE); + xpt_release_devq(path, /*count*/1, /*run_queue*/TRUE); } status = done_ccb->ccb_h.status & CAM_STATUS_MASK; if (softc->restart) { @@ -768,7 +766,7 @@ probedone(struct cam_periph *periph, uni PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SAFTE); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } /* @@ -830,7 +828,7 @@ noerror: } xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } case PROBE_IDENTIFY: { @@ -864,7 +862,7 @@ noerror: PROBE_SET_ACTION(softc, PROBE_SPINUP); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } ident_buf = &path->device->ident_data; if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) { @@ -955,7 +953,7 @@ noerror: PROBE_SET_ACTION(softc, PROBE_SETMODE); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } case PROBE_SPINUP: if (bootverbose) @@ -964,7 +962,7 @@ noerror: PROBE_SET_ACTION(softc, PROBE_IDENTIFY); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; case PROBE_SETMODE: /* Set supported bits. */ bzero(&cts, sizeof(cts)); @@ -1035,7 +1033,7 @@ noerror: PROBE_SET_ACTION(softc, PROBE_SETPM); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } /* FALLTHROUGH */ case PROBE_SETPM: @@ -1046,7 +1044,7 @@ noerror: PROBE_SET_ACTION(softc, PROBE_SETAPST); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } /* FALLTHROUGH */ case PROBE_SETAPST: @@ -1056,7 +1054,7 @@ noerror: PROBE_SET_ACTION(softc, PROBE_SETDMAAA); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } /* FALLTHROUGH */ case PROBE_SETDMAAA: @@ -1066,7 +1064,7 @@ noerror: PROBE_SET_ACTION(softc, PROBE_SETAN); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } /* FALLTHROUGH */ case PROBE_SETAN: @@ -1078,15 +1076,14 @@ notsata: } xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; case PROBE_SET_MULTI: if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) { path->device->flags &= ~CAM_DEV_UNCONFIGURED; xpt_acquire_device(path->device); done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); - xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, - done_ccb); + xpt_async(AC_FOUND_DEVICE, path, done_ccb); } PROBE_SET_ACTION(softc, PROBE_DONE); break; @@ -1119,7 +1116,7 @@ notsata: PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; } ata_device_transport(path); @@ -1128,7 +1125,7 @@ notsata: xpt_acquire_device(path->device); done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); - xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb); + xpt_async(AC_FOUND_DEVICE, path, done_ccb); } PROBE_SET_ACTION(softc, PROBE_DONE); break; @@ -1146,7 +1143,7 @@ notsata: PROBE_SET_ACTION(softc, PROBE_PM_PRV); xpt_release_ccb(done_ccb); xpt_schedule(periph, priority); - return; + goto out; case PROBE_PM_PRV: softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) + (done_ccb->ataio.res.lba_mid << 16) + @@ -1201,12 +1198,11 @@ notsata: xpt_acquire_device(path->device); done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); - xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, - done_ccb); + xpt_async(AC_FOUND_DEVICE, path, done_ccb); } else { done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); - xpt_async(AC_SCSI_AEN, done_ccb->ccb_h.path, done_ccb); + xpt_async(AC_SCSI_AEN, path, done_ccb); } PROBE_SET_ACTION(softc, PROBE_DONE); break; @@ -1251,8 +1247,7 @@ notsata: xpt_acquire_device(path->device); done_ccb->ccb_h.func_code = XPT_GDEV_TYPE; xpt_action(done_ccb); - xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, - done_ccb); + xpt_async(AC_FOUND_DEVICE, path, done_ccb); } PROBE_SET_ACTION(softc, PROBE_DONE); break; @@ -1264,7 +1259,7 @@ done: softc->restart = 0; xpt_release_ccb(done_ccb); probeschedule(periph); - return; + goto out; } xpt_release_ccb(done_ccb); CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n")); @@ -1274,9 +1269,9 @@ done: done_ccb->ccb_h.status = found ? CAM_REQ_CMP : CAM_REQ_CMP_ERR; xpt_done(done_ccb); } + /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */ + cam_release_devq(path, 0, 0, 0, FALSE); cam_periph_invalidate(periph); - cam_release_devq(periph->path, - RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE); cam_periph_release_locked(periph); } Modified: stable/9/sys/cam/cam.h ============================================================================== --- stable/9/sys/cam/cam.h Wed Oct 9 18:48:10 2013 (r256215) +++ stable/9/sys/cam/cam.h Wed Oct 9 18:58:28 2013 (r256216) @@ -80,10 +80,9 @@ typedef struct { #define CAM_PRIORITY_BUS ((CAM_RL_BUS << 8) + 0x80) #define CAM_PRIORITY_XPT ((CAM_RL_XPT << 8) + 0x80) #define CAM_PRIORITY_DEV ((CAM_RL_DEV << 8) + 0x80) +#define CAM_PRIORITY_OOB (CAM_RL_DEV << 8) #define CAM_PRIORITY_NORMAL ((CAM_RL_NORMAL << 8) + 0x80) #define CAM_PRIORITY_NONE (u_int32_t)-1 -#define CAM_PRIORITY_TO_RL(x) ((x) >> 8) -#define CAM_RL_TO_PRIORITY(x) ((x) << 8) u_int32_t generation; int index; #define CAM_UNQUEUED_INDEX -1 Modified: stable/9/sys/cam/cam_ccb.h ============================================================================== --- stable/9/sys/cam/cam_ccb.h Wed Oct 9 18:48:10 2013 (r256215) +++ stable/9/sys/cam/cam_ccb.h Wed Oct 9 18:58:28 2013 (r256216) @@ -150,8 +150,6 @@ typedef enum { /* Path statistics (error counts, etc.) */ XPT_GDEV_STATS = 0x0c, /* Device statistics (error counts, etc.) */ - XPT_FREEZE_QUEUE = 0x0d, - /* Freeze device queue */ XPT_DEV_ADVINFO = 0x0e, /* Get/Set Device advanced information */ /* SCSI Control Functions: 0x10->0x1F */ @@ -755,7 +753,6 @@ struct ccb_relsim { #define RELSIM_RELEASE_AFTER_TIMEOUT 0x02 #define RELSIM_RELEASE_AFTER_CMDCMPLT 0x04 #define RELSIM_RELEASE_AFTER_QEMPTY 0x08 -#define RELSIM_RELEASE_RUNLEVEL 0x10 u_int32_t openings; u_int32_t release_timeout; /* Abstract argument. */ u_int32_t qfrozen_cnt; Modified: stable/9/sys/cam/cam_periph.c ============================================================================== --- stable/9/sys/cam/cam_periph.c Wed Oct 9 18:48:10 2013 (r256215) +++ stable/9/sys/cam/cam_periph.c Wed Oct 9 18:58:28 2013 (r256216) @@ -1113,21 +1113,12 @@ cam_periph_runccb(union ccb *ccb, void cam_freeze_devq(struct cam_path *path) { + struct ccb_hdr ccb_h; - cam_freeze_devq_arg(path, 0, 0); -} - -void -cam_freeze_devq_arg(struct cam_path *path, uint32_t flags, uint32_t arg) -{ - struct ccb_relsim crs; - - xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NONE); - crs.ccb_h.func_code = XPT_FREEZE_QUEUE; - crs.release_flags = flags; - crs.openings = arg; - crs.release_timeout = arg; - xpt_action((union ccb *)&crs); + xpt_setup_ccb(&ccb_h, path, /*priority*/1); + ccb_h.func_code = XPT_NOOP; + ccb_h.flags = CAM_DEV_QFREEZE; + xpt_action((union ccb *)&ccb_h); } u_int32_t Modified: stable/9/sys/cam/cam_periph.h ============================================================================== --- stable/9/sys/cam/cam_periph.h Wed Oct 9 18:48:10 2013 (r256215) +++ stable/9/sys/cam/cam_periph.h Wed Oct 9 18:58:28 2013 (r256216) @@ -171,8 +171,6 @@ int cam_periph_ioctl(struct cam_periph cam_flags camflags, u_int32_t sense_flags)); void cam_freeze_devq(struct cam_path *path); -void cam_freeze_devq_arg(struct cam_path *path, u_int32_t flags, - uint32_t arg); u_int32_t cam_release_devq(struct cam_path *path, u_int32_t relsim_flags, u_int32_t opening_reduction, u_int32_t arg, int getcount_only); Modified: stable/9/sys/cam/cam_queue.c ============================================================================== --- stable/9/sys/cam/cam_queue.c Wed Oct 9 18:48:10 2013 (r256215) +++ stable/9/sys/cam/cam_queue.c Wed Oct 9 18:58:28 2013 (r256216) @@ -230,15 +230,8 @@ int cam_devq_init(struct cam_devq *devq, int devices, int openings) { bzero(devq, sizeof(*devq)); - if (camq_init(&devq->alloc_queue, devices) != 0) { + if (camq_init(&devq->send_queue, devices) != 0) return (1); - } - if (camq_init(&devq->send_queue, devices) != 0) { - camq_fini(&devq->alloc_queue); - return (1); - } - devq->alloc_openings = openings; - devq->alloc_active = 0; devq->send_openings = openings; devq->send_active = 0; return (0); @@ -247,7 +240,6 @@ cam_devq_init(struct cam_devq *devq, int void cam_devq_free(struct cam_devq *devq) { - camq_fini(&devq->alloc_queue); camq_fini(&devq->send_queue); free(devq, M_CAMDEVQ); } @@ -257,11 +249,7 @@ cam_devq_resize(struct cam_devq *camq, i { u_int32_t retval; - retval = camq_resize(&camq->alloc_queue, devices); - - if (retval == CAM_REQ_CMP) - retval = camq_resize(&camq->send_queue, devices); - + retval = camq_resize(&camq->send_queue, devices); return (retval); } @@ -328,11 +316,10 @@ int cam_ccbq_init(struct cam_ccbq *ccbq, int openings) { bzero(ccbq, sizeof(*ccbq)); - if (camq_init(&ccbq->queue, openings + (CAM_RL_VALUES - 1)) != 0) { + if (camq_init(&ccbq->queue, openings + (CAM_RL_VALUES - 1)) != 0) return (1); - } ccbq->devq_openings = openings; - ccbq->dev_openings = openings; + ccbq->dev_openings = openings; return (0); } Modified: stable/9/sys/cam/cam_queue.h ============================================================================== --- stable/9/sys/cam/cam_queue.h Wed Oct 9 18:48:10 2013 (r256215) +++ stable/9/sys/cam/cam_queue.h Wed Oct 9 18:58:28 2013 (r256216) @@ -48,7 +48,7 @@ struct camq { int array_size; int entries; u_int32_t generation; - u_int32_t qfrozen_cnt[CAM_RL_VALUES]; + u_int32_t qfrozen_cnt; }; TAILQ_HEAD(ccb_hdr_tailq, ccb_hdr); @@ -58,7 +58,8 @@ SLIST_HEAD(ccb_hdr_slist, ccb_hdr); struct cam_ccbq { struct camq queue; int devq_openings; - int dev_openings; + int devq_allocating; + int dev_openings; int dev_active; int held; }; @@ -66,11 +67,7 @@ struct cam_ccbq { struct cam_ed; struct cam_devq { - struct camq alloc_queue; struct camq send_queue; - struct cam_ed *active_dev; - int alloc_openings; - int alloc_active; int send_openings; int send_active; }; @@ -158,10 +155,10 @@ cam_ccbq_pending_ccb_count(struct cam_cc static __inline void cam_ccbq_take_opening(struct cam_ccbq *ccbq); -static __inline int +static __inline void cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb); -static __inline int +static __inline void cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb); static __inline union ccb * @@ -190,31 +187,17 @@ cam_ccbq_take_opening(struct cam_ccbq *c ccbq->held++; } -static __inline int +static __inline void cam_ccbq_insert_ccb(struct cam_ccbq *ccbq, union ccb *new_ccb) { ccbq->held--; camq_insert(&ccbq->queue, &new_ccb->ccb_h.pinfo); - if (ccbq->queue.qfrozen_cnt[CAM_PRIORITY_TO_RL( - new_ccb->ccb_h.pinfo.priority)] > 0) { - ccbq->devq_openings++; - ccbq->held++; - return (1); - } else - return (0); } -static __inline int +static __inline void cam_ccbq_remove_ccb(struct cam_ccbq *ccbq, union ccb *ccb) { camq_remove(&ccbq->queue, ccb->ccb_h.pinfo.index); - if (ccbq->queue.qfrozen_cnt[CAM_PRIORITY_TO_RL( - ccb->ccb_h.pinfo.priority)] > 0) { - ccbq->devq_openings--; - ccbq->held--; - return (1); - } else - return (0); } static __inline union ccb * @@ -248,81 +231,5 @@ cam_ccbq_release_opening(struct cam_ccbq ccbq->devq_openings++; } -static __inline int -cam_ccbq_freeze(struct cam_ccbq *ccbq, cam_rl rl, u_int32_t cnt) -{ - int i, frozen = 0; - cam_rl p, n; - - /* Find pevious run level. */ - for (p = 0; p < CAM_RL_VALUES && ccbq->queue.qfrozen_cnt[p] == 0; p++); - /* Find new run level. */ - n = min(rl, p); - /* Apply new run level. */ - for (i = rl; i < CAM_RL_VALUES; i++) - ccbq->queue.qfrozen_cnt[i] += cnt; - /* Update ccbq statistics. */ - if (n == p) - return (0); - for (i = CAMQ_HEAD; i <= ccbq->queue.entries; i++) { - cam_rl rrl = - CAM_PRIORITY_TO_RL(ccbq->queue.queue_array[i]->priority); - if (rrl < n) - continue; - if (rrl >= p) - break; - ccbq->devq_openings++; - ccbq->held++; - frozen++; - } - return (frozen); -} - -static __inline int -cam_ccbq_release(struct cam_ccbq *ccbq, cam_rl rl, u_int32_t cnt) -{ - int i, released = 0; - cam_rl p, n; - - /* Apply new run level. */ - for (i = rl; i < CAM_RL_VALUES; i++) - ccbq->queue.qfrozen_cnt[i] -= cnt; - /* Find new run level. */ - for (n = 0; n < CAM_RL_VALUES && ccbq->queue.qfrozen_cnt[n] == 0; n++); - /* Find previous run level. */ - p = min(rl, n); - /* Update ccbq statistics. */ - if (n == p) - return (0); - for (i = CAMQ_HEAD; i <= ccbq->queue.entries; i++) { - cam_rl rrl = - CAM_PRIORITY_TO_RL(ccbq->queue.queue_array[i]->priority); - if (rrl < p) - continue; - if (rrl >= n) - break; - ccbq->devq_openings--; - ccbq->held--; - released++; - } - return (released); -} - -static __inline u_int32_t -cam_ccbq_frozen(struct cam_ccbq *ccbq, cam_rl rl) -{ - - return (ccbq->queue.qfrozen_cnt[rl]); -} - -static __inline u_int32_t -cam_ccbq_frozen_top(struct cam_ccbq *ccbq) -{ - cam_rl rl; - - rl = CAM_PRIORITY_TO_RL(CAMQ_GET_PRIO(&ccbq->queue)); - return (ccbq->queue.qfrozen_cnt[rl]); -} - #endif /* _KERNEL */ #endif /* _CAM_CAM_QUEUE_H */ Modified: stable/9/sys/cam/cam_xpt.c ============================================================================== --- stable/9/sys/cam/cam_xpt.c Wed Oct 9 18:48:10 2013 (r256215) +++ stable/9/sys/cam/cam_xpt.c Wed Oct 9 18:58:28 2013 (r256216) @@ -225,13 +225,13 @@ static void xpt_async_bcast(struct asyn static path_id_t xptnextfreepathid(void); static path_id_t xptpathid(const char *sim_name, int sim_unit, int sim_bus); static union ccb *xpt_get_ccb(struct cam_ed *device); -static void xpt_run_dev_allocq(struct cam_eb *bus); -static void xpt_run_dev_sendq(struct cam_eb *bus); +static void xpt_run_dev_allocq(struct cam_ed *device); +static void xpt_run_devq(struct cam_devq *devq); static timeout_t xpt_release_devq_timeout; static void xpt_release_simq_timeout(void *arg) __unused; static void xpt_release_bus(struct cam_eb *bus); -static void xpt_release_devq_device(struct cam_ed *dev, cam_rl rl, - u_int count, int run_queue); +static void xpt_release_devq_device(struct cam_ed *dev, u_int count, + int run_queue); static struct cam_et* xpt_alloc_target(struct cam_eb *bus, target_id_t target_id); static void xpt_release_target(struct cam_et *target); @@ -298,49 +298,24 @@ static xpt_busfunc_t xptsetasyncbusfunc; static cam_status xptregister(struct cam_periph *periph, void *arg); static __inline int periph_is_queued(struct cam_periph *periph); -static __inline int device_is_alloc_queued(struct cam_ed *device); -static __inline int device_is_send_queued(struct cam_ed *device); +static __inline int device_is_queued(struct cam_ed *device); static __inline int -xpt_schedule_dev_allocq(struct cam_eb *bus, struct cam_ed *dev) -{ - int retval; - - if ((dev->drvq.entries > 0) && - (dev->ccbq.devq_openings > 0) && - (cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL( - CAMQ_GET_PRIO(&dev->drvq))) == 0)) { - /* - * The priority of a device waiting for CCB resources - * is that of the highest priority peripheral driver - * enqueued. - */ - retval = xpt_schedule_dev(&bus->sim->devq->alloc_queue, - &dev->alloc_ccb_entry.pinfo, - CAMQ_GET_PRIO(&dev->drvq)); - } else { - retval = 0; - } - - return (retval); -} - -static __inline int -xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev) +xpt_schedule_devq(struct cam_devq *devq, struct cam_ed *dev) { int retval; if ((dev->ccbq.queue.entries > 0) && (dev->ccbq.dev_openings > 0) && - (cam_ccbq_frozen_top(&dev->ccbq) == 0)) { + (dev->ccbq.queue.qfrozen_cnt == 0)) { /* * The priority of a device waiting for controller * resources is that of the highest priority CCB * enqueued. */ retval = - xpt_schedule_dev(&bus->sim->devq->send_queue, - &dev->send_ccb_entry.pinfo, + xpt_schedule_dev(&devq->send_queue, + &dev->devq_entry.pinfo, CAMQ_GET_PRIO(&dev->ccbq.queue)); } else { retval = 0; @@ -355,15 +330,9 @@ periph_is_queued(struct cam_periph *peri } static __inline int -device_is_alloc_queued(struct cam_ed *device) -{ - return (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX); -} - -static __inline int -device_is_send_queued(struct cam_ed *device) +device_is_queued(struct cam_ed *device) { - return (device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX); + return (device->devq_entry.pinfo.index != CAM_UNQUEUED_INDEX); } static void @@ -2592,17 +2561,10 @@ xpt_action_default(union ccb *start_ccb) case XPT_RESET_DEV: case XPT_ENG_EXEC: case XPT_SMP_IO: - { - int frozen; - - frozen = cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb); - path->device->sim->devq->alloc_openings += frozen; - if (frozen > 0) - xpt_run_dev_allocq(path->bus); - if (xpt_schedule_dev_sendq(path->bus, path->device)) - xpt_run_dev_sendq(path->bus); + cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb); + if (xpt_schedule_devq(path->bus->sim->devq, path->device)) + xpt_run_devq(path->bus->sim->devq); break; - } case XPT_CALC_GEOMETRY: { struct cam_sim *sim; @@ -2651,8 +2613,7 @@ xpt_action_default(union ccb *start_ccb) device = abort_ccb->ccb_h.path->device; ccbq = &device->ccbq; - device->sim->devq->alloc_openings -= - cam_ccbq_remove_ccb(ccbq, abort_ccb); + cam_ccbq_remove_ccb(ccbq, abort_ccb); abort_ccb->ccb_h.status = CAM_REQ_ABORTED|CAM_DEV_QFRZN; xpt_freeze_devq(abort_ccb->ccb_h.path, 1); @@ -3033,13 +2994,9 @@ xpt_action_default(union ccb *start_ccb) } } - if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) == 0) { - xpt_release_devq_rl(path, /*runlevel*/ - (crs->release_flags & RELSIM_RELEASE_RUNLEVEL) ? - crs->release_timeout : 0, - /*count*/1, /*run_queue*/TRUE); - } - start_ccb->crs.qfrozen_cnt = dev->ccbq.queue.qfrozen_cnt[0]; + if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) == 0) + xpt_release_devq(path, /*count*/1, /*run_queue*/TRUE); + start_ccb->crs.qfrozen_cnt = dev->ccbq.queue.qfrozen_cnt; start_ccb->ccb_h.status = CAM_REQ_CMP; break; } @@ -3082,16 +3039,6 @@ xpt_action_default(union ccb *start_ccb) start_ccb->ccb_h.status = CAM_REQ_CMP; break; } - case XPT_FREEZE_QUEUE: - { - struct ccb_relsim *crs = &start_ccb->crs; - - xpt_freeze_devq_rl(path, /*runlevel*/ - (crs->release_flags & RELSIM_RELEASE_RUNLEVEL) ? - crs->release_timeout : 0, /*count*/1); - start_ccb->ccb_h.status = CAM_REQ_CMP; - break; - } case XPT_NOOP: if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0) xpt_freeze_devq(path, 1); @@ -3197,7 +3144,7 @@ xpt_schedule(struct cam_periph *perph, u camq_change_priority(&device->drvq, perph->pinfo.index, new_priority); - runq = xpt_schedule_dev_allocq(perph->path->bus, device); + runq = 1; } } else { /* New entry on the queue */ @@ -3206,12 +3153,12 @@ xpt_schedule(struct cam_periph *perph, u perph->pinfo.priority = new_priority; perph->pinfo.generation = ++device->drvq.generation; camq_insert(&device->drvq, &perph->pinfo); - runq = xpt_schedule_dev_allocq(perph->path->bus, device); + runq = 1; } if (runq != 0) { CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE, - (" calling xpt_run_devq\n")); - xpt_run_dev_allocq(perph->path->bus); + (" calling xpt_run_dev_allocq\n")); + xpt_run_dev_allocq(device); } } @@ -3264,43 +3211,25 @@ xpt_schedule_dev(struct camq *queue, cam } static void -xpt_run_dev_allocq(struct cam_eb *bus) +xpt_run_dev_allocq(struct cam_ed *device) { - struct cam_devq *devq; - - CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_allocq\n")); - devq = bus->sim->devq; + struct camq *drvq; - CAM_DEBUG_PRINT(CAM_DEBUG_XPT, - (" qfrozen_cnt == 0x%x, entries == %d, " - "openings == %d, active == %d\n", - devq->alloc_queue.qfrozen_cnt[0], - devq->alloc_queue.entries, - devq->alloc_openings, - devq->alloc_active)); - - devq->alloc_queue.qfrozen_cnt[0]++; - while ((devq->alloc_queue.entries > 0) - && (devq->alloc_openings > 0) - && (devq->alloc_queue.qfrozen_cnt[0] <= 1)) { - struct cam_ed_qinfo *qinfo; - struct cam_ed *device; + if (device->ccbq.devq_allocating) + return; + device->ccbq.devq_allocating = 1; + CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_allocq(%p)\n", device)); + drvq = &device->drvq; + while ((drvq->entries > 0) && + (device->ccbq.devq_openings > 0 || + CAMQ_GET_PRIO(drvq) <= CAM_PRIORITY_OOB) && + (device->ccbq.queue.qfrozen_cnt == 0)) { union ccb *work_ccb; struct cam_periph *drv; - struct camq *drvq; - qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->alloc_queue, - CAMQ_HEAD); - device = qinfo->device; - CAM_DEBUG_PRINT(CAM_DEBUG_XPT, - ("running device %p\n", device)); - - drvq = &device->drvq; KASSERT(drvq->entries > 0, ("xpt_run_dev_allocq: " "Device on queue without any work to do")); if ((work_ccb = xpt_get_ccb(device)) != NULL) { - devq->alloc_openings--; - devq->alloc_active++; drv = (struct cam_periph*)camq_remove(drvq, CAMQ_HEAD); xpt_setup_ccb(&work_ccb->ccb_h, drv->path, drv->pinfo.priority); @@ -3319,27 +3248,21 @@ xpt_run_dev_allocq(struct cam_eb *bus) */ break; } - - /* We may have more work. Attempt to reschedule. */ - xpt_schedule_dev_allocq(bus, device); } - devq->alloc_queue.qfrozen_cnt[0]--; + device->ccbq.devq_allocating = 0; } static void -xpt_run_dev_sendq(struct cam_eb *bus) +xpt_run_devq(struct cam_devq *devq) { - struct cam_devq *devq; char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1]; - CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_sendq\n")); - - devq = bus->sim->devq; + CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_devq\n")); - devq->send_queue.qfrozen_cnt[0]++; + devq->send_queue.qfrozen_cnt++; while ((devq->send_queue.entries > 0) && (devq->send_openings > 0) - && (devq->send_queue.qfrozen_cnt[0] <= 1)) { + && (devq->send_queue.qfrozen_cnt <= 1)) { struct cam_ed_qinfo *qinfo; struct cam_ed *device; union ccb *work_ccb; @@ -3389,9 +3312,9 @@ xpt_run_dev_sendq(struct cam_eb *bus) devq->send_openings--; devq->send_active++; - xpt_schedule_dev_sendq(bus, device); + xpt_schedule_devq(devq, device); - if (work_ccb && (work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0){ + if ((work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0) { /* * The client wants to freeze the queue * after this CCB is sent. @@ -3441,7 +3364,7 @@ xpt_run_dev_sendq(struct cam_eb *bus) sim = work_ccb->ccb_h.path->bus->sim; (*(sim->sim_action))(sim, work_ccb); } - devq->send_queue.qfrozen_cnt[0]--; + devq->send_queue.qfrozen_cnt--; } /* @@ -3904,14 +3827,7 @@ xpt_release_ccb(union ccb *free_ccb) SLIST_INSERT_HEAD(&sim->ccb_freeq, &free_ccb->ccb_h, xpt_links.sle); } - if (sim->devq == NULL) { - return; - } - sim->devq->alloc_openings++; - sim->devq->alloc_active--; - if (device_is_alloc_queued(device) == 0) - xpt_schedule_dev_allocq(bus, device); - xpt_run_dev_allocq(bus); + xpt_run_dev_allocq(device); } /* Functions accessed by SIM drivers */ @@ -4266,34 +4182,18 @@ xpt_dev_async_default(u_int32_t async_co } u_int32_t -xpt_freeze_devq_rl(struct cam_path *path, cam_rl rl, u_int count) +xpt_freeze_devq(struct cam_path *path, u_int count) { struct cam_ed *dev = path->device; mtx_assert(path->bus->sim->mtx, MA_OWNED); - dev->sim->devq->alloc_openings += - cam_ccbq_freeze(&dev->ccbq, rl, count); - /* Remove frozen device from allocq. */ - if (device_is_alloc_queued(dev) && - cam_ccbq_frozen(&dev->ccbq, CAM_PRIORITY_TO_RL( - CAMQ_GET_PRIO(&dev->drvq)))) { - camq_remove(&dev->sim->devq->alloc_queue, - dev->alloc_ccb_entry.pinfo.index); - } + dev->ccbq.queue.qfrozen_cnt += count; /* Remove frozen device from sendq. */ - if (device_is_send_queued(dev) && - cam_ccbq_frozen_top(&dev->ccbq)) { + if (device_is_queued(dev)) { camq_remove(&dev->sim->devq->send_queue, - dev->send_ccb_entry.pinfo.index); + dev->devq_entry.pinfo.index); } - return (dev->ccbq.queue.qfrozen_cnt[rl]); -} - -u_int32_t -xpt_freeze_devq(struct cam_path *path, u_int count) -{ - - return (xpt_freeze_devq_rl(path, 0, count)); + return (dev->ccbq.queue.qfrozen_cnt); } u_int32_t @@ -4301,8 +4201,8 @@ xpt_freeze_simq(struct cam_sim *sim, u_i { mtx_assert(sim->mtx, MA_OWNED); - sim->devq->send_queue.qfrozen_cnt[0] += count; - return (sim->devq->send_queue.qfrozen_cnt[0]); + sim->devq->send_queue.qfrozen_cnt += count; + return (sim->devq->send_queue.qfrozen_cnt); } static void @@ -4311,45 +4211,30 @@ xpt_release_devq_timeout(void *arg) struct cam_ed *device; device = (struct cam_ed *)arg; - - xpt_release_devq_device(device, /*rl*/0, /*count*/1, /*run_queue*/TRUE); + xpt_release_devq_device(device, /*count*/1, /*run_queue*/TRUE); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***