aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/vmw_pvscsi.c
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/vmw_pvscsi.c
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/vmw_pvscsi.c')
-rw-r--r--drivers/scsi/vmw_pvscsi.c49
1 files changed, 46 insertions, 3 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) {