Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a815b5a authored by Rishi Mehta's avatar Rishi Mehta Committed by James Bottomley
Browse files

[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: default avatarRishi Mehta <rmehta@vmware.com>
Signed-off-by: default avatarArvind Kumar <arvindkumar@vmware.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent a2713cce
Loading
Loading
Loading
Loading
+46 −3
Original line number Diff line number Diff line
@@ -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,11 +288,16 @@ 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))
	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
	} 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) {
+14 −3
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@

#include <linux/types.h>

#define PVSCSI_DRIVER_VERSION_STRING   "1.0.3.0-k"
#define PVSCSI_DRIVER_VERSION_STRING   "1.0.4.0-k"

#define PVSCSI_MAX_NUM_SG_ENTRIES_PER_SEGMENT 128

@@ -117,8 +117,9 @@ enum PVSCSICommands {
	PVSCSI_CMD_CONFIG            = 7,
	PVSCSI_CMD_SETUP_MSG_RING    = 8,
	PVSCSI_CMD_DEVICE_UNPLUG     = 9,
	PVSCSI_CMD_SETUP_REQCALLTHRESHOLD     = 10,

	PVSCSI_CMD_LAST              = 10  /* has to be last */
	PVSCSI_CMD_LAST              = 11  /* has to be last */
};

/*
@@ -141,6 +142,14 @@ struct PVSCSICmdDescConfigCmd {
	u32 _pad;
} __packed;

/*
 * Command descriptor for PVSCSI_CMD_SETUP_REQCALLTHRESHOLD --
 */

struct PVSCSICmdDescSetupReqCall {
	u32 enable;
} __packed;

enum PVSCSIConfigPageType {
	PVSCSI_CONFIG_PAGE_CONTROLLER = 0x1958,
	PVSCSI_CONFIG_PAGE_PHY        = 0x1959,
@@ -261,7 +270,9 @@ struct PVSCSIRingsState {
	u32	cmpConsIdx;
	u32	cmpNumEntriesLog2;

	u8	_pad[104];
	u32	reqCallThreshold;

	u8	_pad[100];

	u32	msgProdIdx;
	u32	msgConsIdx;