Fix zfs_vdev_aggregation_limit bounds checking

Update the bounds checking for zfs_vdev_aggregation_limit so that
it has a floor of zero and a maximum value of the supported block
size for the pool.

Additionally add an early return when zfs_vdev_aggregation_limit
equals zero to disable aggregation.  For very fast solid state or
memory devices it may be more expensive to perform the aggregation
than to issue the IO immediately.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
Brian Behlendorf 2015-12-17 09:26:05 -08:00
parent 6fe53787f3
commit a58df6f536

View File

@ -499,20 +499,17 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
zio_t *first, *last, *aio, *dio, *mandatory, *nio; zio_t *first, *last, *aio, *dio, *mandatory, *nio;
uint64_t maxgap = 0; uint64_t maxgap = 0;
uint64_t size; uint64_t size;
uint64_t limit;
boolean_t stretch = B_FALSE; boolean_t stretch = B_FALSE;
avl_tree_t *t = vdev_queue_type_tree(vq, zio->io_type); avl_tree_t *t = vdev_queue_type_tree(vq, zio->io_type);
enum zio_flag flags = zio->io_flags & ZIO_FLAG_AGG_INHERIT; enum zio_flag flags = zio->io_flags & ZIO_FLAG_AGG_INHERIT;
void *buf; void *buf;
if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE) limit = MAX(MIN(zfs_vdev_aggregation_limit,
return (NULL); spa_maxblocksize(vq->vq_vdev->vdev_spa)), 0);
/* if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE || limit == 0)
* Prevent users from setting the zfs_vdev_aggregation_limit return (NULL);
* tuning larger than SPA_MAXBLOCKSIZE.
*/
zfs_vdev_aggregation_limit =
MIN(zfs_vdev_aggregation_limit, SPA_MAXBLOCKSIZE);
first = last = zio; first = last = zio;
@ -540,7 +537,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
*/ */
while ((dio = AVL_PREV(t, first)) != NULL && while ((dio = AVL_PREV(t, first)) != NULL &&
(dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags && (dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
IO_SPAN(dio, last) <= zfs_vdev_aggregation_limit && IO_SPAN(dio, last) <= limit &&
IO_GAP(dio, first) <= maxgap) { IO_GAP(dio, first) <= maxgap) {
first = dio; first = dio;
if (mandatory == NULL && !(first->io_flags & ZIO_FLAG_OPTIONAL)) if (mandatory == NULL && !(first->io_flags & ZIO_FLAG_OPTIONAL))
@ -561,7 +558,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
*/ */
while ((dio = AVL_NEXT(t, last)) != NULL && while ((dio = AVL_NEXT(t, last)) != NULL &&
(dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags && (dio->io_flags & ZIO_FLAG_AGG_INHERIT) == flags &&
IO_SPAN(first, dio) <= zfs_vdev_aggregation_limit && IO_SPAN(first, dio) <= limit &&
IO_GAP(last, dio) <= maxgap) { IO_GAP(last, dio) <= maxgap) {
last = dio; last = dio;
if (!(last->io_flags & ZIO_FLAG_OPTIONAL)) if (!(last->io_flags & ZIO_FLAG_OPTIONAL))
@ -607,7 +604,7 @@ vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
return (NULL); return (NULL);
size = IO_SPAN(first, last); size = IO_SPAN(first, last);
ASSERT3U(size, <=, zfs_vdev_aggregation_limit); ASSERT3U(size, <=, limit);
buf = zio_buf_alloc_flags(size, KM_NOSLEEP); buf = zio_buf_alloc_flags(size, KM_NOSLEEP);
if (buf == NULL) if (buf == NULL)