[SCSI] qla2xxx: Determine the number of outstanding commands based on available resources.
Base the number of outstanding requests the driver will keep track of on the available resources instead of being hard-coded. Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Родитель
6d1f6621fa
Коммит
8d93f55022
|
@ -1950,7 +1950,7 @@ qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
|
|||
if (!req)
|
||||
continue;
|
||||
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
|
||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
if (((sp->type == SRB_CT_CMD) ||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* ----------------------------------------------------------------------
|
||||
* | Level | Last Value Used | Holes |
|
||||
* ----------------------------------------------------------------------
|
||||
* | Module Init and Probe | 0x0125 | 0x4b,0xba,0xfa |
|
||||
* | Module Init and Probe | 0x0126 | 0x4b,0xba,0xfa |
|
||||
* | Mailbox commands | 0x114f | 0x111a-0x111b |
|
||||
* | | | 0x112c-0x112e |
|
||||
* | | | 0x113a |
|
||||
|
|
|
@ -253,8 +253,8 @@
|
|||
#define LOOP_DOWN_TIME 255 /* 240 */
|
||||
#define LOOP_DOWN_RESET (LOOP_DOWN_TIME - 30)
|
||||
|
||||
/* Maximum outstanding commands in ISP queues (1-65535) */
|
||||
#define MAX_OUTSTANDING_COMMANDS 1024
|
||||
#define DEFAULT_OUTSTANDING_COMMANDS 1024
|
||||
#define MIN_OUTSTANDING_COMMANDS 128
|
||||
|
||||
/* ISP request and response entry counts (37-65535) */
|
||||
#define REQUEST_ENTRY_CNT_2100 128 /* Number of request entries. */
|
||||
|
@ -2533,8 +2533,9 @@ struct req_que {
|
|||
uint16_t qos;
|
||||
uint16_t vp_idx;
|
||||
struct rsp_que *rsp;
|
||||
srb_t *outstanding_cmds[MAX_OUTSTANDING_COMMANDS];
|
||||
srb_t **outstanding_cmds;
|
||||
uint32_t current_outstanding_cmd;
|
||||
uint16_t num_outstanding_cmds;
|
||||
int max_q_depth;
|
||||
};
|
||||
|
||||
|
@ -2561,7 +2562,7 @@ struct qlt_hw_data {
|
|||
void *target_lport_ptr;
|
||||
struct qla_tgt_func_tmpl *tgt_ops;
|
||||
struct qla_tgt *qla_tgt;
|
||||
struct qla_tgt_cmd *cmds[MAX_OUTSTANDING_COMMANDS];
|
||||
struct qla_tgt_cmd *cmds[DEFAULT_OUTSTANDING_COMMANDS];
|
||||
uint16_t current_handle;
|
||||
|
||||
struct qla_tgt_vp_map *tgt_vp_map;
|
||||
|
@ -2887,6 +2888,7 @@ struct qla_hw_data {
|
|||
#define RISC_START_ADDRESS_2300 0x800
|
||||
#define RISC_START_ADDRESS_2400 0x100000
|
||||
uint16_t fw_xcb_count;
|
||||
uint16_t fw_iocb_count;
|
||||
|
||||
uint16_t fw_options[16]; /* slots: 1,2,3,10,11 */
|
||||
uint8_t fw_seriallink_options[4];
|
||||
|
@ -3248,8 +3250,6 @@ struct qla_tgt_vp_map {
|
|||
|
||||
#define NVRAM_DELAY() udelay(10)
|
||||
|
||||
#define INVALID_HANDLE (MAX_OUTSTANDING_COMMANDS+1)
|
||||
|
||||
/*
|
||||
* Flash support definitions
|
||||
*/
|
||||
|
|
|
@ -84,6 +84,9 @@ extern int qla83xx_nic_core_reset(scsi_qla_host_t *);
|
|||
extern void qla83xx_reset_ownership(scsi_qla_host_t *);
|
||||
extern int qla2xxx_mctp_dump(scsi_qla_host_t *);
|
||||
|
||||
extern int
|
||||
qla2x00_alloc_outstanding_cmds(struct qla_hw_data *, struct req_que *);
|
||||
|
||||
/*
|
||||
* Global Data in qla_os.c source file.
|
||||
*/
|
||||
|
|
|
@ -1559,6 +1559,47 @@ done:
|
|||
return rval;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_alloc_outstanding_cmds(struct qla_hw_data *ha, struct req_que *req)
|
||||
{
|
||||
/* Don't try to reallocate the array */
|
||||
if (req->outstanding_cmds)
|
||||
return QLA_SUCCESS;
|
||||
|
||||
if (!IS_FWI2_CAPABLE(ha) || (ha->mqiobase &&
|
||||
(ql2xmultique_tag || ql2xmaxqueues > 1)))
|
||||
req->num_outstanding_cmds = DEFAULT_OUTSTANDING_COMMANDS;
|
||||
else {
|
||||
if (ha->fw_xcb_count <= ha->fw_iocb_count)
|
||||
req->num_outstanding_cmds = ha->fw_xcb_count;
|
||||
else
|
||||
req->num_outstanding_cmds = ha->fw_iocb_count;
|
||||
}
|
||||
|
||||
req->outstanding_cmds = kzalloc(sizeof(srb_t *) *
|
||||
req->num_outstanding_cmds, GFP_KERNEL);
|
||||
|
||||
if (!req->outstanding_cmds) {
|
||||
/*
|
||||
* Try to allocate a minimal size just so we can get through
|
||||
* initialization.
|
||||
*/
|
||||
req->num_outstanding_cmds = MIN_OUTSTANDING_COMMANDS;
|
||||
req->outstanding_cmds = kzalloc(sizeof(srb_t *) *
|
||||
req->num_outstanding_cmds, GFP_KERNEL);
|
||||
|
||||
if (!req->outstanding_cmds) {
|
||||
ql_log(ql_log_fatal, NULL, 0x0126,
|
||||
"Failed to allocate memory for "
|
||||
"outstanding_cmds for req_que %p.\n", req);
|
||||
req->num_outstanding_cmds = 0;
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
return QLA_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla2x00_setup_chip() - Load and start RISC firmware.
|
||||
* @ha: HA context
|
||||
|
@ -1628,9 +1669,18 @@ enable_82xx_npiv:
|
|||
MIN_MULTI_ID_FABRIC - 1;
|
||||
}
|
||||
qla2x00_get_resource_cnts(vha, NULL,
|
||||
&ha->fw_xcb_count, NULL, NULL,
|
||||
&ha->fw_xcb_count, NULL, &ha->fw_iocb_count,
|
||||
&ha->max_npiv_vports, NULL);
|
||||
|
||||
/*
|
||||
* Allocate the array of outstanding commands
|
||||
* now that we know the firmware resources.
|
||||
*/
|
||||
rval = qla2x00_alloc_outstanding_cmds(ha,
|
||||
vha->req);
|
||||
if (rval != QLA_SUCCESS)
|
||||
goto failed;
|
||||
|
||||
if (!fw_major_version && ql2xallocfwdump
|
||||
&& !IS_QLA82XX(ha))
|
||||
qla2x00_alloc_fw_dump(vha);
|
||||
|
@ -1948,7 +1998,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
|
|||
req = ha->req_q_map[que];
|
||||
if (!req)
|
||||
continue;
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
|
||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++)
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
|
||||
req->current_outstanding_cmd = 1;
|
||||
|
|
|
@ -349,14 +349,14 @@ qla2x00_start_scsi(srb_t *sp)
|
|||
|
||||
/* Check for room in outstanding command list. */
|
||||
handle = req->current_outstanding_cmd;
|
||||
for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
|
||||
for (index = 1; index < req->num_outstanding_cmds; index++) {
|
||||
handle++;
|
||||
if (handle == MAX_OUTSTANDING_COMMANDS)
|
||||
if (handle == req->num_outstanding_cmds)
|
||||
handle = 1;
|
||||
if (!req->outstanding_cmds[handle])
|
||||
break;
|
||||
}
|
||||
if (index == MAX_OUTSTANDING_COMMANDS)
|
||||
if (index == req->num_outstanding_cmds)
|
||||
goto queuing_error;
|
||||
|
||||
/* Map the sg table so we have an accurate count of sg entries needed */
|
||||
|
@ -1467,16 +1467,15 @@ qla24xx_start_scsi(srb_t *sp)
|
|||
|
||||
/* Check for room in outstanding command list. */
|
||||
handle = req->current_outstanding_cmd;
|
||||
for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
|
||||
for (index = 1; index < req->num_outstanding_cmds; index++) {
|
||||
handle++;
|
||||
if (handle == MAX_OUTSTANDING_COMMANDS)
|
||||
if (handle == req->num_outstanding_cmds)
|
||||
handle = 1;
|
||||
if (!req->outstanding_cmds[handle])
|
||||
break;
|
||||
}
|
||||
if (index == MAX_OUTSTANDING_COMMANDS) {
|
||||
if (index == req->num_outstanding_cmds)
|
||||
goto queuing_error;
|
||||
}
|
||||
|
||||
/* Map the sg table so we have an accurate count of sg entries needed */
|
||||
if (scsi_sg_count(cmd)) {
|
||||
|
@ -1641,15 +1640,15 @@ qla24xx_dif_start_scsi(srb_t *sp)
|
|||
|
||||
/* Check for room in outstanding command list. */
|
||||
handle = req->current_outstanding_cmd;
|
||||
for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
|
||||
for (index = 1; index < req->num_outstanding_cmds; index++) {
|
||||
handle++;
|
||||
if (handle == MAX_OUTSTANDING_COMMANDS)
|
||||
if (handle == req->num_outstanding_cmds)
|
||||
handle = 1;
|
||||
if (!req->outstanding_cmds[handle])
|
||||
break;
|
||||
}
|
||||
|
||||
if (index == MAX_OUTSTANDING_COMMANDS)
|
||||
if (index == req->num_outstanding_cmds)
|
||||
goto queuing_error;
|
||||
|
||||
/* Compute number of required data segments */
|
||||
|
@ -1822,14 +1821,14 @@ qla2x00_alloc_iocbs(scsi_qla_host_t *vha, srb_t *sp)
|
|||
|
||||
/* Check for room in outstanding command list. */
|
||||
handle = req->current_outstanding_cmd;
|
||||
for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
|
||||
for (index = 1; req->num_outstanding_cmds; index++) {
|
||||
handle++;
|
||||
if (handle == MAX_OUTSTANDING_COMMANDS)
|
||||
if (handle == req->num_outstanding_cmds)
|
||||
handle = 1;
|
||||
if (!req->outstanding_cmds[handle])
|
||||
break;
|
||||
}
|
||||
if (index == MAX_OUTSTANDING_COMMANDS) {
|
||||
if (index == req->num_outstanding_cmds) {
|
||||
ql_log(ql_log_warn, vha, 0x700b,
|
||||
"No room on outstanding cmd array.\n");
|
||||
goto queuing_error;
|
||||
|
@ -2263,14 +2262,14 @@ qla82xx_start_scsi(srb_t *sp)
|
|||
|
||||
/* Check for room in outstanding command list. */
|
||||
handle = req->current_outstanding_cmd;
|
||||
for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
|
||||
for (index = 1; index < req->num_outstanding_cmds; index++) {
|
||||
handle++;
|
||||
if (handle == MAX_OUTSTANDING_COMMANDS)
|
||||
if (handle == req->num_outstanding_cmds)
|
||||
handle = 1;
|
||||
if (!req->outstanding_cmds[handle])
|
||||
break;
|
||||
}
|
||||
if (index == MAX_OUTSTANDING_COMMANDS)
|
||||
if (index == req->num_outstanding_cmds)
|
||||
goto queuing_error;
|
||||
|
||||
/* Map the sg table so we have an accurate count of sg entries needed */
|
||||
|
@ -2767,15 +2766,15 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
|
|||
|
||||
/* Check for room in outstanding command list. */
|
||||
handle = req->current_outstanding_cmd;
|
||||
for (index = 1; index < MAX_OUTSTANDING_COMMANDS; index++) {
|
||||
for (index = 1; index < req->num_outstanding_cmds; index++) {
|
||||
handle++;
|
||||
if (handle == MAX_OUTSTANDING_COMMANDS)
|
||||
if (handle == req->num_outstanding_cmds)
|
||||
handle = 1;
|
||||
if (!req->outstanding_cmds[handle])
|
||||
break;
|
||||
}
|
||||
|
||||
if (index == MAX_OUTSTANDING_COMMANDS) {
|
||||
if (index == req->num_outstanding_cmds) {
|
||||
rval = EXT_STATUS_BUSY;
|
||||
goto queuing_error;
|
||||
}
|
||||
|
|
|
@ -1029,7 +1029,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
|
|||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
/* Validate handle. */
|
||||
if (index >= MAX_OUTSTANDING_COMMANDS) {
|
||||
if (index >= req->num_outstanding_cmds) {
|
||||
ql_log(ql_log_warn, vha, 0x3014,
|
||||
"Invalid SCSI command index (%x).\n", index);
|
||||
|
||||
|
@ -1067,7 +1067,7 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
|
|||
uint16_t index;
|
||||
|
||||
index = LSW(pkt->handle);
|
||||
if (index >= MAX_OUTSTANDING_COMMANDS) {
|
||||
if (index >= req->num_outstanding_cmds) {
|
||||
ql_log(ql_log_warn, vha, 0x5031,
|
||||
"Invalid command index (%x).\n", index);
|
||||
if (IS_QLA82XX(ha))
|
||||
|
@ -1740,7 +1740,7 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
|
|||
sts24 = (struct sts_entry_24xx *) pkt;
|
||||
|
||||
/* Validate handle. */
|
||||
if (index >= MAX_OUTSTANDING_COMMANDS) {
|
||||
if (index >= req->num_outstanding_cmds) {
|
||||
ql_log(ql_log_warn, vha, 0x70af,
|
||||
"Invalid SCSI completion handle 0x%x.\n", index);
|
||||
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
||||
|
@ -1910,9 +1910,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
|
|||
req = ha->req_q_map[que];
|
||||
|
||||
/* Validate handle. */
|
||||
if (handle < MAX_OUTSTANDING_COMMANDS) {
|
||||
if (handle < req->num_outstanding_cmds)
|
||||
sp = req->outstanding_cmds[handle];
|
||||
} else
|
||||
else
|
||||
sp = NULL;
|
||||
|
||||
if (sp == NULL) {
|
||||
|
|
|
@ -900,13 +900,13 @@ qla2x00_abort_command(srb_t *sp)
|
|||
"Entered %s.\n", __func__);
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
|
||||
for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
|
||||
if (req->outstanding_cmds[handle] == sp)
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
if (handle == MAX_OUTSTANDING_COMMANDS) {
|
||||
if (handle == req->num_outstanding_cmds) {
|
||||
/* command not found */
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
@ -2535,12 +2535,12 @@ qla24xx_abort_command(srb_t *sp)
|
|||
"Entered %s.\n", __func__);
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
|
||||
for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
|
||||
if (req->outstanding_cmds[handle] == sp)
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
if (handle == MAX_OUTSTANDING_COMMANDS) {
|
||||
if (handle == req->num_outstanding_cmds) {
|
||||
/* Command not found. */
|
||||
return QLA_FUNCTION_FAILED;
|
||||
}
|
||||
|
|
|
@ -523,6 +523,7 @@ qla25xx_free_req_que(struct scsi_qla_host *vha, struct req_que *req)
|
|||
clear_bit(que_id, ha->req_qid_map);
|
||||
mutex_unlock(&ha->vport_lock);
|
||||
}
|
||||
kfree(req->outstanding_cmds);
|
||||
kfree(req);
|
||||
req = NULL;
|
||||
}
|
||||
|
@ -649,6 +650,10 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
|
|||
goto que_failed;
|
||||
}
|
||||
|
||||
ret = qla2x00_alloc_outstanding_cmds(ha, req);
|
||||
if (ret != QLA_SUCCESS)
|
||||
goto que_failed;
|
||||
|
||||
mutex_lock(&ha->vport_lock);
|
||||
que_id = find_first_zero_bit(ha->req_qid_map, ha->max_req_queues);
|
||||
if (que_id >= ha->max_req_queues) {
|
||||
|
@ -685,7 +690,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
|
|||
"options=0x%x.\n", req->options);
|
||||
ql_dbg(ql_dbg_init, base_vha, 0x00dd,
|
||||
"options=0x%x.\n", req->options);
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
|
||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++)
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
req->current_outstanding_cmd = 1;
|
||||
|
||||
|
|
|
@ -3629,7 +3629,7 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
|
|||
req = ha->req_q_map[que];
|
||||
if (!req)
|
||||
continue;
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
|
||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
if (!sp->u.scmd.ctx ||
|
||||
|
|
|
@ -360,6 +360,9 @@ static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req)
|
|||
(req->length + 1) * sizeof(request_t),
|
||||
req->ring, req->dma);
|
||||
|
||||
if (req)
|
||||
kfree(req->outstanding_cmds);
|
||||
|
||||
kfree(req);
|
||||
req = NULL;
|
||||
}
|
||||
|
@ -1010,7 +1013,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
|
|||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
req = vha->req;
|
||||
for (cnt = 1; status == QLA_SUCCESS &&
|
||||
cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
|
||||
cnt < req->num_outstanding_cmds; cnt++) {
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (!sp)
|
||||
continue;
|
||||
|
@ -1337,7 +1340,9 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
|
|||
req = ha->req_q_map[que];
|
||||
if (!req)
|
||||
continue;
|
||||
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
|
||||
if (!req->outstanding_cmds)
|
||||
continue;
|
||||
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
|
||||
sp = req->outstanding_cmds[cnt];
|
||||
if (sp) {
|
||||
req->outstanding_cmds[cnt] = NULL;
|
||||
|
@ -4733,7 +4738,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
|
|||
cpu_flags);
|
||||
req = ha->req_q_map[0];
|
||||
for (index = 1;
|
||||
index < MAX_OUTSTANDING_COMMANDS;
|
||||
index < req->num_outstanding_cmds;
|
||||
index++) {
|
||||
fc_port_t *sfcp;
|
||||
|
||||
|
|
|
@ -1570,7 +1570,7 @@ static inline uint32_t qlt_make_handle(struct scsi_qla_host *vha)
|
|||
/* always increment cmd handle */
|
||||
do {
|
||||
++h;
|
||||
if (h > MAX_OUTSTANDING_COMMANDS)
|
||||
if (h > DEFAULT_OUTSTANDING_COMMANDS)
|
||||
h = 1; /* 0 is QLA_TGT_NULL_HANDLE */
|
||||
if (h == ha->tgt.current_handle) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe04e,
|
||||
|
@ -2441,7 +2441,7 @@ static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha,
|
|||
return NULL;
|
||||
}
|
||||
/* handle-1 is actually used */
|
||||
if (unlikely(handle > MAX_OUTSTANDING_COMMANDS)) {
|
||||
if (unlikely(handle > DEFAULT_OUTSTANDING_COMMANDS)) {
|
||||
ql_dbg(ql_dbg_tgt, vha, 0xe052,
|
||||
"qla_target(%d): Wrong handle %x received\n",
|
||||
vha->vp_idx, handle);
|
||||
|
|
|
@ -60,8 +60,9 @@
|
|||
* multi-complete should come to the tgt driver or be handled there by qla2xxx
|
||||
*/
|
||||
#define CTIO_COMPLETION_HANDLE_MARK BIT_29
|
||||
#if (CTIO_COMPLETION_HANDLE_MARK <= MAX_OUTSTANDING_COMMANDS)
|
||||
#error "CTIO_COMPLETION_HANDLE_MARK not larger than MAX_OUTSTANDING_COMMANDS"
|
||||
#if (CTIO_COMPLETION_HANDLE_MARK <= DEFAULT_OUTSTANDING_COMMANDS)
|
||||
#error "CTIO_COMPLETION_HANDLE_MARK not larger than "
|
||||
"DEFAULT_OUTSTANDING_COMMANDS"
|
||||
#endif
|
||||
#define HANDLE_IS_CTIO_COMP(h) (h & CTIO_COMPLETION_HANDLE_MARK)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче