Skip to content

Commit

Permalink
scsi: qla2xxx: Add multiple queue pair functionality.
Browse files Browse the repository at this point in the history
Replaced existing multiple queue functionality with framework
that allows for the creation of pairs of request and response queues,
either at start of day or dynamically.

Queue pair creation depend on module parameter "ql2xmqsupport",
which need to be enabled to create queue pair.

Signed-off-by: Sawan Chandak <sawan.chandak@cavium.com>
Signed-off-by: Michael Hernandez <michael.hernandez@cavium.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
  • Loading branch information
Michael Hernandez authored and martinkpetersen committed Dec 14, 2016
1 parent 4fa1834 commit d745952
Show file tree
Hide file tree
Showing 11 changed files with 1,114 additions and 335 deletions.
36 changes: 15 additions & 21 deletions drivers/scsi/qla2xxx/qla_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1988,9 +1988,9 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
scsi_qla_host_t *vha = NULL;
struct qla_hw_data *ha = base_vha->hw;
uint16_t options = 0;
int cnt;
struct req_que *req = ha->req_q_map[0];
struct qla_qpair *qpair;

ret = qla24xx_vport_create_req_sanity_check(fc_vport);
if (ret) {
Expand Down Expand Up @@ -2075,15 +2075,9 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
qlt_vport_create(vha, ha);
qla24xx_vport_disable(fc_vport, disable);

if (ha->flags.cpu_affinity_enabled) {
req = ha->req_q_map[1];
ql_dbg(ql_dbg_multiq, vha, 0xc000,
"Request queue %p attached with "
"VP[%d], cpu affinity =%d\n",
req, vha->vp_idx, ha->flags.cpu_affinity_enabled);
goto vport_queue;
} else if (ql2xmaxqueues == 1 || !ha->npiv_info)
if (!ql2xmqsupport || !ha->npiv_info)
goto vport_queue;

/* Create a request queue in QoS mode for the vport */
for (cnt = 0; cnt < ha->nvram_npiv_size; cnt++) {
if (memcmp(ha->npiv_info[cnt].port_name, vha->port_name, 8) == 0
Expand All @@ -2095,20 +2089,20 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable)
}

if (qos) {
ret = qla25xx_create_req_que(ha, options, vha->vp_idx, 0, 0,
qos);
if (!ret)
qpair = qla2xxx_create_qpair(vha, qos, vha->vp_idx);
if (!qpair)
ql_log(ql_log_warn, vha, 0x7084,
"Can't create request queue for VP[%d]\n",
"Can't create qpair for VP[%d]\n",
vha->vp_idx);
else {
ql_dbg(ql_dbg_multiq, vha, 0xc001,
"Request Que:%d Q0s: %d) created for VP[%d]\n",
ret, qos, vha->vp_idx);
"Queue pair: %d Qos: %d) created for VP[%d]\n",
qpair->id, qos, vha->vp_idx);
ql_dbg(ql_dbg_user, vha, 0x7085,
"Request Que:%d Q0s: %d) created for VP[%d]\n",
ret, qos, vha->vp_idx);
req = ha->req_q_map[ret];
"Queue Pair: %d Qos: %d) created for VP[%d]\n",
qpair->id, qos, vha->vp_idx);
req = qpair->req;
vha->qpair = qpair;
}
}

Expand Down Expand Up @@ -2162,10 +2156,10 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
clear_bit(vha->vp_idx, ha->vp_idx_map);
mutex_unlock(&ha->vport_lock);

if (vha->req->id && !ha->flags.cpu_affinity_enabled) {
if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS)
if (vha->qpair->vp_idx == vha->vp_idx) {
if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS)
ql_log(ql_log_warn, vha, 0x7087,
"Queue delete failed.\n");
"Queue Pair delete failed.\n");
}

