Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Nov 2019 21:31:59 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r355023 - head/sys/cam
Message-ID:  <201911222131.xAMLVxnn059632@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Fri Nov 22 21:31:59 2019
New Revision: 355023
URL: https://svnweb.freebsd.org/changeset/base/355023

Log:
  Do not retry long ready waits if previous gave nothing.
  
  I have some disks reporting "Logical unit is in process of becoming ready"
  for about half an hour before finally reporting failure.  During that time
  CAM waits for the readiness during ~2 minutes for each request, that makes
  system boot take very long time.
  
  This change reduces wait times for the following requests to ~1 second if
  previously long wait for that device has timed out.
  
  MFC after:	2 weeks
  Sponsored by:	iXsystems, Inc.

Modified:
  head/sys/cam/cam_periph.c
  head/sys/cam/cam_periph.h

Modified: head/sys/cam/cam_periph.c
==============================================================================
--- head/sys/cam/cam_periph.c	Fri Nov 22 20:24:15 2019	(r355022)
+++ head/sys/cam/cam_periph.c	Fri Nov 22 21:31:59 2019	(r355023)
@@ -1428,6 +1428,14 @@ camperiphdone(struct cam_periph *periph, union ccb *do
 			xpt_async(AC_INQ_CHANGED, done_ccb->ccb_h.path, NULL);
 	}
 
+	/* If we tried long wait and still failed, remember that. */
+	if ((periph->flags & CAM_PERIPH_RECOVERY_WAIT) &&
+	    (done_ccb->csio.cdb_io.cdb_bytes[0] == TEST_UNIT_READY)) {
+		periph->flags &= ~CAM_PERIPH_RECOVERY_WAIT;
+		if (error != 0 && done_ccb->ccb_h.retry_count == 0)
+			periph->flags |= CAM_PERIPH_RECOVERY_WAIT_FAILED;
+	}
+
 	/*
 	 * After recovery action(s) completed, return to the original CCB.
 	 * If the recovery CCB has failed, considering its own possible
@@ -1783,7 +1791,9 @@ camperiphscsisenseerror(union ccb *ccb, union ccb **or
 			 */
 			int retries;
 
-			if ((err_action & SSQ_MANY) != 0) {
+			if ((err_action & SSQ_MANY) != 0 && (periph->flags &
+			     CAM_PERIPH_RECOVERY_WAIT_FAILED) == 0) {
+				periph->flags |= CAM_PERIPH_RECOVERY_WAIT;
 				*action_string = "Polling device for readiness";
 				retries = 120;
 			} else {

Modified: head/sys/cam/cam_periph.h
==============================================================================
--- head/sys/cam/cam_periph.h	Fri Nov 22 20:24:15 2019	(r355022)
+++ head/sys/cam/cam_periph.h	Fri Nov 22 21:31:59 2019	(r355023)
@@ -134,6 +134,8 @@ struct cam_periph {
 #define CAM_PERIPH_RUN_TASK		0x40
 #define CAM_PERIPH_FREE			0x80
 #define CAM_PERIPH_ANNOUNCED		0x100
+#define CAM_PERIPH_RECOVERY_WAIT	0x200
+#define CAM_PERIPH_RECOVERY_WAIT_FAILED	0x400
 	uint32_t		 scheduled_priority;
 	uint32_t		 immediate_priority;
 	int			 periph_allocating;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911222131.xAMLVxnn059632>