Add separate aggregation limit for non-rotating media

Before sequential scrub patches ZFS never aggregated I/Os above 128KB.
Sequential scrub bumped that to 1MB, supposedly to reduce number of
head seeks for spinning disks.  But for SSDs it makes little to no
sense, especially on FreeBSD, where due to MAXPHYS limitation device
will likely still see bunch of 128KB I/Os instead of one large.
Having more strict aggregation limit for SSDs allows to avoid
allocation of large memory buffer and copy to/from it, that is a
serious problem when throughput reaches gigabytes per second.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Richard Elling <Richard.Elling@RichardElling.com>
Signed-off-by:	Alexander Motin <mav@FreeBSD.org>
Closes #8494
This commit is contained in:
Alexander Motin 2019-03-13 15:00:10 -04:00 committed by Brian Behlendorf
parent 12a935ee9c
commit 1af240f3b5
2 changed files with 21 additions and 1 deletions

View File

@ -2364,6 +2364,17 @@ Default value: \fB5\fR.
.RS 12n .RS 12n
Max vdev I/O aggregation size Max vdev I/O aggregation size
.sp .sp
Default value: \fB1,048,576\fR.
.RE
.sp
.ne 2
.na
\fBzfs_vdev_aggregation_limit_non_rotating\fR (int)
.ad
.RS 12n
Max vdev I/O aggregation size for non-rotating media
.sp
Default value: \fB131,072\fR. Default value: \fB131,072\fR.
.RE .RE

View File

@ -174,6 +174,7 @@ int zfs_vdev_async_write_active_max_dirty_percent = 60;
* they aren't able to help us aggregate at this level. * they aren't able to help us aggregate at this level.
*/ */
int zfs_vdev_aggregation_limit = 1 << 20; int zfs_vdev_aggregation_limit = 1 << 20;
int zfs_vdev_aggregation_limit_non_rotating = SPA_OLD_MAXBLOCKSIZE;
int zfs_vdev_read_gap_limit = 32 << 10; int zfs_vdev_read_gap_limit = 32 << 10;
int zfs_vdev_write_gap_limit = 4 << 10; int zfs_vdev_write_gap_limit = 4 << 10;
@ -549,7 +550,11 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
abd_t *abd; abd_t *abd;
maxblocksize = spa_maxblocksize(vq->vq_vdev->vdev_spa); maxblocksize = spa_maxblocksize(vq->vq_vdev->vdev_spa);
limit = MAX(MIN(zfs_vdev_aggregation_limit, maxblocksize), 0); if (vq->vq_vdev->vdev_nonrot)
limit = zfs_vdev_aggregation_limit_non_rotating;
else
limit = zfs_vdev_aggregation_limit;
limit = MAX(MIN(limit, maxblocksize), 0);
if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE || limit == 0) if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE || limit == 0)
return (NULL); return (NULL);
@ -913,6 +918,10 @@ vdev_queue_last_offset(vdev_t *vd)
module_param(zfs_vdev_aggregation_limit, int, 0644); module_param(zfs_vdev_aggregation_limit, int, 0644);
MODULE_PARM_DESC(zfs_vdev_aggregation_limit, "Max vdev I/O aggregation size"); MODULE_PARM_DESC(zfs_vdev_aggregation_limit, "Max vdev I/O aggregation size");
module_param(zfs_vdev_aggregation_limit_non_rotating, int, 0644);
MODULE_PARM_DESC(zfs_vdev_aggregation_limit_non_rotating,
"Max vdev I/O aggregation size for non-rotating media");
module_param(zfs_vdev_read_gap_limit, int, 0644); module_param(zfs_vdev_read_gap_limit, int, 0644);
MODULE_PARM_DESC(zfs_vdev_read_gap_limit, "Aggregate read I/O over gap"); MODULE_PARM_DESC(zfs_vdev_read_gap_limit, "Aggregate read I/O over gap");