MCPcopy Create free account
hub / github.com/F-Stack/f-stack / vdev_queue_aggregate

Function vdev_queue_aggregate

freebsd/contrib/openzfs/module/zfs/vdev_queue.c:645–861  ·  view source on GitHub ↗

* Sufficiently adjacent io_offset's in ZIOs will be aggregated. We do this * by creating a gang ABD from the adjacent ZIOs io_abd's. By using * a gang ABD we avoid doing memory copies to and from the parent, * child ZIOs. The gang ABD also accounts for gaps between adjacent * io_offsets by simply getting the zero ABD for writes or allocating * a new ABD for reads and placing them in the gang

Source from the content-addressed store, hash-verified

643 * a new ABD for reads and placing them in the gang ABD as well.
644 */
645static zio_t *
646vdev_queue_aggregate(vdev_queue_t *vq, zio_t *zio)
647{
648 zio_t *first, *last, *aio, *dio, *mandatory, *nio;
649 zio_link_t *zl = NULL;
650 uint64_t maxgap = 0;
651 uint64_t size;
652 uint64_t limit;
653 int maxblocksize;
654 boolean_t stretch = B_FALSE;
655 avl_tree_t *t = vdev_queue_type_tree(vq, zio->io_type);
656 enum zio_flag flags = zio->io_flags & ZIO_FLAG_AGG_INHERIT;
657 uint64_t next_offset;
658 abd_t *abd;
659
660 maxblocksize = spa_maxblocksize(vq->vq_vdev->vdev_spa);
661 if (vq->vq_vdev->vdev_nonrot)
662 limit = zfs_vdev_aggregation_limit_non_rotating;
663 else
664 limit = zfs_vdev_aggregation_limit;
665 limit = MAX(MIN(limit, maxblocksize), 0);
666
667 if (zio->io_flags & ZIO_FLAG_DONT_AGGREGATE || limit == 0)
668 return (NULL);
669
670 /*
671 * While TRIM commands could be aggregated based on offset this
672 * behavior is disabled until it's determined to be beneficial.
673 */
674 if (zio->io_type == ZIO_TYPE_TRIM && !zfs_vdev_aggregate_trim)
675 return (NULL);
676
677 /*
678 * I/Os to distributed spares are directly dispatched to the dRAID
679 * leaf vdevs for aggregation. See the comment at the end of the
680 * zio_vdev_io_start() function.
681 */
682 ASSERT(vq->vq_vdev->vdev_ops != &vdev_draid_spare_ops);
683
684 first = last = zio;
685
686 if (zio->io_type == ZIO_TYPE_READ)
687 maxgap = zfs_vdev_read_gap_limit;
688
689 /*
690 * We can aggregate I/Os that are sufficiently adjacent and of
691 * the same flavor, as expressed by the AGG_INHERIT flags.
692 * The latter requirement is necessary so that certain
693 * attributes of the I/O, such as whether it's a normal I/O
694 * or a scrub/resilver, can be preserved in the aggregate.
695 * We can include optional I/Os, but don't allow them
696 * to begin a range as they add no benefit in that situation.
697 */
698
699 /*
700 * We keep track of the last non-optional I/O.
701 */
702 mandatory = (first->io_flags & ZIO_FLAG_OPTIONAL) ? NULL : first;

Callers 1

vdev_queue_io_to_issueFunction · 0.85

Calls 15

vdev_queue_type_treeFunction · 0.85
spa_maxblocksizeFunction · 0.85
abd_alloc_gang_abdFunction · 0.85
zio_vdev_delegated_ioFunction · 0.85
zio_add_childFunction · 0.85
vdev_queue_io_removeFunction · 0.85
abd_gang_addFunction · 0.85
abd_get_sizeFunction · 0.85
abd_get_offset_sizeFunction · 0.85
abd_get_zerosFunction · 0.85
mutex_exitFunction · 0.85
zio_walk_parentsFunction · 0.85

Tested by

no test coverage detected