Skip to content

Commit be0cf6c

Browse files
kattisrinivasanJames Bottomley
authored and
James Bottomley
committed
scsi: storvsc: Set the tablesize based on the information given by the host
Set the tablesize based on the information given by the host. Signed-off-by: K. Y. Srinivasan <[email protected]> Reviewed-by: Long Li <[email protected]> Tested-by: Long Li <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent aaced99 commit be0cf6c

File tree

1 file changed

+64
-25
lines changed

1 file changed

+64
-25
lines changed

drivers/scsi/storvsc_drv.c

+64-25
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,10 @@ struct storvsc_cmd_request {
351351
/* Synchronize the request/response if needed */
352352
struct completion wait_event;
353353

354-
struct hv_multipage_buffer data_buffer;
354+
struct vmbus_channel_packet_multipage_buffer mpb;
355+
struct vmbus_packet_mpb_array *payload;
356+
u32 payload_sz;
357+
355358
struct vstor_packet vstor_packet;
356359
};
357360

@@ -1103,6 +1106,8 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
11031106
struct Scsi_Host *host;
11041107
struct storvsc_device *stor_dev;
11051108
struct hv_device *dev = host_dev->dev;
1109+
u32 payload_sz = cmd_request->payload_sz;
1110+
void *payload = cmd_request->payload;
11061111

11071112
stor_dev = get_in_stor_device(dev);
11081113
host = stor_dev->host;
@@ -1132,10 +1137,14 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
11321137
sense_hdr.ascq);
11331138

11341139
scsi_set_resid(scmnd,
1135-
cmd_request->data_buffer.len -
1140+
cmd_request->payload->range.len -
11361141
vm_srb->data_transfer_length);
11371142

11381143
scmnd->scsi_done(scmnd);
1144+
1145+
if (payload_sz >
1146+
sizeof(struct vmbus_channel_packet_multipage_buffer))
1147+
kfree(payload);
11391148
}
11401149

11411150
static void storvsc_on_io_completion(struct hv_device *device,
@@ -1337,7 +1346,7 @@ static int storvsc_dev_remove(struct hv_device *device)
13371346
}
13381347

