From owner-svn-src-all@freebsd.org Mon Oct 30 03:25:24 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4AB5DE530E0; Mon, 30 Oct 2017 03:25:24 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 13B447188E; Mon, 30 Oct 2017 03:25:24 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v9U3PNqd025476; Mon, 30 Oct 2017 03:25:23 GMT (envelope-from imp@FreeBSD.org) Received: (from imp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v9U3PNDS025475; Mon, 30 Oct 2017 03:25:23 GMT (envelope-from imp@FreeBSD.org) Message-Id: <201710300325.v9U3PNDS025475@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: imp set sender to imp@FreeBSD.org using -f From: Warner Losh Date: Mon, 30 Oct 2017 03:25:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r325117 - head/sys/cam/ata X-SVN-Group: head X-SVN-Commit-Author: imp X-SVN-Commit-Paths: head/sys/cam/ata X-SVN-Commit-Revision: 325117 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 30 Oct 2017 03:25:24 -0000 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