Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Oct 2017 03:25:23 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r325117 - head/sys/cam/ata
Message-ID:  <201710300325.v9U3PNDS025475@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Mon Oct 30 03:25:22 2017
New Revision: 325117
URL: https://svnweb.freebsd.org/changeset/base/325117

Log:
  Send IDLE IMMEDIATE for warm boot.
  
  We must send either an IDLE IMMEDIATE or a STANDBY IMMEDIATE to drives
  on warm boot so their SMART and other volatile data is
  persisted. However, for a warm boot we don't want to send STANDBY
  IMMEDIATE to some spinning drives because they will spin down. If
  there's a lot of these drives on the system, that can cause a
  thundering herd problem at startup time (that in extreme cases causes
  timeout in device discovery).
  
  Sponsored by: Netflix
  Differential Revision: https://reviews.freebsd.org/D12811

Modified:
  head/sys/cam/ata/ata_da.c

Modified: head/sys/cam/ata/ata_da.c
==============================================================================
--- head/sys/cam/ata/ata_da.c	Mon Oct 30 03:12:38 2017	(r325116)
+++ head/sys/cam/ata/ata_da.c	Mon Oct 30 03:25:22 2017	(r325117)
@@ -3534,17 +3534,29 @@ adaspindown(uint8_t cmd, int flags)
 static void
 adashutdown(void *arg, int howto)
 {
+	int how;
 
 	adaflush();
 
 	/*
-	 * STANDBY IMMEDIATE flushes any volatile data to the drive so
-	 * do this always to ensure we flush a cosnsistent state to
-	 * the drive. adaspindown will ensure that we don't send this
-	 * to a drive that doesn't support it.
+	 * STANDBY IMMEDIATE saves any volatile data to the drive. It also spins
+	 * down hard drives. IDLE IMMEDIATE also saves the volatile data without
+	 * a spindown. We send the former when we expect to lose power soon. For
+	 * a warm boot, we send the latter to avoid a thundering herd of spinups
+	 * just after the kernel loads while probing. We have to do something to
+	 * flush the data because the BIOS in many systems resets the HBA
+	 * causing a COMINIT/COMRESET negotiation, which some drives interpret
+	 * as license to toss the volatile data, and others count as unclean
+	 * shutdown when in the Active PM state in SMART attributes.
+	 *
+	 * adaspindown will ensure that we don't send this to a drive that
+	 * doesn't support it.
 	 */
-	if (ada_spindown_shutdown != 0)
-		adaspindown(ATA_STANDBY_IMMEDIATE, 0);
+	if (ada_spindown_shutdown != 0) {
+		how = (howto & (RB_HALT | RB_POWEROFF | RB_POWERCYCLE)) ?
+		    ATA_STANDBY_IMMEDIATE : ATA_IDLE_IMMEDIATE;
+		adaspindown(how, 0);
+	}
 }
 
 static void



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