Commit 911ae943 authored by nagalakshmi.nandigama@lsi.com's avatar nagalakshmi.nandigama@lsi.com Committed by James Bottomley

[SCSI] mpt2sas: Added NUNA IO support in driver which uses multi-reply queue support of the HBA

Support added for controllers capable of multi reply queues.

The following are the modifications to the driver to support NUMA.

1) Create the new structure adapter_reply_queue to contain the reply queue
   info for every msix vector.  This object will contain a
   reply_post_host_index, reply_post_free for each instance, msix_index, among
   other parameters.  We will track all the reply queues on a link list called
   ioc->reply_queue_list. Each reply queue is aligned with each IRQ, and is
   passed to the interrupt via the bus_id parameter.

(2) The driver will figure out the msix_vector_count from the PCIe MSIX
    capabilities register instead of the IOC Facts->MaxMSIxVectors. This is
    because the firmware is not filling in this field until the driver has
    already registered MSIX support.

(3) If the ioc_facts reports that the controller is MSIX compatible in the
    capabilities, then the driver will request for multiple irqs.  This count
    is calculated based on the minimum between the online cpus available and
    the ioc->msix_vector_count.  This count is reported to firmware in the
    ioc_init request.

(4) New routines were added _base_free_irq and _base_request_irq, so
    registering and freeing msix vectors were done thru simple function API.

(5) The new routine _base_assign_reply_queues was added to align the msix
    indexes across cpus. This will initialize the array called
    ioc->cpu_msix_table.  This array is looked up on every MPI request so the
    MSIxIndex is set appropriately.

(6) A new shost sysfs attribute was added to report the reply_queue_count.

(7) User needs to set the affinity cpu mask, so the interrupts occur on the
    same cpu that sent the original request.
Signed-off-by: default avatarNagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 66195fc9
This diff is collapsed.
......@@ -544,6 +544,28 @@ struct _tr_list {
typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);
/**
* struct adapter_reply_queue - the reply queue struct
* @ioc: per adapter object
* @msix_index: msix index into vector table
* @vector: irq vector
* @reply_post_host_index: head index in the pool where FW completes IO
* @reply_post_free: reply post base virt address
* @name: the name registered to request_irq()
* @busy: isr is actively processing replies on another cpu
* @list: this list
*/
struct adapter_reply_queue {
struct MPT2SAS_ADAPTER *ioc;
u8 msix_index;
unsigned int vector;
u32 reply_post_host_index;
Mpi2ReplyDescriptorsUnion_t *reply_post_free;
char name[MPT_NAME_LENGTH];
atomic_t busy;
struct list_head list;
};
/* IOC Facts and Port Facts converted from little endian to cpu */
union mpi2_version_union {
MPI2_VERSION_STRUCT Struct;
......@@ -606,7 +628,7 @@ enum mutex_type {
* @list: ioc_list
* @shost: shost object
* @id: unique adapter id
* @pci_irq: irq number
* @cpu_count: number online cpus
* @name: generic ioc string
* @tmp_string: tmp string used for logging
* @pdev: pci pdev object
......@@ -636,8 +658,8 @@ enum mutex_type {
* @wait_for_port_enable_to_complete:
* @msix_enable: flag indicating msix is enabled
* @msix_vector_count: number msix vectors
* @msix_table: virt address to the msix table
* @msix_table_backup: backup msix table
* @cpu_msix_table: table for mapping cpus to msix index
* @cpu_msix_table_sz: table size
* @scsi_io_cb_idx: shost generated commands
* @tm_cb_idx: task management commands
* @scsih_cb_idx: scsih internal commands
......@@ -728,7 +750,8 @@ enum mutex_type {
* @reply_post_queue_depth: reply post queue depth
* @reply_post_free: pool for reply post (64bit descriptor)
* @reply_post_free_dma:
* @reply_post_free_dma_pool:
* @reply_queue_count: number of reply queue's
* @reply_queue_list: link list contaning the reply queue info
* @reply_post_host_index: head index in the pool where FW completes IO
* @delayed_tr_list: target reset link list
* @delayed_tr_volume_list: volume target reset link list
......@@ -737,7 +760,7 @@ struct MPT2SAS_ADAPTER {
struct list_head list;
struct Scsi_Host *shost;
u8 id;
u32 pci_irq;
int cpu_count;
char name[MPT_NAME_LENGTH];
char tmp_string[MPT_STRING_LENGTH];
struct pci_dev *pdev;
......@@ -779,8 +802,9 @@ struct MPT2SAS_ADAPTER {
u8 msix_enable;
u16 msix_vector_count;
u32 *msix_table;
u32 *msix_table_backup;
u8 *cpu_msix_table;
resource_size_t **reply_post_host_index;
u16 cpu_msix_table_sz;
u32 ioc_reset_count;
/* internal commands, callback index */
......@@ -911,7 +935,8 @@ struct MPT2SAS_ADAPTER {
Mpi2ReplyDescriptorsUnion_t *reply_post_free;
dma_addr_t reply_post_free_dma;
struct dma_pool *reply_post_free_dma_pool;
u32 reply_post_host_index;
u8 reply_queue_count;
struct list_head reply_queue_list;
struct list_head delayed_tr_list;
struct list_head delayed_tr_volume_list;
......@@ -955,6 +980,7 @@ void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
__le32 mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
u16 smid);
void mpt2sas_base_flush_reply_queues(struct MPT2SAS_ADAPTER *ioc);
/* hi-priority queue */
u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx);
......
......@@ -2705,6 +2705,33 @@ _ctl_ioc_reset_count_show(struct device *cdev, struct device_attribute *attr,
static DEVICE_ATTR(ioc_reset_count, S_IRUGO,
_ctl_ioc_reset_count_show, NULL);
/**
* _ctl_ioc_reply_queue_count_show - number of reply queues
* @cdev - pointer to embedded class device
* @buf - the buffer returned
*
* This is number of reply queues
*
* A sysfs 'read-only' shost attribute.
*/
static ssize_t
_ctl_ioc_reply_queue_count_show(struct device *cdev,
struct device_attribute *attr, char *buf)
{
u8 reply_queue_count;
struct Scsi_Host *shost = class_to_shost(cdev);
struct MPT2SAS_ADAPTER *ioc = shost_priv(shost);
if ((ioc->facts.IOCCapabilities &
MPI2_IOCFACTS_CAPABILITY_MSI_X_INDEX) && ioc->msix_enable)
reply_queue_count = ioc->reply_queue_count;
else
reply_queue_count = 1;
return snprintf(buf, PAGE_SIZE, "%d\n", reply_queue_count);
}
static DEVICE_ATTR(reply_queue_count, S_IRUGO,
_ctl_ioc_reply_queue_count_show, NULL);
struct DIAG_BUFFER_START {
__le32 Size;
__le32 DiagVersion;
......@@ -2915,6 +2942,7 @@ struct device_attribute *mpt2sas_host_attrs[] = {
&dev_attr_host_trace_buffer_size,
&dev_attr_host_trace_buffer,
&dev_attr_host_trace_buffer_enable,
&dev_attr_reply_queue_count,
NULL,
};
......
......@@ -2162,6 +2162,7 @@ _scsih_tm_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
return 1;
if (ioc->tm_cmds.smid != smid)
return 1;
mpt2sas_base_flush_reply_queues(ioc);
ioc->tm_cmds.status |= MPT2_CMD_COMPLETE;
mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
if (mpi_reply) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment