* 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
| 643 | * a new ABD for reads and placing them in the gang ABD as well. |
| 644 | */ |
| 645 | static zio_t * |
| 646 | vdev_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; |
no test coverage detected