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-head mailing list