svn commit: r289924 - in stable/10: share/man/man4 sys/cam/scsi
Alexander Motin
mav at FreeBSD.org
Sun Oct 25 07:26:14 UTC 2015
Author: mav
Date: Sun Oct 25 07:26:12 2015
New Revision: 289924
URL: https://svnweb.freebsd.org/changeset/base/289924
Log:
MFC r289146:
Make delete method set via kern.cam.da.X.delete_method persistent.
This allows to set delete method via tunable, before device capabilities
are known. Also allow ZERO method for devices not reporting LBP, if user
explicitly requests it -- it may be useful if storage supports compression
and WRITE SAME, but does not support UNMAP.
Modified:
stable/10/share/man/man4/da.4
stable/10/sys/cam/scsi/scsi_da.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/share/man/man4/da.4
==============================================================================
--- stable/10/share/man/man4/da.4 Sun Oct 25 06:07:46 2015 (r289923)
+++ stable/10/share/man/man4/da.4 Sun Oct 25 07:26:12 2015 (r289924)
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 22, 2014
+.Dd October 11, 2015
.Dt DA 4
.Os
.Sh NAME
@@ -133,8 +133,7 @@ variables and
.Xr loader 8
tunables:
.Bl -tag -width 12
-.It kern.cam.da.retry_count
-.Pp
+.It Va kern.cam.da.retry_count
This variable determines how many times the
.Nm
driver will retry a READ or WRITE command.
@@ -143,8 +142,7 @@ the
.Nm
driver dump routine.
This value currently defaults to 4.
-.It kern.cam.da.default_timeout
-.Pp
+.It Va kern.cam.da.default_timeout
This variable determines how long the
.Nm
driver will wait before timing out an outstanding command.
@@ -152,20 +150,31 @@ The units for this value are seconds, an
seconds.
.It Va kern.cam.sort_io_queue
.It Va kern.cam.da. Ns Ar X Ns Va .sort_io_queue
-.Pp
These variables determine whether request queue should be sorted trying
to optimize head seeks.
Set to 1 to enable sorting, 0 to disable, -1 to leave it as-is.
The default is sorting enabled for HDDs and disabled for SSDs.
-.It kern.cam.da.%d.minimum_cmd_size
-.Pp
+.It Va kern.cam.da. Ns Ar X Ns Va .delete_method
+This variable specifies method to handle BIO_DELETE requests:
+.Bl -tag
+.It ATA_TRIM
+ATA TRIM via ATA COMMAND PASS THROUGH command,
+.It UNMAP
+UNMAP command,
+.It WS16
+WRITE SAME(16) command with UNMAP flag,
+.It WS10
+WRITE SAME(10) command with UNMAP flag,
+.It ZERO
+WRITE SAME(10) command without UNMAP flag,
+.It DISABLE
+disable BIO_DELETE support.
+.El
+.It Va kern.cam.da. Ns Ar X Ns Va .minimum_cmd_size
This variable determines what the minimum READ/WRITE CDB size is for a
given
.Nm
unit.
-(The %d above denotes the unit number of the
-.Nm
-driver instance, e.g.\& 1, 2, 4, 8, etc.)
Valid minimum command size values are 6, 10, 12 and 16 bytes.
The default is 6 bytes.
.Pp
Modified: stable/10/sys/cam/scsi/scsi_da.c
==============================================================================
--- stable/10/sys/cam/scsi/scsi_da.c Sun Oct 25 06:07:46 2015 (r289923)
+++ stable/10/sys/cam/scsi/scsi_da.c Sun Oct 25 07:26:12 2015 (r289924)
@@ -219,6 +219,7 @@ struct da_softc {
uint32_t unmap_max_ranges;
uint32_t unmap_max_lba; /* Max LBAs in UNMAP req */
uint64_t ws_max_blks;
+ da_delete_methods delete_method_pref;
da_delete_methods delete_method;
da_delete_func_t *delete_func;
struct disk_params params;
@@ -1805,7 +1806,7 @@ dasysctlinit(void *context, int pending)
* the fly.
*/
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
- OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RW,
+ OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RWTUN,
softc, 0, dadeletemethodsysctl, "A",
"BIO_DELETE execution method");
SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
@@ -1916,7 +1917,6 @@ static void
dadeletemethodset(struct da_softc *softc, da_delete_methods delete_method)
{
-
softc->delete_method = delete_method;
softc->disk->d_delmaxsize = dadeletemaxsize(softc, delete_method);
softc->delete_func = da_delete_functions[delete_method];
@@ -1969,25 +1969,17 @@ daprobedone(struct cam_periph *periph, u
snprintf(buf, sizeof(buf), "Delete methods: <");
sep = 0;
- for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) {
- if (softc->delete_available & (1 << i)) {
- if (sep) {
- strlcat(buf, ",", sizeof(buf));
- } else {
- sep = 1;
- }
- strlcat(buf, da_delete_method_names[i],
- sizeof(buf));
- if (i == softc->delete_method) {
- strlcat(buf, "(*)", sizeof(buf));
- }
- }
- }
- if (sep == 0) {
- if (softc->delete_method == DA_DELETE_NONE)
- strlcat(buf, "NONE(*)", sizeof(buf));
- else
- strlcat(buf, "DISABLED(*)", sizeof(buf));
+ for (i = 0; i <= DA_DELETE_MAX; i++) {
+ if ((softc->delete_available & (1 << i)) == 0 &&
+ i != softc->delete_method)
+ continue;
+ if (sep)
+ strlcat(buf, ",", sizeof(buf));
+ strlcat(buf, da_delete_method_names[i],
+ sizeof(buf));
+ if (i == softc->delete_method)
+ strlcat(buf, "(*)", sizeof(buf));
+ sep = 1;
}
strlcat(buf, ">", sizeof(buf));
printf("%s%d: %s\n", periph->periph_name,
@@ -2017,21 +2009,28 @@ daprobedone(struct cam_periph *periph, u
static void
dadeletemethodchoose(struct da_softc *softc, da_delete_methods default_method)
{
- int i, delete_method;
+ int i, methods;
- delete_method = default_method;
+ /* If available, prefer the method requested by user. */
+ i = softc->delete_method_pref;
+ methods = softc->delete_available | (1 << DA_DELETE_DISABLE);
+ if (methods & (1 << i)) {
+ dadeletemethodset(softc, i);
+ return;
+ }
- /*
- * Use the pre-defined order to choose the best
- * performing delete.
- */
+ /* Use the pre-defined order to choose the best performing delete. */
for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) {
+ if (i == DA_DELETE_ZERO)
+ continue;
if (softc->delete_available & (1 << i)) {
dadeletemethodset(softc, i);
return;
}
}
- dadeletemethodset(softc, delete_method);
+
+ /* Fallback to default. */
+ dadeletemethodset(softc, default_method);
}
static int
@@ -2055,13 +2054,14 @@ dadeletemethodsysctl(SYSCTL_HANDLER_ARGS
return (error);
methods = softc->delete_available | (1 << DA_DELETE_DISABLE);
for (i = 0; i <= DA_DELETE_MAX; i++) {
- if (!(methods & (1 << i)) ||
- strcmp(buf, da_delete_method_names[i]) != 0)
- continue;
- dadeletemethodset(softc, i);
- return (0);
+ if (strcmp(buf, da_delete_method_names[i]) == 0)
+ break;
}
- return (EINVAL);
+ if (i > DA_DELETE_MAX)
+ return (EINVAL);
+ softc->delete_method_pref = i;
+ dadeletemethodchoose(softc, DA_DELETE_NONE);
+ return (0);
}
static cam_status
@@ -3298,6 +3298,7 @@ dadone(struct cam_periph *periph, union
/* Ensure re-probe doesn't see old delete. */
softc->delete_available = 0;
+ dadeleteflag(softc, DA_DELETE_ZERO, 1);
if (lbp && (softc->quirks & DA_Q_NO_UNMAP) == 0) {
/*
* Based on older SBC-3 spec revisions
@@ -3314,7 +3315,6 @@ dadone(struct cam_periph *periph, union
*/
dadeleteflag(softc, DA_DELETE_WS16, 1);
dadeleteflag(softc, DA_DELETE_WS10, 1);
- dadeleteflag(softc, DA_DELETE_ZERO, 1);
dadeleteflag(softc, DA_DELETE_UNMAP, 1);
xpt_release_ccb(done_ccb);
@@ -3343,8 +3343,6 @@ dadone(struct cam_periph *periph, union
(lbp->flags & SVPD_LBP_WS16));
dadeleteflag(softc, DA_DELETE_WS10,
(lbp->flags & SVPD_LBP_WS10));
- dadeleteflag(softc, DA_DELETE_ZERO,
- (lbp->flags & SVPD_LBP_WS10));
dadeleteflag(softc, DA_DELETE_UNMAP,
(lbp->flags & SVPD_LBP_UNMAP));
} else {
More information about the svn-src-stable-10
mailing list