* [PATCH V2 0/7] scsi: storvsc: Miscellaneous enhancements and fixes
@ 2015-03-27 7:26 K. Y. Srinivasan
2015-03-27 7:27 ` K. Y. Srinivasan
2015-04-08 16:57 ` James Bottomley
0 siblings, 2 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:26 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
This patch-set addresses perf issues discovered on the Azure storage stack.
These patches also fix a couple of bugs.
As in the first version of this patch-set, some of the patches are simply a resend.
I have bumped up the version number of all patches though. In this version, I have
addressed issues raised by Olaf Hering <olaf@aepfle.de>,
Long Li <longli@microsoft.com> and Venkatesh Srinivas <venkateshs@google.com>
K. Y. Srinivasan (7):
scsi: storvsc: Increase the ring buffer size
scsi: storvsc: Size the queue depth based on the ringbuffer size
scsi: storvsc: Always send on the selected outgoing channel
scsi: storvsc: Retrieve information about the capability of the
target
scsi: storvsc: Fix a bug in copy_from_bounce_buffer()
scsi: storvsc: Don't assume that the scatterlist is not chained
scsi: storvsc: Set the tablesize based on the information given by
the host
drivers/scsi/storvsc_drv.c | 232 ++++++++++++++++++++++++++++----------------
1 files changed, 149 insertions(+), 83 deletions(-)
--
1.7.4.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH V2 1/7] scsi: storvsc: Increase the ring buffer size
2015-03-27 7:26 [PATCH V2 0/7] scsi: storvsc: Miscellaneous enhancements and fixes K. Y. Srinivasan
@ 2015-03-27 7:27 ` K. Y. Srinivasan
2015-04-08 16:57 ` James Bottomley
1 sibling, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
Increase the default ring buffer size as this can significantly
improve performance especially on high latency storage back-ends.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
drivers/scsi/storvsc_drv.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index efc6e44..27fe850 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -308,7 +308,7 @@ enum storvsc_request_type {
* This is the end of Protocol specific defines.
*/
-static int storvsc_ringbuffer_size = (20 * PAGE_SIZE);
+static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
module_param(storvsc_ringbuffer_size, int, S_IRUGO);
MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 1/7] scsi: storvsc: Increase the ring buffer size
@ 2015-03-27 7:27 ` K. Y. Srinivasan
0 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Increase the default ring buffer size as this can significantly
improve performance especially on high latency storage back-ends.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
drivers/scsi/storvsc_drv.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index efc6e44..27fe850 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -308,7 +308,7 @@ enum storvsc_request_type {
* This is the end of Protocol specific defines.
*/
-static int storvsc_ringbuffer_size = (20 * PAGE_SIZE);
+static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
module_param(storvsc_ringbuffer_size, int, S_IRUGO);
MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 2/7] scsi: storvsc: Size the queue depth based on the ringbuffer size
2015-03-27 7:27 ` K. Y. Srinivasan
@ 2015-03-27 7:27 ` K. Y. Srinivasan
-1 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
Size the queue depth based on the ringbuffer size. Also accomodate for the
fact that we could have multiple channels (ringbuffers) per adaptor.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
v2: Fixed a bug in computing queue depth: Venkatesh Srinivas <venkateshs@google.com>
drivers/scsi/storvsc_drv.c | 27 ++++++++++++++++-----------
1 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 27fe850..7f569f9 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -309,10 +309,15 @@ enum storvsc_request_type {
*/
static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
+static u32 max_outstanding_req_per_channel;
+
+static int storvsc_vcpus_per_sub_channel = 4;
module_param(storvsc_ringbuffer_size, int, S_IRUGO);
MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
+module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
+MODULE_PARM_DESC(vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
/*
* Timeout in seconds for all devices managed by this driver.
*/
@@ -320,7 +325,6 @@ static int storvsc_timeout = 180;
static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
-#define STORVSC_MAX_IO_REQUESTS 200
static void storvsc_on_channel_callback(void *context);
@@ -1376,7 +1380,6 @@ static int storvsc_do_io(struct hv_device *device,
static int storvsc_device_configure(struct scsi_device *sdevice)
{
- scsi_change_queue_depth(sdevice, STORVSC_MAX_IO_REQUESTS);
blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE);
@@ -1646,7 +1649,6 @@ static struct scsi_host_template scsi_driver = {
.eh_timed_out = storvsc_eh_timed_out,
.slave_configure = storvsc_device_configure,
.cmd_per_lun = 255,
- .can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
.this_id = -1,
/* no use setting to 0 since ll_blk_rw reset it to 1 */
/* currently 32 */
@@ -1686,6 +1688,7 @@ static int storvsc_probe(struct hv_device *device,
const struct hv_vmbus_device_id *dev_id)
{
int ret;
+ int num_cpus = num_online_cpus();
struct Scsi_Host *host;
struct hv_host_device *host_dev;
bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false);
@@ -1694,6 +1697,7 @@ static int storvsc_probe(struct hv_device *device,
int max_luns_per_target;
int max_targets;
int max_channels;
+ int max_sub_channels = 0;
/*
* Based on the windows host we are running on,
@@ -1719,12 +1723,18 @@ static int storvsc_probe(struct hv_device *device,
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
+ /*
+ * On Windows8 and above, we support sub-channels for storage.
+ * The number of sub-channels offerred is based on the number of
+ * VCPUs in the guest.
+ */
+ max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel);
break;
}
- if (dev_id->driver_data == SFC_GUID)
- scsi_driver.can_queue = (STORVSC_MAX_IO_REQUESTS *
- STORVSC_FC_MAX_TARGETS);
+ scsi_driver.can_queue = (max_outstanding_req_per_channel *
+ (max_sub_channels + 1));
+
host = scsi_host_alloc(&scsi_driver,
sizeof(struct hv_host_device));
if (!host)
@@ -1837,7 +1847,6 @@ static struct hv_driver storvsc_drv = {
static int __init storvsc_drv_init(void)
{
- u32 max_outstanding_req_per_channel;
/*
* Divide the ring buffer data size (which is 1 page less
@@ -1852,10 +1861,6 @@ static int __init storvsc_drv_init(void)
vmscsi_size_delta,
sizeof(u64)));
- if (max_outstanding_req_per_channel <
- STORVSC_MAX_IO_REQUESTS)
- return -EINVAL;
-
return vmbus_driver_register(&storvsc_drv);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 2/7] scsi: storvsc: Size the queue depth based on the ringbuffer size
@ 2015-03-27 7:27 ` K. Y. Srinivasan
0 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Size the queue depth based on the ringbuffer size. Also accomodate for the
fact that we could have multiple channels (ringbuffers) per adaptor.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
v2: Fixed a bug in computing queue depth: Venkatesh Srinivas <venkateshs@google.com>
drivers/scsi/storvsc_drv.c | 27 ++++++++++++++++-----------
1 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 27fe850..7f569f9 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -309,10 +309,15 @@ enum storvsc_request_type {
*/
static int storvsc_ringbuffer_size = (256 * PAGE_SIZE);
+static u32 max_outstanding_req_per_channel;
+
+static int storvsc_vcpus_per_sub_channel = 4;
module_param(storvsc_ringbuffer_size, int, S_IRUGO);
MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
+module_param(storvsc_vcpus_per_sub_channel, int, S_IRUGO);
+MODULE_PARM_DESC(vcpus_per_sub_channel, "Ratio of VCPUs to subchannels");
/*
* Timeout in seconds for all devices managed by this driver.
*/
@@ -320,7 +325,6 @@ static int storvsc_timeout = 180;
static int msft_blist_flags = BLIST_TRY_VPD_PAGES;
-#define STORVSC_MAX_IO_REQUESTS 200
static void storvsc_on_channel_callback(void *context);
@@ -1376,7 +1380,6 @@ static int storvsc_do_io(struct hv_device *device,
static int storvsc_device_configure(struct scsi_device *sdevice)
{
- scsi_change_queue_depth(sdevice, STORVSC_MAX_IO_REQUESTS);
blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE);
@@ -1646,7 +1649,6 @@ static struct scsi_host_template scsi_driver = {
.eh_timed_out = storvsc_eh_timed_out,
.slave_configure = storvsc_device_configure,
.cmd_per_lun = 255,
- .can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
.this_id = -1,
/* no use setting to 0 since ll_blk_rw reset it to 1 */
/* currently 32 */
@@ -1686,6 +1688,7 @@ static int storvsc_probe(struct hv_device *device,
const struct hv_vmbus_device_id *dev_id)
{
int ret;
+ int num_cpus = num_online_cpus();
struct Scsi_Host *host;
struct hv_host_device *host_dev;
bool dev_is_ide = ((dev_id->driver_data == IDE_GUID) ? true : false);
@@ -1694,6 +1697,7 @@ static int storvsc_probe(struct hv_device *device,
int max_luns_per_target;
int max_targets;
int max_channels;
+ int max_sub_channels = 0;
/*
* Based on the windows host we are running on,
@@ -1719,12 +1723,18 @@ static int storvsc_probe(struct hv_device *device,
max_luns_per_target = STORVSC_MAX_LUNS_PER_TARGET;
max_targets = STORVSC_MAX_TARGETS;
max_channels = STORVSC_MAX_CHANNELS;
+ /*
+ * On Windows8 and above, we support sub-channels for storage.
+ * The number of sub-channels offerred is based on the number of
+ * VCPUs in the guest.
+ */
+ max_sub_channels = (num_cpus / storvsc_vcpus_per_sub_channel);
break;
}
- if (dev_id->driver_data == SFC_GUID)
- scsi_driver.can_queue = (STORVSC_MAX_IO_REQUESTS *
- STORVSC_FC_MAX_TARGETS);
+ scsi_driver.can_queue = (max_outstanding_req_per_channel *
+ (max_sub_channels + 1));
+
host = scsi_host_alloc(&scsi_driver,
sizeof(struct hv_host_device));
if (!host)
@@ -1837,7 +1847,6 @@ static struct hv_driver storvsc_drv = {
static int __init storvsc_drv_init(void)
{
- u32 max_outstanding_req_per_channel;
/*
* Divide the ring buffer data size (which is 1 page less
@@ -1852,10 +1861,6 @@ static int __init storvsc_drv_init(void)
vmscsi_size_delta,
sizeof(u64)));
- if (max_outstanding_req_per_channel <
- STORVSC_MAX_IO_REQUESTS)
- return -EINVAL;
-
return vmbus_driver_register(&storvsc_drv);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 3/7] scsi: storvsc: Always send on the selected outgoing channel
2015-03-27 7:27 ` K. Y. Srinivasan
@ 2015-03-27 7:27 ` K. Y. Srinivasan
-1 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
The current code always sent packets without data on the primary channel.
Properly distribute sending of packets with no data amongst all available
channels. I would like to thank Long Li for noticing this problem.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
drivers/scsi/storvsc_drv.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 7f569f9..0ba7f2c 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1362,7 +1362,7 @@ static int storvsc_do_io(struct hv_device *device,
vmscsi_size_delta),
(unsigned long)request);
} else {
- ret = vmbus_sendpacket(device->channel, vstor_packet,
+ ret = vmbus_sendpacket(outgoing_channel, vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
(unsigned long)request,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 3/7] scsi: storvsc: Always send on the selected outgoing channel
@ 2015-03-27 7:27 ` K. Y. Srinivasan
0 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
The current code always sent packets without data on the primary channel.
Properly distribute sending of packets with no data amongst all available
channels. I would like to thank Long Li for noticing this problem.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
drivers/scsi/storvsc_drv.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 7f569f9..0ba7f2c 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1362,7 +1362,7 @@ static int storvsc_do_io(struct hv_device *device,
vmscsi_size_delta),
(unsigned long)request);
} else {
- ret = vmbus_sendpacket(device->channel, vstor_packet,
+ ret = vmbus_sendpacket(outgoing_channel, vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
(unsigned long)request,
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 4/7] scsi: storvsc: Retrieve information about the capability of the target
2015-03-27 7:27 ` K. Y. Srinivasan
@ 2015-03-27 7:27 ` K. Y. Srinivasan
-1 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
The storage protocol informs the guest of the I/O capabilities of the storage
stack. Retrieve this information and use it in the guest.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
drivers/scsi/storvsc_drv.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 0ba7f2c..cdf048b 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -377,6 +377,10 @@ struct storvsc_device {
unsigned char path_id;
unsigned char target_id;
+ /*
+ * Max I/O, the device can support.
+ */
+ u32 max_transfer_bytes;
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
@@ -974,6 +978,8 @@ static int storvsc_channel_init(struct hv_device *device)
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
}
+ stor_device->max_transfer_bytes =
+ vstor_packet->storage_channel_properties.max_transfer_bytes;
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 4/7] scsi: storvsc: Retrieve information about the capability of the target
@ 2015-03-27 7:27 ` K. Y. Srinivasan
0 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
The storage protocol informs the guest of the I/O capabilities of the storage
stack. Retrieve this information and use it in the guest.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
drivers/scsi/storvsc_drv.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 0ba7f2c..cdf048b 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -377,6 +377,10 @@ struct storvsc_device {
unsigned char path_id;
unsigned char target_id;
+ /*
+ * Max I/O, the device can support.
+ */
+ u32 max_transfer_bytes;
/* Used for vsc/vsp channel reset process */
struct storvsc_cmd_request init_request;
struct storvsc_cmd_request reset_request;
@@ -974,6 +978,8 @@ static int storvsc_channel_init(struct hv_device *device)
STORAGE_CHANNEL_SUPPORTS_MULTI_CHANNEL)
process_sub_channels = true;
}
+ stor_device->max_transfer_bytes =
+ vstor_packet->storage_channel_properties.max_transfer_bytes;
memset(vstor_packet, 0, sizeof(struct vstor_packet));
vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 5/7] scsi: storvsc: Fix a bug in copy_from_bounce_buffer()
2015-03-27 7:27 ` K. Y. Srinivasan
@ 2015-03-27 7:27 ` K. Y. Srinivasan
-1 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan, stable
We may exit this function without properly freeing up the maapings
we may have acquired. Fix the bug.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
Cc: <stable@vger.kernel.org>
---
drivers/scsi/storvsc_drv.c | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index cdf048b..f8e4dd9 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -754,21 +754,22 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
if (bounce_sgl[j].length == PAGE_SIZE) {
/* full..move to next entry */
sg_kunmap_atomic(bounce_addr);
+ bounce_addr = 0;
j++;
+ }
- /* if we need to use another bounce buffer */
- if (srclen || i != orig_sgl_count - 1)
- bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+ /* if we need to use another bounce buffer */
+ if (srclen && bounce_addr == 0)
+ bounce_addr = sg_kmap_atomic(bounce_sgl, j);
- } else if (srclen == 0 && i == orig_sgl_count - 1) {
- /* unmap the last bounce that is < PAGE_SIZE */
- sg_kunmap_atomic(bounce_addr);
- }
}
sg_kunmap_atomic(src_addr - orig_sgl[i].offset);
}
+ if (bounce_addr)
+ sg_kunmap_atomic(bounce_addr);
+
local_irq_restore(flags);
return total_copied;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 5/7] scsi: storvsc: Fix a bug in copy_from_bounce_buffer()
@ 2015-03-27 7:27 ` K. Y. Srinivasan
0 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Cc: stable
We may exit this function without properly freeing up the maapings
we may have acquired. Fix the bug.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
Cc: <stable@vger.kernel.org>
---
drivers/scsi/storvsc_drv.c | 15 ++++++++-------
1 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index cdf048b..f8e4dd9 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -754,21 +754,22 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
if (bounce_sgl[j].length == PAGE_SIZE) {
/* full..move to next entry */
sg_kunmap_atomic(bounce_addr);
+ bounce_addr = 0;
j++;
+ }
- /* if we need to use another bounce buffer */
- if (srclen || i != orig_sgl_count - 1)
- bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+ /* if we need to use another bounce buffer */
+ if (srclen && bounce_addr == 0)
+ bounce_addr = sg_kmap_atomic(bounce_sgl, j);
- } else if (srclen == 0 && i == orig_sgl_count - 1) {
- /* unmap the last bounce that is < PAGE_SIZE */
- sg_kunmap_atomic(bounce_addr);
- }
}
sg_kunmap_atomic(src_addr - orig_sgl[i].offset);
}
+ if (bounce_addr)
+ sg_kunmap_atomic(bounce_addr);
+
local_irq_restore(flags);
return total_copied;
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 6/7] scsi: storvsc: Don't assume that the scatterlist is not chained
2015-03-27 7:27 ` K. Y. Srinivasan
@ 2015-03-27 7:27 ` K. Y. Srinivasan
-1 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
The current code assumes that the scatterlists presented are not chained.
Fix the code to not make this assumption.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
V2: Got rid of double assignment. Olaf Hering <olaf@aepfle.de>
drivers/scsi/storvsc_drv.c | 99 +++++++++++++++++++++++++------------------
1 files changed, 57 insertions(+), 42 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index f8e4dd9..4156e29 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -626,19 +626,6 @@ cleanup:
return NULL;
}
-/* Disgusting wrapper functions */
-static inline unsigned long sg_kmap_atomic(struct scatterlist *sgl, int idx)
-{
- void *addr = kmap_atomic(sg_page(sgl + idx));
- return (unsigned long)addr;
-}
-
-static inline void sg_kunmap_atomic(unsigned long addr)
-{
- kunmap_atomic((void *)addr);
-}
-
-
/* Assume the original sgl has enough room */
static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
struct scatterlist *bounce_sgl,
@@ -653,32 +640,38 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
unsigned long bounce_addr = 0;
unsigned long dest_addr = 0;
unsigned long flags;
+ struct scatterlist *cur_dest_sgl;
+ struct scatterlist *cur_src_sgl;
local_irq_save(flags);
-
+ cur_dest_sgl = orig_sgl;
+ cur_src_sgl = bounce_sgl;
for (i = 0; i < orig_sgl_count; i++) {
- dest_addr = sg_kmap_atomic(orig_sgl,i) + orig_sgl[i].offset;
+ dest_addr = (unsigned long)
+ kmap_atomic(sg_page(cur_dest_sgl)) +
+ cur_dest_sgl->offset;
dest = dest_addr;
- destlen = orig_sgl[i].length;
+ destlen = cur_dest_sgl->length;
if (bounce_addr == 0)
- bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+ bounce_addr = (unsigned long)kmap_atomic(
+ sg_page(cur_src_sgl));
while (destlen) {
- src = bounce_addr + bounce_sgl[j].offset;
- srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
+ src = bounce_addr + cur_src_sgl->offset;
+ srclen = cur_src_sgl->length - cur_src_sgl->offset;
copylen = min(srclen, destlen);
memcpy((void *)dest, (void *)src, copylen);
total_copied += copylen;
- bounce_sgl[j].offset += copylen;
+ cur_src_sgl->offset += copylen;
destlen -= copylen;
dest += copylen;
- if (bounce_sgl[j].offset == bounce_sgl[j].length) {
+ if (cur_src_sgl->offset == cur_src_sgl->length) {
/* full */
- sg_kunmap_atomic(bounce_addr);
+ kunmap_atomic((void *)bounce_addr);
j++;
/*
@@ -692,21 +685,27 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
/*
* We are done; cleanup and return.
*/
- sg_kunmap_atomic(dest_addr - orig_sgl[i].offset);
+ kunmap_atomic((void *)(dest_addr -
+ cur_dest_sgl->offset));
local_irq_restore(flags);
return total_copied;
}
/* if we need to use another bounce buffer */
- if (destlen || i != orig_sgl_count - 1)
- bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+ if (destlen || i != orig_sgl_count - 1) {
+ cur_src_sgl = sg_next(cur_src_sgl);
+ bounce_addr = (unsigned long)
+ kmap_atomic(
+ sg_page(cur_src_sgl));
+ }
} else if (destlen == 0 && i == orig_sgl_count - 1) {
/* unmap the last bounce that is < PAGE_SIZE */
- sg_kunmap_atomic(bounce_addr);
+ kunmap_atomic((void *)bounce_addr);
}
}
- sg_kunmap_atomic(dest_addr - orig_sgl[i].offset);
+ kunmap_atomic((void *)(dest_addr - cur_dest_sgl->offset));
+ cur_dest_sgl = sg_next(cur_dest_sgl);
}
local_irq_restore(flags);
@@ -727,48 +726,61 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
unsigned long bounce_addr = 0;
unsigned long src_addr = 0;
unsigned long flags;
+ struct scatterlist *cur_src_sgl;
+ struct scatterlist *cur_dest_sgl;
local_irq_save(flags);
+ cur_src_sgl = orig_sgl;
+ cur_dest_sgl = bounce_sgl;
+
for (i = 0; i < orig_sgl_count; i++) {
- src_addr = sg_kmap_atomic(orig_sgl,i) + orig_sgl[i].offset;
+ src_addr = (unsigned long)
+ kmap_atomic(sg_page(cur_src_sgl)) +
+ cur_src_sgl->offset;
src = src_addr;
- srclen = orig_sgl[i].length;
+ srclen = cur_src_sgl->length;
if (bounce_addr == 0)
- bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+ bounce_addr = (unsigned long)
+ kmap_atomic(sg_page(cur_dest_sgl));
while (srclen) {
/* assume bounce offset always == 0 */
- dest = bounce_addr + bounce_sgl[j].length;
- destlen = PAGE_SIZE - bounce_sgl[j].length;
+ dest = bounce_addr + cur_dest_sgl->length;
+ destlen = PAGE_SIZE - cur_dest_sgl->length;
copylen = min(srclen, destlen);
memcpy((void *)dest, (void *)src, copylen);
total_copied += copylen;
- bounce_sgl[j].length += copylen;
+ cur_dest_sgl->length += copylen;
srclen -= copylen;
src += copylen;
- if (bounce_sgl[j].length == PAGE_SIZE) {
+ if (cur_dest_sgl->length == PAGE_SIZE) {
/* full..move to next entry */
- sg_kunmap_atomic(bounce_addr);
+ kunmap_atomic((void *)bounce_addr);
bounce_addr = 0;
j++;
}
/* if we need to use another bounce buffer */
- if (srclen && bounce_addr == 0)
- bounce_addr = sg_kmap_atomic(bounce_sgl, j);
+ if (srclen && bounce_addr == 0) {
+ cur_dest_sgl = sg_next(cur_dest_sgl);
+ bounce_addr = (unsigned long)
+ kmap_atomic(
+ sg_page(cur_dest_sgl));
+ }
}
- sg_kunmap_atomic(src_addr - orig_sgl[i].offset);
+ kunmap_atomic((void *)(src_addr - cur_src_sgl->offset));
+ cur_src_sgl = sg_next(cur_src_sgl);
}
if (bounce_addr)
- sg_kunmap_atomic(bounce_addr);
+ kunmap_atomic((void *)bounce_addr);
local_irq_restore(flags);
@@ -1536,6 +1548,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
struct scatterlist *sgl;
unsigned int sg_count = 0;
struct vmscsi_request *vm_srb;
+ struct scatterlist *cur_sgl;
if (vmstor_current_major <= VMSTOR_WIN8_MAJOR) {
/*
@@ -1617,10 +1630,12 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
}
cmd_request->data_buffer.offset = sgl[0].offset;
-
- for (i = 0; i < sg_count; i++)
+ cur_sgl = sgl;
+ for (i = 0; i < sg_count; i++) {
cmd_request->data_buffer.pfn_array[i] =
- page_to_pfn(sg_page((&sgl[i])));
+ page_to_pfn(sg_page((cur_sgl)));
+ cur_sgl = sg_next(cur_sgl);
+ }
} else if (scsi_sglist(scmnd)) {
cmd_request->data_buffer.offset =
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH V2 6/7] scsi: storvsc: Don't assume that the scatterlist is not chained
@ 2015-03-27 7:27 ` K. Y. Srinivasan
0 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
The current code assumes that the scatterlists presented are not chained.
Fix the code to not make this assumption.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
---
V2: Got rid of double assignment. Olaf Hering <olaf@aepfle.de>
drivers/scsi/storvsc_drv.c | 99 +++++++++++++++++++++++++------------------
1 files changed, 57 insertions(+), 42 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index f8e4dd9..4156e29 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -626,19 +626,6 @@ cleanup:
return NULL;
}
-/* Disgusting wrapper functions */
-static inline unsigned long sg_kmap_atomic(struct scatterlist *sgl, int idx)
-{
- void *addr = kmap_atomic(sg_page(sgl + idx));
- return (unsigned long)addr;
-}
-
-static inline void sg_kunmap_atomic(unsigned long addr)
-{
- kunmap_atomic((void *)addr);
-}
-
-
/* Assume the original sgl has enough room */
static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
struct scatterlist *bounce_sgl,
@@ -653,32 +640,38 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
unsigned long bounce_addr = 0;
unsigned long dest_addr = 0;
unsigned long flags;
+ struct scatterlist *cur_dest_sgl;
+ struct scatterlist *cur_src_sgl;
local_irq_save(flags);
-
+ cur_dest_sgl = orig_sgl;
+ cur_src_sgl = bounce_sgl;
for (i = 0; i < orig_sgl_count; i++) {
- dest_addr = sg_kmap_atomic(orig_sgl,i) + orig_sgl[i].offset;
+ dest_addr = (unsigned long)
+ kmap_atomic(sg_page(cur_dest_sgl)) +
+ cur_dest_sgl->offset;
dest = dest_addr;
- destlen = orig_sgl[i].length;
+ destlen = cur_dest_sgl->length;
if (bounce_addr == 0)
- bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+ bounce_addr = (unsigned long)kmap_atomic(
+ sg_page(cur_src_sgl));
while (destlen) {
- src = bounce_addr + bounce_sgl[j].offset;
- srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
+ src = bounce_addr + cur_src_sgl->offset;
+ srclen = cur_src_sgl->length - cur_src_sgl->offset;
copylen = min(srclen, destlen);
memcpy((void *)dest, (void *)src, copylen);
total_copied += copylen;
- bounce_sgl[j].offset += copylen;
+ cur_src_sgl->offset += copylen;
destlen -= copylen;
dest += copylen;
- if (bounce_sgl[j].offset == bounce_sgl[j].length) {
+ if (cur_src_sgl->offset == cur_src_sgl->length) {
/* full */
- sg_kunmap_atomic(bounce_addr);
+ kunmap_atomic((void *)bounce_addr);
j++;
/*
@@ -692,21 +685,27 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
/*
* We are done; cleanup and return.
*/
- sg_kunmap_atomic(dest_addr - orig_sgl[i].offset);
+ kunmap_atomic((void *)(dest_addr -
+ cur_dest_sgl->offset));
local_irq_restore(flags);
return total_copied;
}
/* if we need to use another bounce buffer */
- if (destlen || i != orig_sgl_count - 1)
- bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+ if (destlen || i != orig_sgl_count - 1) {
+ cur_src_sgl = sg_next(cur_src_sgl);
+ bounce_addr = (unsigned long)
+ kmap_atomic(
+ sg_page(cur_src_sgl));
+ }
} else if (destlen == 0 && i == orig_sgl_count - 1) {
/* unmap the last bounce that is < PAGE_SIZE */
- sg_kunmap_atomic(bounce_addr);
+ kunmap_atomic((void *)bounce_addr);
}
}
- sg_kunmap_atomic(dest_addr - orig_sgl[i].offset);
+ kunmap_atomic((void *)(dest_addr - cur_dest_sgl->offset));
+ cur_dest_sgl = sg_next(cur_dest_sgl);
}
local_irq_restore(flags);
@@ -727,48 +726,61 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
unsigned long bounce_addr = 0;
unsigned long src_addr = 0;
unsigned long flags;
+ struct scatterlist *cur_src_sgl;
+ struct scatterlist *cur_dest_sgl;
local_irq_save(flags);
+ cur_src_sgl = orig_sgl;
+ cur_dest_sgl = bounce_sgl;
+
for (i = 0; i < orig_sgl_count; i++) {
- src_addr = sg_kmap_atomic(orig_sgl,i) + orig_sgl[i].offset;
+ src_addr = (unsigned long)
+ kmap_atomic(sg_page(cur_src_sgl)) +
+ cur_src_sgl->offset;
src = src_addr;
- srclen = orig_sgl[i].length;
+ srclen = cur_src_sgl->length;
if (bounce_addr == 0)
- bounce_addr = sg_kmap_atomic(bounce_sgl,j);
+ bounce_addr = (unsigned long)
+ kmap_atomic(sg_page(cur_dest_sgl));
while (srclen) {
/* assume bounce offset always == 0 */
- dest = bounce_addr + bounce_sgl[j].length;
- destlen = PAGE_SIZE - bounce_sgl[j].length;
+ dest = bounce_addr + cur_dest_sgl->length;
+ destlen = PAGE_SIZE - cur_dest_sgl->length;
copylen = min(srclen, destlen);
memcpy((void *)dest, (void *)src, copylen);
total_copied += copylen;
- bounce_sgl[j].length += copylen;
+ cur_dest_sgl->length += copylen;
srclen -= copylen;
src += copylen;
- if (bounce_sgl[j].length == PAGE_SIZE) {
+ if (cur_dest_sgl->length == PAGE_SIZE) {
/* full..move to next entry */
- sg_kunmap_atomic(bounce_addr);
+ kunmap_atomic((void *)bounce_addr);
bounce_addr = 0;
j++;
}
/* if we need to use another bounce buffer */
- if (srclen && bounce_addr == 0)
- bounce_addr = sg_kmap_atomic(bounce_sgl, j);
+ if (srclen && bounce_addr == 0) {
+ cur_dest_sgl = sg_next(cur_dest_sgl);
+ bounce_addr = (unsigned long)
+ kmap_atomic(
+ sg_page(cur_dest_sgl));
+ }
}
- sg_kunmap_atomic(src_addr - orig_sgl[i].offset);
+ kunmap_atomic((void *)(src_addr - cur_src_sgl->offset));
+ cur_src_sgl = sg_next(cur_src_sgl);
}
if (bounce_addr)
- sg_kunmap_atomic(bounce_addr);
+ kunmap_atomic((void *)bounce_addr);
local_irq_restore(flags);
@@ -1536,6 +1548,7 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
struct scatterlist *sgl;
unsigned int sg_count = 0;
struct vmscsi_request *vm_srb;
+ struct scatterlist *cur_sgl;
if (vmstor_current_major <= VMSTOR_WIN8_MAJOR) {
/*
@@ -1617,10 +1630,12 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
}
cmd_request->data_buffer.offset = sgl[0].offset;
-
- for (i = 0; i < sg_count; i++)
+ cur_sgl = sgl;
+ for (i = 0; i < sg_count; i++) {
cmd_request->data_buffer.pfn_array[i] =
- page_to_pfn(sg_page((&sgl[i])));
+ page_to_pfn(sg_page((cur_sgl)));
+ cur_sgl = sg_next(cur_sgl);
+ }
} else if (scsi_sglist(scmnd)) {
cmd_request->data_buffer.offset =
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 7/7] scsi: storvsc: Set the tablesize based on the information given by the host
2015-03-27 7:27 ` K. Y. Srinivasan
` (5 preceding siblings ...)
(?)
@ 2015-03-27 7:27 ` K. Y. Srinivasan
-1 siblings, 0 replies; 16+ messages in thread
From: K. Y. Srinivasan @ 2015-03-27 7:27 UTC (permalink / raw)
To: gregkh, linux-kernel, devel, ohering, jbottomley, hch,
linux-scsi, apw, vkuznets, jasowang
Cc: K. Y. Srinivasan
Set the tablesize based on the information given by the host.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
Tested-by: Long Li <longli@microsoft.com>
---
drivers/scsi/storvsc_drv.c | 89 +++++++++++++++++++++++++++++++------------
1 files changed, 64 insertions(+), 25 deletions(-)
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 4156e29..d9dad90 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -351,7 +351,10 @@ struct storvsc_cmd_request {
/* Synchronize the request/response if needed */
struct completion wait_event;
- struct hv_multipage_buffer data_buffer;
+ struct vmbus_channel_packet_multipage_buffer mpb;
+ struct vmbus_packet_mpb_array *payload;
+ u32 payload_sz;
+
struct vstor_packet vstor_packet;
};
@@ -1103,6 +1106,8 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
struct Scsi_Host *host;
struct storvsc_device *stor_dev;
struct hv_device *dev = host_dev->dev;
+ u32 payload_sz = cmd_request->payload_sz;
+ void *payload = cmd_request->payload;
stor_dev = get_in_stor_device(dev);
host = stor_dev->host;
@@ -1132,10 +1137,14 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
sense_hdr.ascq);
scsi_set_resid(scmnd,
- cmd_request->data_buffer.len -
+ cmd_request->payload->range.len -
vm_srb->data_transfer_length);
scmnd->scsi_done(scmnd);
+
+ if (payload_sz >
+ sizeof(struct vmbus_channel_packet_multipage_buffer))
+ kfree(payload);
}
static void storvsc_on_io_completion(struct hv_device *device,
@@ -1337,7 +1346,7 @@ static int storvsc_dev_remove(struct hv_device *device)
}
static int storvsc_do_io(struct hv_device *device,
- struct storvsc_cmd_request *request)
+ struct storvsc_cmd_request *request)
{
struct storvsc_device *stor_device;
struct vstor_packet *vstor_packet;
@@ -1369,13 +1378,14 @@ static int storvsc_do_io(struct hv_device *device,
vstor_packet->vm_srb.data_transfer_length =
- request->data_buffer.len;
+ request->payload->range.len;
vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
- if (request->data_buffer.len) {
- ret = vmbus_sendpacket_multipagebuffer(outgoing_channel,
- &request->data_buffer,
+ if (request->payload->range.len) {
+
+ ret = vmbus_sendpacket_mpb_desc(outgoing_channel,
+ request->payload, request->payload_sz,
vstor_packet,
(sizeof(struct vstor_packet) -
vmscsi_size_delta),
@@ -1549,6 +1559,9 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
unsigned int sg_count = 0;
struct vmscsi_request *vm_srb;
struct scatterlist *cur_sgl;
+ struct vmbus_packet_mpb_array *payload;
+ u32 payload_sz;
+ u32 length;
if (vmstor_current_major <= VMSTOR_WIN8_MAJOR) {
/*
@@ -1602,48 +1615,71 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length);
- cmd_request->data_buffer.len = scsi_bufflen(scmnd);
- if (scsi_sg_count(scmnd)) {
- sgl = (struct scatterlist *)scsi_sglist(scmnd);
- sg_count = scsi_sg_count(scmnd);
+ sgl = (struct scatterlist *)scsi_sglist(scmnd);
+ sg_count = scsi_sg_count(scmnd);
+ length = scsi_bufflen(scmnd);
+ payload = (struct vmbus_packet_mpb_array *)&cmd_request->mpb;
+ payload_sz = sizeof(cmd_request->mpb);
+
+ if (sg_count) {
/* check if we need to bounce the sgl */
if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
cmd_request->bounce_sgl =
- create_bounce_buffer(sgl, scsi_sg_count(scmnd),
- scsi_bufflen(scmnd),
+ create_bounce_buffer(sgl, sg_count,
+ length,
vm_srb->data_in);
if (!cmd_request->bounce_sgl)
return SCSI_MLQUEUE_HOST_BUSY;
cmd_request->bounce_sgl_count =
- ALIGN(scsi_bufflen(scmnd), PAGE_SIZE) >>
- PAGE_SHIFT;
+ ALIGN(length, PAGE_SIZE) >> PAGE_SHIFT;
if (vm_srb->data_in == WRITE_TYPE)
copy_to_bounce_buffer(sgl,
- cmd_request->bounce_sgl,
- scsi_sg_count(scmnd));
+ cmd_request->bounce_sgl, sg_count);
sgl = cmd_request->bounce_sgl;
sg_count = cmd_request->bounce_sgl_count;
}
- cmd_request->data_buffer.offset = sgl[0].offset;
+
+ if (sg_count > MAX_PAGE_BUFFER_COUNT) {
+
+ payload_sz = (sg_count * sizeof(void *) +
+ sizeof(struct vmbus_packet_mpb_array));
+ payload = kmalloc(payload_sz, GFP_ATOMIC);
+ if (!payload) {
+ if (cmd_request->bounce_sgl_count)
+ destroy_bounce_buffer(
+ cmd_request->bounce_sgl,
+ cmd_request->bounce_sgl_count);
+
+ return SCSI_MLQUEUE_DEVICE_BUSY;
+ }
+ }
+
+ payload->range.len = length;
+ payload->range.offset = sgl[0].offset;
+
cur_sgl = sgl;
for (i = 0; i < sg_count; i++) {
- cmd_request->data_buffer.pfn_array[i] =
+ payload->range.pfn_array[i] =
page_to_pfn(sg_page((cur_sgl)));
cur_sgl = sg_next(cur_sgl);
}
} else if (scsi_sglist(scmnd)) {
- cmd_request->data_buffer.offset =
+ payload->range.len = length;
+ payload->range.offset =
virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1);
- cmd_request->data_buffer.pfn_array[0] =
+ payload->range.pfn_array[0] =
virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT;
}
+ cmd_request->payload = payload;
+ cmd_request->payload_sz = payload_sz;
+
/* Invokes the vsc to start an IO */
ret = storvsc_do_io(dev, cmd_request);
@@ -1672,10 +1708,7 @@ static struct scsi_host_template scsi_driver = {
.slave_configure = storvsc_device_configure,
.cmd_per_lun = 255,
.this_id = -1,
- /* no use setting to 0 since ll_blk_rw reset it to 1 */
- /* currently 32 */
- .sg_tablesize = MAX_MULTIPAGE_BUFFER_COUNT,
- .use_clustering = DISABLE_CLUSTERING,
+ .use_clustering = ENABLE_CLUSTERING,
/* Make sure we dont get a sg segment crosses a page boundary */
.dma_boundary = PAGE_SIZE-1,
.no_write_same = 1,
@@ -1812,6 +1845,12 @@ 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.
+ */
+ host->sg_tablesize = (stor_device->max_transfer_bytes >> PAGE_SHIFT);
+
/* Register the HBA and start the scsi bus scan */
ret = scsi_add_host(host, &device->device);
if (ret != 0)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH V2 0/7] scsi: storvsc: Miscellaneous enhancements and fixes
2015-03-27 7:26 [PATCH V2 0/7] scsi: storvsc: Miscellaneous enhancements and fixes K. Y. Srinivasan
@ 2015-04-08 16:57 ` James Bottomley
2015-04-08 16:57 ` James Bottomley
1 sibling, 0 replies; 16+ messages in thread
From: James Bottomley @ 2015-04-08 16:57 UTC (permalink / raw)
To: K. Y. Srinivasan
Cc: gregkh, linux-kernel, devel, ohering, hch, linux-scsi, apw,
vkuznets, jasowang
On Fri, 2015-03-27 at 00:26 -0700, K. Y. Srinivasan wrote:
> This patch-set addresses perf issues discovered on the Azure storage stack.
> These patches also fix a couple of bugs.
>
> As in the first version of this patch-set, some of the patches are simply a resend.
> I have bumped up the version number of all patches though. In this version, I have
> addressed issues raised by Olaf Hering <olaf@aepfle.de>,
> Long Li <longli@microsoft.com> and Venkatesh Srinivas <venkateshs@google.com>
Well, I was waiting for a reviewed-by from Olaf and Venkatesh, but I
guess that's not forthcoming.
James
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH V2 0/7] scsi: storvsc: Miscellaneous enhancements and fixes
@ 2015-04-08 16:57 ` James Bottomley
0 siblings, 0 replies; 16+ messages in thread
From: James Bottomley @ 2015-04-08 16:57 UTC (permalink / raw)
To: K. Y. Srinivasan
Cc: linux-scsi, gregkh, jasowang, ohering, linux-kernel, hch, apw, devel
On Fri, 2015-03-27 at 00:26 -0700, K. Y. Srinivasan wrote:
> This patch-set addresses perf issues discovered on the Azure storage stack.
> These patches also fix a couple of bugs.
>
> As in the first version of this patch-set, some of the patches are simply a resend.
> I have bumped up the version number of all patches though. In this version, I have
> addressed issues raised by Olaf Hering <olaf@aepfle.de>,
> Long Li <longli@microsoft.com> and Venkatesh Srinivas <venkateshs@google.com>
Well, I was waiting for a reviewed-by from Olaf and Venkatesh, but I
guess that's not forthcoming.
James
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2015-04-08 16:57 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-27 7:26 [PATCH V2 0/7] scsi: storvsc: Miscellaneous enhancements and fixes K. Y. Srinivasan
2015-03-27 7:27 ` [PATCH V2 1/7] scsi: storvsc: Increase the ring buffer size K. Y. Srinivasan
2015-03-27 7:27 ` K. Y. Srinivasan
2015-03-27 7:27 ` [PATCH V2 2/7] scsi: storvsc: Size the queue depth based on the ringbuffer size K. Y. Srinivasan
2015-03-27 7:27 ` K. Y. Srinivasan
2015-03-27 7:27 ` [PATCH V2 3/7] scsi: storvsc: Always send on the selected outgoing channel K. Y. Srinivasan
2015-03-27 7:27 ` K. Y. Srinivasan
2015-03-27 7:27 ` [PATCH V2 4/7] scsi: storvsc: Retrieve information about the capability of the target K. Y. Srinivasan
2015-03-27 7:27 ` K. Y. Srinivasan
2015-03-27 7:27 ` [PATCH V2 5/7] scsi: storvsc: Fix a bug in copy_from_bounce_buffer() K. Y. Srinivasan
2015-03-27 7:27 ` K. Y. Srinivasan
2015-03-27 7:27 ` [PATCH V2 6/7] scsi: storvsc: Don't assume that the scatterlist is not chained K. Y. Srinivasan
2015-03-27 7:27 ` K. Y. Srinivasan
2015-03-27 7:27 ` [PATCH 7/7] scsi: storvsc: Set the tablesize based on the information given by the host K. Y. Srinivasan
2015-04-08 16:57 ` [PATCH V2 0/7] scsi: storvsc: Miscellaneous enhancements and fixes James Bottomley
2015-04-08 16:57 ` James Bottomley
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.