svn commit: r331435 - head/sys/cam/scsi
Warner Losh
imp at FreeBSD.org
Fri Mar 23 16:23:16 UTC 2018
Author: imp
Date: Fri Mar 23 16:23:15 2018
New Revision: 331435
URL: https://svnweb.freebsd.org/changeset/base/331435
Log:
Flag when we have a pending TUR. Don't schedule another one when we
have one pending. Otherwise, we can race and send two, which is
wasteful in close proximity. It can also cause the acaquire/release
count for TUR to be > 1, which is undexpected.
PR: 226510
Differential Review: https://reviews.freebsd.org/D14792
Modified:
head/sys/cam/scsi/scsi_da.c
Modified: head/sys/cam/scsi/scsi_da.c
==============================================================================
--- head/sys/cam/scsi/scsi_da.c Fri Mar 23 16:15:07 2018 (r331434)
+++ head/sys/cam/scsi/scsi_da.c Fri Mar 23 16:23:15 2018 (r331435)
@@ -116,7 +116,8 @@ typedef enum {
DA_FLAG_CAN_ATA_LOG = 0x008000,
DA_FLAG_CAN_ATA_IDLOG = 0x010000,
DA_FLAG_CAN_ATA_SUPCAP = 0x020000,
- DA_FLAG_CAN_ATA_ZONE = 0x040000
+ DA_FLAG_CAN_ATA_ZONE = 0x040000,
+ DA_FLAG_TUR_PENDING = 0x080000
} da_flags;
typedef enum {
@@ -2068,7 +2069,8 @@ daasync(void *callback_arg, u_int32_t code,
case AC_SCSI_AEN:
softc = (struct da_softc *)periph->softc;
cam_periph_lock(periph);
- if (!cam_iosched_has_work_flags(softc->cam_iosched, DA_WORK_TUR)) {
+ if (!cam_iosched_has_work_flags(softc->cam_iosched, DA_WORK_TUR) &&
+ (softc->flags & DA_FLAG_TUR_PENDING) == 0) {
if (da_periph_acquire(periph, DA_REF_TUR) == 0) {
cam_iosched_set_work_flags(softc->cam_iosched, DA_WORK_TUR);
daschedule(periph);
@@ -3113,6 +3115,7 @@ more:
bp = cam_iosched_next_bio(softc->cam_iosched);
if (bp == NULL) {
if (cam_iosched_has_work_flags(softc->cam_iosched, DA_WORK_TUR)) {
+ softc->flags |= DA_FLAG_TUR_PENDING;
cam_iosched_clr_work_flags(softc->cam_iosched, DA_WORK_TUR);
scsi_test_unit_ready(&start_ccb->csio,
/*retries*/ da_retry_count,
@@ -5570,7 +5573,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
if (daerror(done_ccb, CAM_RETRY_SELTO,
SF_RETRY_UA | SF_NO_RECOVERY | SF_NO_PRINT) ==
ERESTART)
- return;
+ return; /* Will complete again, keep reference */
if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(done_ccb->ccb_h.path,
/*relsim_flags*/0,
@@ -5579,6 +5582,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb)
/*getcount_only*/0);
}
xpt_release_ccb(done_ccb);
+ softc->flags &= ~DA_FLAG_TUR_PENDING;
da_periph_release_locked(periph, DA_REF_TUR);
return;
}
@@ -5700,6 +5704,7 @@ damediapoll(void *arg)
struct da_softc *softc = periph->softc;
if (!cam_iosched_has_work_flags(softc->cam_iosched, DA_WORK_TUR) &&
+ (softc->flags & DA_FLAG_TUR_PENDING) == 0 &&
LIST_EMPTY(&softc->pending_ccbs)) {
if (da_periph_acquire(periph, DA_REF_TUR) == 0) {
cam_iosched_set_work_flags(softc->cam_iosched, DA_WORK_TUR);
More information about the svn-src-all
mailing list