ql_log(ql_log_info, vha, 0x7088, "VP[%d] deleted.\n", id);
Expand Down
4 changes: 2 additions & 2 deletions drivers/scsi/qla2xxx/qla_dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* ----------------------------------------------------------------------
* | Level | Last Value Used | Holes |
* ----------------------------------------------------------------------
* | Module Init and Probe | 0x0191 | 0x0146 |
* | Module Init and Probe | 0x0193 | 0x0146 |
* | | | 0x015b-0x0160 |
* | | | 0x016e |
* | Mailbox commands | 0x1199 | 0x1193 |
Expand Down Expand Up @@ -58,7 +58,7 @@
* | | | 0xb13a,0xb142 |
* | | | 0xb13c-0xb140 |
* | | | 0xb149 |
* | MultiQ | 0xc00c | |
* | MultiQ | 0xc010 | |
* | Misc | 0xd301 | 0xd031-0xd0ff |
* | | | 0xd101-0xd1fe |
* | | | 0xd214-0xd2fe |
Expand Down
105 changes: 90 additions & 15 deletions drivers/scsi/qla2xxx/qla_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ typedef struct srb {
uint16_t type;
char *name;
int iocbs;
struct qla_qpair *qpair;
union {
struct srb_iocb iocb_cmd;
struct bsg_job *bsg_job;
Expand Down Expand Up @@ -2719,6 +2720,7 @@ struct isp_operations {

int (*get_flash_version) (struct scsi_qla_host *, void *);
int (*start_scsi) (srb_t *);
int (*start_scsi_mq) (srb_t *);
int (*abort_isp) (struct scsi_qla_host *);
int (*iospace_config)(struct qla_hw_data*);
int (*initialize_adapter)(struct scsi_qla_host *);
Expand All @@ -2730,8 +2732,9 @@ struct isp_operations {
#define QLA_MSIX_FW_MODE(m) (((m) & (BIT_7|BIT_8|BIT_9)) >> 7)
#define QLA_MSIX_FW_MODE_1(m) (QLA_MSIX_FW_MODE(m) == 1)

#define QLA_MSIX_DEFAULT 0x00
#define QLA_MSIX_RSP_Q 0x01
#define QLA_MSIX_DEFAULT 0x00
#define QLA_MSIX_RSP_Q 0x01
#define QLA_MSIX_QPAIR_MULTIQ_RSP_Q 0x02

#define QLA_MIDX_DEFAULT 0
#define QLA_MIDX_RSP_Q 1
Expand All @@ -2745,8 +2748,10 @@ struct scsi_qla_host;

struct qla_msix_entry {
int have_irq;
int in_use;
uint32_t vector;
uint16_t entry;
char name[30];
void *handle;
struct irq_affinity_notify irq_notify;
int cpuid;
Expand Down Expand Up @@ -2872,7 +2877,6 @@ struct rsp_que {
struct qla_msix_entry *msix;
struct req_que *req;
srb_t *status_srb; /* status continuation entry */
struct work_struct q_work;

dma_addr_t dma_fx00;
response_t *ring_fx00;
Expand Down Expand Up @@ -2909,6 +2913,37 @@ struct req_que {
uint8_t req_pkt[REQUEST_ENTRY_SIZE];
};

/*Queue pair data structure */
struct qla_qpair {
spinlock_t qp_lock;
atomic_t ref_count;
/* distill these fields down to 'online=0/1'
* ha->flags.eeh_busy
* ha->flags.pci_channel_io_perm_failure
* base_vha->loop_state
*/
uint32_t online:1;
/* move vha->flags.difdix_supported here */
uint32_t difdix_supported:1;
uint32_t delete_in_progress:1;

uint16_t id; /* qp number used with FW */
uint16_t num_active_cmd; /* cmds down at firmware */
cpumask_t cpu_mask; /* CPU mask for cpu affinity operation */
uint16_t vp_idx; /* vport ID */

mempool_t *srb_mempool;

/* to do: New driver: move queues to here instead of pointers */
struct req_que *req;
struct rsp_que *rsp;
struct atio_que *atio;
struct qla_msix_entry *msix; /* point to &ha->msix_entries[x] */
struct qla_hw_data *hw;
struct work_struct q_work;
struct list_head qp_list_elem; /* vha->qp_list */
};

/* Place holder for FW buffer parameters */
struct qlfc_fw {
void *fw_buf;
Expand Down Expand Up @@ -3004,7 +3039,6 @@ struct qla_hw_data {
uint32_t chip_reset_done :1;
uint32_t running_gold_fw :1;
uint32_t eeh_busy :1;
uint32_t cpu_affinity_enabled :1;
uint32_t disable_msix_handshake :1;
uint32_t fcp_prio_enabled :1;
uint32_t isp82xx_fw_hung:1;
Expand Down Expand Up @@ -3061,10 +3095,15 @@ struct qla_hw_data {
uint8_t mqenable;
struct req_que **req_q_map;
struct rsp_que **rsp_q_map;
struct qla_qpair **queue_pair_map;
unsigned long req_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
unsigned long rsp_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
unsigned long qpair_qid_map[(QLA_MAX_QUEUES / 8)
/ sizeof(unsigned long)];
uint8_t max_req_queues;
uint8_t max_rsp_queues;
uint8_t max_qpairs;
struct qla_qpair *base_qpair;
struct qla_npiv_entry *npiv_info;
uint16_t nvram_npiv_size;

Expand Down Expand Up @@ -3328,6 +3367,7 @@ struct qla_hw_data {

struct mutex vport_lock; /* Virtual port synchronization */
spinlock_t vport_slock; /* order is hardware_lock, then vport_slock */
struct mutex mq_lock; /* multi-queue synchronization */
struct completion mbx_cmd_comp; /* Serialize mbx access */
struct completion mbx_intr_comp; /* Used for completion notification */
struct completion dcbx_comp; /* For set port config notification */
Expand Down Expand Up @@ -3608,6 +3648,7 @@ typedef struct scsi_qla_host {

uint32_t fw_tgt_reported:1;
uint32_t bbcr_enable:1;
uint32_t qpairs_available:1;
} flags;

atomic_t loop_state;
Expand Down Expand Up @@ -3646,6 +3687,7 @@ typedef struct scsi_qla_host {
#define FX00_TARGET_SCAN 24
#define FX00_CRITEMP_RECOVERY 25
#define FX00_HOST_INFO_RESEND 26
#define QPAIR_ONLINE_CHECK_NEEDED 27

unsigned long pci_flags;
#define PFLG_DISCONNECTED 0 /* PCI device removed */
Expand Down Expand Up @@ -3704,10 +3746,13 @@ typedef struct scsi_qla_host {
/* List of pending PLOGI acks, protected by hw lock */
struct list_head plogi_ack_list;

struct list_head qp_list;

uint32_t vp_abort_cnt;

struct fc_vport *fc_vport; /* holds fc_vport * for each vport */
uint16_t vp_idx; /* vport ID */
struct qla_qpair *qpair; /* base qpair */

unsigned long vp_flags;
#define VP_IDX_ACQUIRED 0 /* bit no 0 */
Expand Down Expand Up @@ -3763,6 +3808,23 @@ struct qla_tgt_vp_map {
scsi_qla_host_t *vha;
};

struct qla2_sgx {
dma_addr_t dma_addr; /* OUT */
uint32_t dma_len; /* OUT */

uint32_t tot_bytes; /* IN */
struct scatterlist *cur_sg; /* IN */

/* for book keeping, bzero on initial invocation */
uint32_t bytes_consumed;
uint32_t num_bytes;
uint32_t tot_partial;

/* for debugging */
uint32_t num_sg;
srb_t *sp;
};

/*
* Macros to help code, maintain, etc.
*/
Expand All @@ -3775,21 +3837,34 @@ struct qla_tgt_vp_map {
(test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \
test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags))

#define QLA_VHA_MARK_BUSY(__vha, __bail) do { \
atomic_inc(&__vha->vref_count); \
mb(); \
if (__vha->flags.delete_progress) { \
atomic_dec(&__vha->vref_count); \
__bail = 1; \
} else { \
__bail = 0; \
} \
#define QLA_VHA_MARK_BUSY(__vha, __bail) do { \
atomic_inc(&__vha->vref_count); \
mb(); \
if (__vha->flags.delete_progress) { \
atomic_dec(&__vha->vref_count); \
__bail = 1; \
} else { \
__bail = 0; \
} \
} while (0)

#define QLA_VHA_MARK_NOT_BUSY(__vha) do { \
atomic_dec(&__vha->vref_count); \
#define QLA_VHA_MARK_NOT_BUSY(__vha) \
atomic_dec(&__vha->vref_count); \

#define QLA_QPAIR_MARK_BUSY(__qpair, __bail) do { \
atomic_inc(&__qpair->ref_count); \
mb(); \
if (__qpair->delete_in_progress) { \
atomic_dec(&__qpair->ref_count); \
__bail = 1; \
} else { \
__bail = 0; \
} \
} while (0)

#define QLA_QPAIR_MARK_NOT_BUSY(__qpair) \
atomic_dec(&__qpair->ref_count); \

/*
* qla2x00 local function return status codes
*/
Expand Down
Loading

0 comments on commit d745952

Please sign in to comment.