Skip to content

Commit 4e81a6c

Browse files
kelleymhmartinkpetersen
authored andcommitted
scsi: storvsc: Don't pass unused PFNs to Hyper-V host
In a SCSI request, storvsc pre-allocates space for up to MAX_PAGE_BUFFER_COUNT physical frame numbers to be passed to Hyper-V. If the size of the I/O request requires more PFNs, a separate memory area of exactly the correct size is dynamically allocated. But when the pre-allocated area is used, current code always passes MAX_PAGE_BUFFER_COUNT PFNs to Hyper-V, even if fewer are needed. While this doesn't break anything because the additional PFNs are always zero, more bytes than necessary are copied into the VMBus channel ring buffer. This takes CPU cycles and wastes space in the ring buffer. For a typical 4 Kbyte I/O that requires only a single PFN, 248 unnecessary bytes are copied. Fix this by setting the payload_sz based on the actual number of PFNs required, not the size of the pre-allocated space. Reported-by: John Starks <[email protected]> Fixes: 8f43710 ("scsi: storvsc: Support PAGE_SIZE larger than 4K") Signed-off-by: Michael Kelley <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 72a81bb commit 4e81a6c

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

drivers/scsi/storvsc_drv.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,7 +1780,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
17801780

17811781
length = scsi_bufflen(scmnd);
17821782
payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb;
1783-
payload_sz = sizeof(cmd_request->mpb);
1783+
payload_sz = 0;
17841784

17851785
if (scsi_sg_count(scmnd)) {
17861786
unsigned long offset_in_hvpg = offset_in_hvpage(sgl->offset);
@@ -1789,10 +1789,10 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
17891789
unsigned long hvpfn, hvpfns_to_add;
17901790
int j, i = 0, sg_count;
17911791

1792-
if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
1792+
payload_sz = (hvpg_count * sizeof(u64) +
1793+
sizeof(struct vmbus_packet_mpb_array));
17931794

1794-
payload_sz = (hvpg_count * sizeof(u64) +
1795-
sizeof(struct vmbus_packet_mpb_array));
1795+
if (hvpg_count > MAX_PAGE_BUFFER_COUNT) {
17961796
payload = kzalloc(payload_sz, GFP_ATOMIC);
17971797
if (!payload)
17981798
return SCSI_MLQUEUE_DEVICE_BUSY;

0 commit comments

Comments
 (0)