13391348
static int storvsc_do_io(struct hv_device *device,
1340-
struct storvsc_cmd_request *request)
1349+
struct storvsc_cmd_request *request)
13411350
{
13421351
struct storvsc_device *stor_device;
13431352
struct vstor_packet *vstor_packet;
@@ -1369,13 +1378,14 @@ static int storvsc_do_io(struct hv_device *device,
13691378

13701379

13711380
vstor_packet->vm_srb.data_transfer_length =
1372-
request->data_buffer.len;
1381+
request->payload->range.len;
13731382

13741383
vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
13751384

1376-
if (request->data_buffer.len) {
1377-
ret = vmbus_sendpacket_multipagebuffer(outgoing_channel,
1378-
&request->data_buffer,
1385+
if (request->payload->range.len) {
1386+
1387+
ret = vmbus_sendpacket_mpb_desc(outgoing_channel,
1388+
request->payload, request->payload_sz,
13791389
vstor_packet,
13801390
(sizeof(struct vstor_packet) -
13811391
vmscsi_size_delta),
@@ -1549,6 +1559,9 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
15491559
unsigned int sg_count = 0;
15501560
struct vmscsi_request *vm_srb;
15511561
struct scatterlist *cur_sgl;
1562+
struct vmbus_packet_mpb_array *payload;
1563+
u32 payload_sz;
1564+
u32 length;
15521565

15531566
if (vmstor_current_major <= VMSTOR_WIN8_MAJOR) {
15541567
/*
@@ -1602,48 +1615,71 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
16021615

16031616
memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length);
16041617

1605-
cmd_request->data_buffer.len = scsi_bufflen(scmnd);
1606-
if (scsi_sg_count(scmnd)) {
1607-
sgl = (struct scatterlist *)scsi_sglist(scmnd);
1608-
sg_count = scsi_sg_count(scmnd);
1618+
sgl = (struct scatterlist *)scsi_sglist(scmnd);
1619+
sg_count = scsi_sg_count(scmnd);
16091620

1621+
length = scsi_bufflen(scmnd);
1622+
payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb;
1623+
payload_sz = sizeof(cmd_request->mpb);
1624+
1625+
if (sg_count) {
16101626
/* check if we need to bounce the sgl */
16111627
if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
16121628
cmd_request->bounce_sgl =
1613-
create_bounce_buffer(sgl, scsi_sg_count(scmnd),
1614-
scsi_bufflen(scmnd),
1629+
create_bounce_buffer(sgl, sg_count,
1630+
length,
16151631
vm_srb->data_in);
16161632
if (!cmd_request->bounce_sgl)
16171633
return SCSI_MLQUEUE_HOST_BUSY;
16181634

16191635
cmd_request->bounce_sgl_count =
1620-
ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >>
1621-
PAGE_SHIFT;
1636+
ALIGN(length, PAGE_SIZE) >> PAGE_SHIFT;
16221637

16231638
if (vm_srb->data_in == WRITE_TYPE)
16241639
copy_to_bounce_buffer(sgl,
1625-
cmd_request->bounce_sgl,
1626-
scsi_sg_count(scmnd));
1640+
cmd_request->bounce_sgl, sg_count);
16271641

16281642
sgl = cmd_request->bounce_sgl;
16291643
sg_count = cmd_request->bounce_sgl_count;
16301644
}
16311645

1632-
cmd_request->data_buffer.offset = sgl[0].offset;
1646+
1647+
if (sg_count > MAX_PAGE_BUFFER_COUNT) {
1648+
1649+
payload_sz = (sg_count * sizeof(void *) +
1650+
sizeof(struct vmbus_packet_mpb_array));
1651+
payload = kmalloc(payload_sz, GFP_ATOMIC);
1652+
if (!payload) {
1653+
if (cmd_request->bounce_sgl_count)
1654+
destroy_bounce_buffer(
1655+
cmd_request->bounce_sgl,
1656+
cmd_request->bounce_sgl_count);
1657+
1658+
return SCSI_MLQUEUE_DEVICE_BUSY;
1659+
}
1660+
}
1661+
1662+
payload->range.len = length;
1663+
payload->range.offset = sgl[0].offset;
1664+
16331665
cur_sgl = sgl;
16341666
for (i = 0; i < sg_count; i++) {
1635-
cmd_request->data_buffer.pfn_array[i] =
1667+
payload->range.pfn_array[i] =
16361668
page_to_pfn(sg_page((cur_sgl)));
16371669
cur_sgl = sg_next(cur_sgl);
16381670
}
16391671

16401672
} else if (scsi_sglist(scmnd)) {
1641-
cmd_request->data_buffer.offset =
1673+
payload->range.len = length;
1674+
payload->range.offset =
16421675
virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1);
1643-
cmd_request->data_buffer.pfn_array[0] =
1676+
payload->range.pfn_array[0] =
16441677
virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT;
16451678
}
16461679

1680+
cmd_request->payload = payload;
1681+
cmd_request->payload_sz = payload_sz;
1682+
16471683
/* Invokes the vsc to start an IO */
16481684
ret = storvsc_do_io(dev, cmd_request);
16491685

@@ -1672,10 +1708,7 @@ static struct scsi_host_template scsi_driver = {
16721708
.slave_configure = storvsc_device_configure,
16731709
.cmd_per_lun = 255,
16741710
.this_id = -1,
1675-
/* no use setting to 0 since ll_blk_rw reset it to 1 */
1676-
/* currently 32 */
1677-
.sg_tablesize = MAX_MULTIPAGE_BUFFER_COUNT,
1678-
.use_clustering = DISABLE_CLUSTERING,
1711+
.use_clustering = ENABLE_CLUSTERING,
16791712
/* Make sure we dont get a sg segment crosses a page boundary */
16801713
.dma_boundary = PAGE_SIZE-1,
16811714
.no_write_same = 1,
@@ -1812,6 +1845,12 @@ static int storvsc_probe(struct hv_device *device,
18121845
/* max cmd length */
18131846
host->max_cmd_len = STORVSC_MAX_CMD_LEN;
18141847

1848+
/*
1849+
* set the table size based on the info we got
1850+
* from the host.
1851+
*/
1852+
host->sg_tablesize = (stor_device->max_transfer_bytes >> PAGE_SHIFT);
1853+
18151854
/* Register the HBA and start the scsi bus scan */
18161855
ret = scsi_add_host(host, &device->device);
18171856
if (ret != 0)

0 commit comments

Comments
 (0)