|
@@ -72,6 +72,7 @@ struct pvscsi_adapter {
|
|
|
bool use_msi;
|
|
|
bool use_msix;
|
|
|
bool use_msg;
|
|
|
+ bool use_req_threshold;
|
|
|
|
|
|
spinlock_t hw_lock;
|
|
|
|
|
@@ -109,6 +110,7 @@ static int pvscsi_cmd_per_lun = PVSCSI_DEFAULT_QUEUE_DEPTH;
|
|
|
static bool pvscsi_disable_msi;
|
|
|
static bool pvscsi_disable_msix;
|
|
|
static bool pvscsi_use_msg = true;
|
|
|
+static bool pvscsi_use_req_threshold = true;
|
|
|
|
|
|
#define PVSCSI_RW (S_IRUSR | S_IWUSR)
|
|
|
|
|
@@ -133,6 +135,10 @@ MODULE_PARM_DESC(disable_msix, "Disable MSI-X use in driver - (default=0)");
|
|
|
module_param_named(use_msg, pvscsi_use_msg, bool, PVSCSI_RW);
|
|
|
MODULE_PARM_DESC(use_msg, "Use msg ring when available - (default=1)");
|
|
|
|
|
|
+module_param_named(use_req_threshold, pvscsi_use_req_threshold,
|
|
|
+ bool, PVSCSI_RW);
|
|
|
+MODULE_PARM_DESC(use_req_threshold, "Use driver-based request coalescing if configured - (default=1)");
|
|
|
+
|
|
|
static const struct pci_device_id pvscsi_pci_tbl[] = {
|
|
|
{ PCI_VDEVICE(VMWARE, PCI_DEVICE_ID_VMWARE_PVSCSI) },
|
|
|
{ 0 }
|
|
@@ -282,10 +288,15 @@ static int scsi_is_rw(unsigned char op)
|
|
|
static void pvscsi_kick_io(const struct pvscsi_adapter *adapter,
|
|
|
unsigned char op)
|
|
|
{
|
|
|
- if (scsi_is_rw(op))
|
|
|
- pvscsi_kick_rw_io(adapter);
|
|
|
- else
|
|
|
+ if (scsi_is_rw(op)) {
|
|
|
+ struct PVSCSIRingsState *s = adapter->rings_state;
|
|
|
+
|
|
|
+ if (!adapter->use_req_threshold ||
|
|
|
+ s->reqProdIdx - s->reqConsIdx >= s->reqCallThreshold)
|
|
|
+ pvscsi_kick_rw_io(adapter);
|
|
|
+ } else {
|
|
|
pvscsi_process_request_ring(adapter);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static void ll_adapter_reset(const struct pvscsi_adapter *adapter)
|
|
@@ -1077,6 +1088,34 @@ static int pvscsi_setup_msg_workqueue(struct pvscsi_adapter *adapter)
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+static bool pvscsi_setup_req_threshold(struct pvscsi_adapter *adapter,
|
|
|
+ bool enable)
|
|
|
+{
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ if (!pvscsi_use_req_threshold)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ pvscsi_reg_write(adapter, PVSCSI_REG_OFFSET_COMMAND,
|
|
|
+ PVSCSI_CMD_SETUP_REQCALLTHRESHOLD);
|
|
|
+ val = pvscsi_reg_read(adapter, PVSCSI_REG_OFFSET_COMMAND_STATUS);
|
|
|
+ if (val == -1) {
|
|
|
+ printk(KERN_INFO "vmw_pvscsi: device does not support req_threshold\n");
|
|
|
+ return false;
|
|
|
+ } else {
|
|
|
+ struct PVSCSICmdDescSetupReqCall cmd_msg = { 0 };
|
|
|
+ cmd_msg.enable = enable;
|
|
|
+ printk(KERN_INFO
|
|
|
+ "vmw_pvscsi: %sabling reqCallThreshold\n",
|
|
|
+ enable ? "en" : "dis");
|
|
|
+ pvscsi_write_cmd_desc(adapter,
|
|
|
+ PVSCSI_CMD_SETUP_REQCALLTHRESHOLD,
|
|
|
+ &cmd_msg, sizeof(cmd_msg));
|
|
|
+ return pvscsi_reg_read(adapter,
|
|
|
+ PVSCSI_REG_OFFSET_COMMAND_STATUS) != 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static irqreturn_t pvscsi_isr(int irq, void *devp)
|
|
|
{
|
|
|
struct pvscsi_adapter *adapter = devp;
|
|
@@ -1416,6 +1455,10 @@ static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
flags = IRQF_SHARED;
|
|
|
}
|
|
|
|
|
|
+ adapter->use_req_threshold = pvscsi_setup_req_threshold(adapter, true);
|
|
|
+ printk(KERN_DEBUG "vmw_pvscsi: driver-based request coalescing %sabled\n",
|
|
|
+ adapter->use_req_threshold ? "en" : "dis");
|
|
|
+
|
|
|
error = request_irq(adapter->irq, pvscsi_isr, flags,
|
|
|
"vmw_pvscsi", adapter);
|
|
|
if (error) {
|