aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorRishi Mehta <rmehta@vmware.com>2014-03-11 16:51:33 -0400
committerJames Bottomley <JBottomley@Parallels.com>2014-03-19 18:04:45 -0400
commit2a815b5ac374d670f347f2d3a39db07105715398 (patch)
tree8be49db5de5327ac0271efbe3fee7cb6560a2b2f /drivers/scsi
parenta2713cceb3a8efef8b86bec06f10689c95ddbc8c (diff)
[SCSI] vmw_pvscsi: Add support for I/O requests coalescing.
This change allows pvscsi driver to coalesce I/O requests before issuing them. The number of I/O's coalesced can be dynamically configured based on the workload. Signed-off-by: Rishi Mehta <rmehta@vmware.com> Signed-off-by: Arvind Kumar <arvindkumar@vmware.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/vmw_pvscsi.c49
-rw-r--r--drivers/scsi/vmw_pvscsi.h17
2 files changed, 60 insertions, 6 deletions
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index 7c5abd7f6c67..b92ea94be98f 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -72,6 +72,7 @@ struct pvscsi_adapter {
72 bool use_msi; 72 bool use_msi;
73 bool use_msix; 73 bool use_msix;
74 bool use_msg; 74 bool use_msg;
75 bool use_req_threshold;
75 76
76 spinlock_t hw_lock; 77 spinlock_t hw_lock;
77 78
@@ -109,6 +110,7 @@ static int pvscsi_cmd_per_lun = PVSCSI_DEFAULT_QUEUE_DEPTH;
109static bool pvscsi_disable_msi; 110static bool pvscsi_disable_msi;
110static bool pvscsi_disable_msix; 111static bool pvscsi_disable_msix;
111static bool pvscsi_use_msg = true; 112static bool pvscsi_use_msg = true;
113static bool pvscsi_use_req_threshold = true;
112 114
113#define PVSCSI_RW (S_IRUSR | S_IWUSR) 115#define PVSCSI_RW (S_IRUSR | S_IWUSR)
114 116
@@ -133,6 +135,10 @@ MODULE_PARM_DESC(disable_msix, "Disable MSI-X use in driver - (default=0)");
133module_param_named(use_msg, pvscsi_use_msg, bool, PVSCSI_RW); 135module_param_named(use_msg, pvscsi_use_msg, bool, PVSCSI_RW);
134MODULE_PARM_DESC(use_msg, "Use msg ring when available - (default=1)"); 136MODULE_PARM_DESC(use_msg, "Use msg ring when available - (default=1)");
135 137
138module_param_named(use_req_threshold, pvscsi_use_req_threshold,
139 bool, PVSCSI_RW);
140MODULE_PARM_DESC(use_req_threshold, "Use driver-based request coalescing if configured - (default=1)");
141
136static const struct pci_device_id pvscsi_pci_tbl[] = { 142static const struct pci_device_id pvscsi_pci_tbl[] = {
137 { PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_PVSCSI) }, 143 { PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_PVSCSI) },
138 { 0 } 144 { 0 }
@@ -282,10 +288,15 @@ static int scsi_is_rw(unsigned char op)
282static void pvscsi_kick_io(const struct pvscsi_adapter *adapter, 288static void pvscsi_kick_io(const struct pvscsi_adapter *adapter,
283 unsigned char op) 289 unsigned char op)
284{ 290{
285 if (scsi_is_rw(op)) 291 if (scsi_is_rw(op)) {
286 pvscsi_kick_rw_io(adapter); 292 struct PVSCSIRingsState *s = adapter->rings_state;
287 else 293
294 if (!adapter->use_req_threshold ||
295 s->reqProdIdx - s->reqConsIdx >= s->reqCallThreshold)
296 pvscsi_kick_rw_io(adapter);
297 } else {
288 pvscsi_process_request_ring(adapter); 298 pvscsi_process_request_ring(adapter);
299 }
289} 300}
290 301
291static void ll_adapter_reset(const struct pvscsi_adapter *adapter) 302static void ll_adapter_reset(const struct pvscsi_adapter *adapter)
@@ -1077,6 +1088,34 @@ static int pvscsi_setup_msg_workqueue(struct pvscsi_adapter *adapter)
1077 return 1; 1088 return 1;
1078} 1089}
1079 1090
1091static bool pvscsi_setup_req_threshold(struct pvscsi_adapter *adapter,
1092 bool enable)
1093{
1094 u32 val;
1095
1096 if (!pvscsi_use_req_threshold)
1097 return false;
1098
1099 pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_COMMAND,
1100 PVSCSI_CMD_SETUP_REQCALLTHRESHOLD);
1101 val = pvscsi_reg_read(adapter, PVSCSI_REG_OFFSET_COMMAND_STATUS);
1102 if (val == -1) {
1103 printk(KERN_INFO "vmw_pvscsi: device does not support req_threshold\n");
1104 return false;
1105 } else {
1106 struct PVSCSICmdDescSetupReqCall cmd_msg = { 0 };
1107 cmd_msg.enable = enable;
1108 printk(KERN_INFO
1109 "vmw_pvscsi: %sabling reqCallThreshold\n",
1110 enable ? "en" : "dis");
1111 pvscsi_write_cmd_desc(adapter,
1112 PVSCSI_CMD_SETUP_REQCALLTHRESHOLD,
1113 &cmd_msg, sizeof(cmd_msg));
1114 return pvscsi_reg_read(adapter,
1115 PVSCSI_REG_OFFSET_COMMAND_STATUS) != 0;
1116 }
1117}
1118
1080static irqreturn_t pvscsi_isr(int irq, void *devp) 1119static irqreturn_t pvscsi_isr(int irq, void *devp)
1081{ 1120{
1082 struct pvscsi_adapter *adapter = devp; 1121 struct pvscsi_adapter *adapter = devp;
@@ -1416,6 +1455,10 @@ static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1416 flags = IRQF_SHARED; 1455 flags = IRQF_SHARED;
1417 } 1456 }
1418 1457
1458 adapter->use_req_threshold = pvscsi_setup_req_threshold(adapter, true);
1459 printk(KERN_DEBUG "vmw_pvscsi: driver-based request coalescing %sabled\n",
1460 adapter->use_req_threshold ? "en" : "dis");
1461
1419 error = request_irq(adapter->irq, pvscsi_isr, flags, 1462 error = request_irq(adapter->irq, pvscsi_isr, flags,
1420 "vmw_pvscsi", adapter); 1463 "vmw_pvscsi", adapter);
1421 if (error) { 1464 if (error) {
diff --git a/drivers/scsi/vmw_pvscsi.h b/drivers/scsi/vmw_pvscsi.h
index a6437758384f..15a9ac68a50b 100644
--- a/drivers/scsi/vmw_pvscsi.h
+++ b/drivers/scsi/vmw_pvscsi.h
@@ -26,7 +26,7 @@
26 26
27#include <linux/types.h> 27#include <linux/types.h>
28 28
29#define PVSCSI_DRIVER_VERSION_STRING "1.0.3.0-k" 29#define PVSCSI_DRIVER_VERSION_STRING "1.0.4.0-k"
30 30
31#define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128 31#define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128
32 32
@@ -117,8 +117,9 @@ enum PVSCSICommands {
117 PVSCSI_CMD_CONFIG = 7, 117 PVSCSI_CMD_CONFIG = 7,
118 PVSCSI_CMD_SETUP_MSG_RING = 8, 118 PVSCSI_CMD_SETUP_MSG_RING = 8,
119 PVSCSI_CMD_DEVICE_UNPLUG = 9, 119 PVSCSI_CMD_DEVICE_UNPLUG = 9,
120 PVSCSI_CMD_SETUP_REQCALLTHRESHOLD = 10,
120 121
121 PVSCSI_CMD_LAST = 10 /* has to be last */ 122 PVSCSI_CMD_LAST = 11 /* has to be last */
122}; 123};
123 124
124/* 125/*
@@ -141,6 +142,14 @@ struct PVSCSICmdDescConfigCmd {
141 u32 _pad; 142 u32 _pad;
142} __packed; 143} __packed;
143 144
145/*
146 * Command descriptor for PVSCSI_CMD_SETUP_REQCALLTHRESHOLD --
147 */
148
149struct PVSCSICmdDescSetupReqCall {
150 u32 enable;
151} __packed;
152
144enum PVSCSIConfigPageType { 153enum PVSCSIConfigPageType {
145 PVSCSI_CONFIG_PAGE_CONTROLLER = 0x1958, 154 PVSCSI_CONFIG_PAGE_CONTROLLER = 0x1958,
146 PVSCSI_CONFIG_PAGE_PHY = 0x1959, 155 PVSCSI_CONFIG_PAGE_PHY = 0x1959,
@@ -261,7 +270,9 @@ struct PVSCSIRingsState {
261 u32 cmpConsIdx; 270 u32 cmpConsIdx;
262 u32 cmpNumEntriesLog2; 271 u32 cmpNumEntriesLog2;
263 272
264 u8 _pad[104]; 273 u32 reqCallThreshold;
274
275 u8 _pad[100];
265 276
266 u32 msgProdIdx; 277 u32 msgProdIdx;
267 u32 msgConsIdx; 278 u32 msgConsIdx;