• Damien Le Moal's avatar
    dm: handle REQ_OP_ZONE_RESET_ALL · 81e77063
    Damien Le Moal authored
    This commit implements processing of the REQ_OP_ZONE_RESET_ALL operation
    for zoned mapped devices. Given that this operation always has a BIO
    sector of 0 and a 0 size, processing through the regular BIO
    __split_and_process_bio() function does not work because this function
    would always select the first target. Instead, handling of this
    operation is implemented using the function __send_zone_reset_all().
    
    Similarly to the __send_empty_flush() function, the new
    __send_zone_reset_all() function manually goes through all targets of a
    mapped device table doing the following:
    1) If the target can natively support REQ_OP_ZONE_RESET_ALL,
       __send_duplicate_bios() is used to forward the reset all operation to
       the target. This case is handled with the
       __send_zone_reset_all_native() function.
    2) For other targets, the function __send_zone_reset_all_emulated() is
       executed to emulate the execution of REQ_OP_ZONE_RESET_ALL using
       regular REQ_OP_ZONE_RESET operations.
    
    Targets that can natively support REQ_OP_ZONE_RESET_ALL are identified
    using the new target field zone_reset_all_supported. This boolean is set
    to true in for targets that have reliable zone limits, that is, targets
    that map all sequential write required zones of their zoned device(s).
    Setting this field is handled in dm_set_zones_restrictions() and
    device_get_zone_resource_limits().
    
    For targets with unreliable zone limits, REQ_OP_ZONE_RESET_ALL must be
    emulated (case 2 above). This is implemented with
    __send_zone_reset_all_emulated() and is similar to the block layer
    function blkdev_zone_reset_all_emulated(): first a report zones is done
    for the zones of the target to identify zones that need reset, that is,
    any sequential write required zone that is not already empty. This is
    done using a bitmap and the function dm_zone_get_reset_bitmap() which
    sets to 1 the bit corresponding to a zone that needs reset. Next, this
    zone bitmap is inspected and a clone BIO modified to use the
    REQ_OP_ZONE_RESET operation issued for any zone with its bit set in the
    zone bitmap.
    
    This implementation is more efficient than what the block layer does
    with blkdev_zone_reset_all_emulated(), which is always used for DM zoned
    devices currently: as we can natively use REQ_OP_ZONE_RESET_ALL on
    targets mapping all sequential write required zones, resetting all zones
    of a zoned mapped device can be much faster compared to always emulating
    this operation using regular per-zone reset. In the worst case, this
    implementation is as-efficient as the block layer emulation. This
    reduction in the time it takes to reset all zones of a zoned mapped
    device depends directly on the mapped device targets mapping (reliable
    zone limits or not).
    Signed-off-by: default avatarDamien Le Moal <dlemoal@kernel.org>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
    Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    Link: https://lore.kernel.org/r/20240704052816.623865-4-dlemoal@kernel.orgSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
    81e77063
dm-zone.c 12.1 KB