Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Dec 2013 16:01:37 +0100
From:      Thomas Eberhardt <sneakywumpus@gmail.com>
To:        freebsd-scsi@freebsd.org
Subject:   [cam][patch] SCSI disk spin-down on shutdown
Message-ID:  <20391D99-9F60-4D21-AC21-00FF754F7F2D@gmail.com>

Next in thread | Raw E-Mail | Index | Archive | Help

--Apple-Mail=_20A480EF-3CF9-4DDD-B15E-960B9986360A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=windows-1252

Hi,

Appended is a patch to optionally spin-down SCSI disks on shutdown (i =
didn=92t like the increasing
Power-Off retract events in the SMART-stats of my disks). The patch is =
based on r203420 and
the current stable/9 ata_da.c code.

My server is running stable/9 and has a bunch of SATA-disks behind three =
IBM M1015 controllers
(using IT-firmware) and has been running free of trouble for over a year =
with this patch.

Hopefully i didn=92t do any stupid things in the code since i=92m not =
really a kernel hacker. :-)

Regards,

Thomas


--Apple-Mail=_20A480EF-3CF9-4DDD-B15E-960B9986360A
Content-Disposition: attachment;
	filename=scsi_da-spindown.patch.txt
Content-Type: text/plain;
	name="scsi_da-spindown.patch.txt"
Content-Transfer-Encoding: 7bit

Index: share/man/man4/da.4
===================================================================
--- share/man/man4/da.4	(revision 259401)
+++ share/man/man4/da.4	(working copy)
@@ -133,7 +133,7 @@
 .Xr loader 8
 tunables:
 .Bl -tag -width 12
-.It kern.cam.da.retry_count
+.It Va kern.cam.da.retry_count
 .Pp
 This variable determines how many times the
 .Nm
@@ -143,7 +143,7 @@
 .Nm
 driver dump routine.
 This value currently defaults to 4.
-.It kern.cam.da.default_timeout
+.It Va kern.cam.da.default_timeout
 .Pp
 This variable determines how long the
 .Nm
@@ -150,8 +150,13 @@
 driver will wait before timing out an outstanding command.
 The units for this value are seconds, and the default is currently 60
 seconds.
-.It kern.cam.da.%d.minimum_cmd_size
+.It Va kern.cam.da.spindown_shutdown
 .Pp
+This variable determines whether to spin-down disks when shutting down.
+Set to 1 to enable spin-down, 0 to disable.  
+The default is currently disabled.
+.It Va kern.cam.da.%d.minimum_cmd_size
+.Pp
 This variable determines what the minimum READ/WRITE CDB size is for a
 given
 .Nm
Index: sys/cam/scsi/scsi_da.c
===================================================================
--- sys/cam/scsi/scsi_da.c	(revision 259401)
+++ sys/cam/scsi/scsi_da.c	(working copy)
@@ -46,6 +46,7 @@
 #include <sys/cons.h>
 #include <sys/endian.h>
 #include <sys/proc.h>
+#include <sys/reboot.h>
 #include <geom/geom.h>
 #include <geom/geom_disk.h>
 #endif /* _KERNEL */
@@ -1163,6 +1164,10 @@
 #define	DA_DEFAULT_SEND_ORDERED	1
 #endif
 
+#ifndef	DA_DEFAULT_SPINDOWN_SHUTDOWN
+#define	DA_DEFAULT_SPINDOWN_SHUTDOWN	0
+#endif
+
 #define DA_SIO (softc->sort_io_queue >= 0 ? \
     softc->sort_io_queue : cam_sort_io_queues)
 
@@ -1170,6 +1175,7 @@
 static int da_retry_count = DA_DEFAULT_RETRY;
 static int da_default_timeout = DA_DEFAULT_TIMEOUT;
 static int da_send_ordered = DA_DEFAULT_SEND_ORDERED;
+static int da_spindown_shutdown = DA_DEFAULT_SPINDOWN_SHUTDOWN;
 
 static SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
             "CAM Direct Access Disk driver");
@@ -1185,6 +1191,9 @@
 SYSCTL_INT(_kern_cam_da, OID_AUTO, send_ordered, CTLFLAG_RW,
            &da_send_ordered, 0, "Send Ordered Tags");
 TUNABLE_INT("kern.cam.da.send_ordered", &da_send_ordered);
+SYSCTL_INT(_kern_cam_da, OID_AUTO, spindown_shutdown, CTLFLAG_RW,
+           &da_spindown_shutdown, 0, "Spin down upon shutdown");
+TUNABLE_INT("kern.cam.da.spindown_shutdown", &da_spindown_shutdown);
 
 /*
  * DA_ORDEREDTAG_INTERVAL determines how often, relative
@@ -3759,7 +3768,7 @@
  * sync the disk cache to physical media.
  */
 static void
-dashutdown(void * arg, int howto)
+daflush(void)
 {
 	struct cam_periph *periph;
 	struct da_softc *softc;
@@ -3808,6 +3817,63 @@
 	}
 }
 
+static void
+daspindown(void)
+{
+	struct cam_periph *periph;
+	struct da_softc *softc;
+	union ccb *ccb;
+	int error;
+
+	CAM_PERIPH_FOREACH(periph, &dadriver) {
+		/* If we paniced with lock held - not recurse here. */
+		if (cam_periph_owned(periph))
+			continue;
+		cam_periph_lock(periph);
+		softc = (struct da_softc *)periph->softc;
+		/*
+		 * XXX How to check for power mgmt like ADA_FLAG_CAN_POWERMGT?
+		 * XXX Only spin-down fixed drives for now
+		 */
+		if (softc->flags & DA_FLAG_PACK_REMOVABLE) {
+			cam_periph_unlock(periph);
+			continue;
+		}
+
+		if (bootverbose)
+			xpt_print(periph->path, "spin-down\n");
+
+		ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
+		scsi_start_stop(&ccb->csio,
+				/*retries*/0,
+				/*cbfcnp*/dadone,
+				MSG_SIMPLE_Q_TAG,
+				/*start*/FALSE,
+				/*load/eject*/FALSE,
+				/*immediate*/TRUE,
+				SSD_FULL_SIZE,
+				/*timeout*/50*1000);
+
+		error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
+		    /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR,
+		    softc->disk->d_devstat);
+		if (error != 0)
+			xpt_print(periph->path, "Spin-down disk failed\n");
+		xpt_release_ccb(ccb);
+		cam_periph_unlock(periph);
+	}
+}
+
+static void
+dashutdown(void *arg, int howto)
+{
+
+	daflush();
+	if (da_spindown_shutdown != 0 &&
+	    (howto & (RB_HALT | RB_POWEROFF)) != 0)
+		daspindown();
+}
+
 #else /* !_KERNEL */
 
 /*

--Apple-Mail=_20A480EF-3CF9-4DDD-B15E-960B9986360A--



Want to link to this message? Use this URL: <http://docs.FreeBSD.org/cgi/mid.cgi?20391D99-9F60-4D21-AC21-00FF754F7F2D>