lkml.org 
[lkml]   [2022]   [Jun]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.18 054/181] scsi: storvsc: Correct reporting of Hyper-V I/O size limits
    Date
    From: Saurabh Sengar <ssengar@linux.microsoft.com>

    [ Upstream commit 1d3e0980782fbafaf93285779fd3905e4f866802 ]

    Current code is based on the idea that the max number of SGL entries
    also determines the max size of an I/O request. While this idea was
    true in older versions of the storvsc driver when SGL entry length
    was limited to 4 Kbytes, commit 3d9c3dcc58e9 ("scsi: storvsc: Enable
    scatterlist entry lengths > 4Kbytes") removed that limitation. It's
    now theoretically possible for the block layer to send requests that
    exceed the maximum size supported by Hyper-V. This problem doesn't
    currently happen in practice because the block layer defaults to a
    512 Kbyte maximum, while Hyper-V in Azure supports 2 Mbyte I/O sizes.
    But some future configuration of Hyper-V could have a smaller max I/O
    size, and the block layer could exceed that max.

    Fix this by correctly setting max_sectors as well as sg_tablesize to
    reflect the maximum I/O size that Hyper-V reports. While allowing
    I/O sizes larger than the block layer default of 512 Kbytes doesn’t
    provide any noticeable performance benefit in the tests we ran, it's
    still appropriate to report the correct underlying Hyper-V capabilities
    to the Linux block layer.

    Also tweak the virt_boundary_mask to reflect that the required
    alignment derives from Hyper-V communication using a 4 Kbyte page size,
    and not on the guest page size, which might be bigger (eg. ARM64).

    Link: https://lore.kernel.org/r/1655190355-28722-1-git-send-email-ssengar@linux.microsoft.com
    Fixes: 3d9c3dcc58e9 ("scsi: storvsc: Enable scatter list entry lengths > 4Kbytes")
    Reviewed-by: Michael Kelley <mikelley@microsoft.com>
    Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/scsi/storvsc_drv.c | 27 ++++++++++++++++++++++-----
    1 file changed, 22 insertions(+), 5 deletions(-)

    diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
    index 9a0bba5a51a7..4b1f1d73eee8 100644
    --- a/drivers/scsi/storvsc_drv.c
    +++ b/drivers/scsi/storvsc_drv.c
    @@ -1916,7 +1916,7 @@ static struct scsi_host_template scsi_driver = {
    .cmd_per_lun = 2048,
    .this_id = -1,
    /* Ensure there are no gaps in presented sgls */
    - .virt_boundary_mask = PAGE_SIZE-1,
    + .virt_boundary_mask = HV_HYP_PAGE_SIZE - 1,
    .no_write_same = 1,
    .track_queue_depth = 1,
    .change_queue_depth = storvsc_change_queue_depth,
    @@ -1970,6 +1970,7 @@ static int storvsc_probe(struct hv_device *device,
    int max_targets;
    int max_channels;
    int max_sub_channels = 0;
    + u32 max_xfer_bytes;

    /*
    * Based on the windows host we are running on,
    @@ -2059,12 +2060,28 @@ static int storvsc_probe(struct hv_device *device,
    }
    /* max cmd length */
    host->max_cmd_len = STORVSC_MAX_CMD_LEN;
    -
    /*
    - * set the table size based on the info we got
    - * from the host.
    + * Any reasonable Hyper-V configuration should provide
    + * max_transfer_bytes value aligning to HV_HYP_PAGE_SIZE,
    + * protecting it from any weird value.
    + */
    + max_xfer_bytes = round_down(stor_device->max_transfer_bytes, HV_HYP_PAGE_SIZE);
    + /* max_hw_sectors_kb */
    + host->max_sectors = max_xfer_bytes >> 9;
    + /*
    + * There are 2 requirements for Hyper-V storvsc sgl segments,
    + * based on which the below calculation for max segments is
    + * done:
    + *
    + * 1. Except for the first and last sgl segment, all sgl segments
    + * should be align to HV_HYP_PAGE_SIZE, that also means the
    + * maximum number of segments in a sgl can be calculated by
    + * dividing the total max transfer length by HV_HYP_PAGE_SIZE.
    + *
    + * 2. Except for the first and last, each entry in the SGL must
    + * have an offset that is a multiple of HV_HYP_PAGE_SIZE.
    */
    - host->sg_tablesize = (stor_device->max_transfer_bytes >> PAGE_SHIFT);
    + host->sg_tablesize = (max_xfer_bytes >> HV_HYP_PAGE_SHIFT) + 1;
    /*
    * For non-IDE disks, the host supports multiple channels.
    * Set the number of HW queues we are supporting.
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-06-27 13:55    [W:4.094 / U:0.428 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site