Skip to content

Commit 093df73

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix Target mode handling with Multiqueue changes.
- Fix race condition between dpc_thread accessing Multiqueue resources and qla2x00_remove_one thread trying to free resource. - Fix out of order free for Multiqueue resources. Also, Multiqueue interrupts needs a workqueue. Interrupt needed to stop before the wq can be destroyed. Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 5601236 commit 093df73

File tree

4 files changed

+50
-28
lines changed

4 files changed

+50
-28
lines changed

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2734,7 +2734,8 @@ struct isp_operations {
27342734

27352735
#define QLA_MSIX_DEFAULT 0x00
27362736
#define QLA_MSIX_RSP_Q 0x01
2737-
#define QLA_MSIX_QPAIR_MULTIQ_RSP_Q 0x02
2737+
#define QLA_ATIO_VECTOR 0x02
2738+
#define QLA_MSIX_QPAIR_MULTIQ_RSP_Q 0x03
27382739

27392740
#define QLA_MIDX_DEFAULT 0
27402741
#define QLA_MIDX_RSP_Q 1

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6764,7 +6764,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
67646764
qpair->vp_idx = vp_idx;
67656765

67666766
for (i = 0; i < ha->msix_count; i++) {
6767-
msix = &ha->msix_entries[i + 2];
6767+
msix = &ha->msix_entries[i];
67686768
if (msix->in_use)
67696769
continue;
67706770
qpair->msix = msix;

drivers/scsi/qla2xxx/qla_isr.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,6 +3005,7 @@ struct qla_init_msix_entry {
30053005
static struct qla_init_msix_entry msix_entries[] = {
30063006
{ "qla2xxx (default)", qla24xx_msix_default },
30073007
{ "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
3008+
{ "qla2xxx (atio_q)", qla83xx_msix_atio_q },
30083009
{ "qla2xxx (qpair_multiq)", qla2xxx_msix_rsp_q },
30093010
};
30103011

@@ -3013,17 +3014,10 @@ static struct qla_init_msix_entry qla82xx_msix_entries[] = {
30133014
{ "qla2xxx (rsp_q)", qla82xx_msix_rsp_q },
30143015
};
30153016

3016-
static struct qla_init_msix_entry qla83xx_msix_entries[] = {
3017-
{ "qla2xxx (default)", qla24xx_msix_default },
3018-
{ "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
3019-
{ "qla2xxx (atio_q)", qla83xx_msix_atio_q },
3020-
};
3021-
30223017
static int
30233018
qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
30243019
{
30253020
#define MIN_MSIX_COUNT 2
3026-
#define ATIO_VECTOR 2
30273021
int i, ret;
30283022
struct qla_msix_entry *qentry;
30293023
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
@@ -3080,7 +3074,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
30803074
}
30813075

30823076
/* Enable MSI-X vectors for the base queue */
3083-
for (i = 0; i < 2; i++) {
3077+
for (i = 0; i < (QLA_MSIX_RSP_Q + 1); i++) {
30843078
qentry = &ha->msix_entries[i];
30853079
qentry->handle = rsp;
30863080
rsp->msix = qentry;
@@ -3097,6 +3091,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
30973091
if (ret)
30983092
goto msix_register_fail;
30993093
qentry->have_irq = 1;
3094+
qentry->in_use = 1;
31003095

31013096
/* Register for CPU affinity notification. */
31023097
irq_set_affinity_notifier(qentry->vector, &qentry->irq_notify);
@@ -3116,14 +3111,15 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
31163111
* queue.
31173112
*/
31183113
if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) {
3119-
qentry = &ha->msix_entries[ATIO_VECTOR];
3114+
qentry = &ha->msix_entries[QLA_ATIO_VECTOR];
31203115
rsp->msix = qentry;
31213116
qentry->handle = rsp;
31223117
scnprintf(qentry->name, sizeof(qentry->name),
3123-
qla83xx_msix_entries[ATIO_VECTOR].name);
3118+
msix_entries[QLA_ATIO_VECTOR].name);
3119+
qentry->in_use = 1;
31243120
ret = request_irq(qentry->vector,
3125-
qla83xx_msix_entries[ATIO_VECTOR].handler,
3126-
0, qla83xx_msix_entries[ATIO_VECTOR].name, rsp);
3121+
msix_entries[QLA_ATIO_VECTOR].handler,
3122+
0, msix_entries[QLA_ATIO_VECTOR].name, rsp);
31273123
qentry->have_irq = 1;
31283124
}
31293125

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -439,24 +439,41 @@ static void qla2x00_free_queues(struct qla_hw_data *ha)
439439
struct req_que *req;
440440
struct rsp_que *rsp;
441441
int cnt;
442+
unsigned long flags;
442443

444+
spin_lock_irqsave(&ha->hardware_lock, flags);
443445
for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
444446
if (!test_bit(cnt, ha->req_qid_map))
445447
continue;
446448

447449
req = ha->req_q_map[cnt];
450+
clear_bit(cnt, ha->req_qid_map);
451+
ha->req_q_map[cnt] = NULL;
452+
453+
spin_unlock_irqrestore(&ha->hardware_lock, flags);
448454
qla2x00_free_req_que(ha, req);
455+
spin_lock_irqsave(&ha->hardware_lock, flags);
449456
}
457+
spin_unlock_irqrestore(&ha->hardware_lock, flags);
458+
450459
kfree(ha->req_q_map);
451460
ha->req_q_map = NULL;
452461

462+
463+
spin_lock_irqsave(&ha->hardware_lock, flags);
453464
for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) {
454465
if (!test_bit(cnt, ha->rsp_qid_map))
455466
continue;
456467

457468
rsp = ha->rsp_q_map[cnt];
469+
clear_bit(cnt, ha->req_qid_map);
470+
ha->rsp_q_map[cnt] = NULL;
471+
spin_unlock_irqrestore(&ha->hardware_lock, flags);
458472
qla2x00_free_rsp_que(ha, rsp);
473+
spin_lock_irqsave(&ha->hardware_lock, flags);
459474
}
475+
spin_unlock_irqrestore(&ha->hardware_lock, flags);
476+
460477
kfree(ha->rsp_q_map);
461478
ha->rsp_q_map = NULL;
462479
}
@@ -1890,17 +1907,22 @@ qla83xx_iospace_config(struct qla_hw_data *ha)
18901907
pci_read_config_word(ha->pdev,
18911908
QLA_83XX_PCI_MSIX_CONTROL, &msix);
18921909
ha->msix_count = msix + 1;
1893-
/* Max queues are bounded by available msix vectors */
1894-
/* queue 0 uses two msix vectors */
1910+
/*
1911+
* By default, driver uses at least two msix vectors
1912+
* (default & rspq)
1913+
*/
18951914
if (ql2xmqsupport) {
18961915
/* MB interrupt uses 1 vector */
18971916
ha->max_req_queues = ha->msix_count - 1;
18981917
ha->max_rsp_queues = ha->max_req_queues;
1918+
1919+
/* ATIOQ needs 1 vector. That's 1 less QPair */
1920+
if (QLA_TGT_MODE_ENABLED())
1921+
ha->max_req_queues--;
1922+
18991923
/* Queue pairs is the max value minus
19001924
* the base queue pair */
19011925
ha->max_qpairs = ha->max_req_queues - 1;
1902-
ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc010,
1903-
"Max no of queues pairs: %d.\n", ha->max_qpairs);
19041926
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0190,
19051927
"Max no of queues pairs: %d.\n", ha->max_qpairs);
19061928
}
@@ -1912,6 +1934,8 @@ qla83xx_iospace_config(struct qla_hw_data *ha)
19121934

19131935
mqiobase_exit:
19141936
ha->msix_count = ha->max_rsp_queues + 1;
1937+
if (QLA_TGT_MODE_ENABLED())
1938+
ha->msix_count++;
19151939

19161940
qlt_83xx_iospace_config(ha);
19171941

@@ -2989,7 +3013,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
29893013
host->can_queue, base_vha->req,
29903014
base_vha->mgmt_svr_loop_id, host->sg_tablesize);
29913015

2992-
if (ha->mqenable) {
3016+
if (ha->mqenable && qla_ini_mode_enabled(base_vha)) {
29933017
ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1);
29943018
/* Create start of day qpairs for Block MQ */
29953019
if (shost_use_blk_mq(host)) {
@@ -3263,13 +3287,6 @@ qla2x00_delete_all_vps(struct qla_hw_data *ha, scsi_qla_host_t *base_vha)
32633287
static void
32643288
qla2x00_destroy_deferred_work(struct qla_hw_data *ha)
32653289
{
3266-
/* Flush the work queue and remove it */
3267-
if (ha->wq) {
3268-
flush_workqueue(ha->wq);
3269-
destroy_workqueue(ha->wq);
3270-
ha->wq = NULL;
3271-
}
3272-
32733290
/* Cancel all work and destroy DPC workqueues */
32743291
if (ha->dpc_lp_wq) {
32753292
cancel_work_sync(&ha->idc_aen);
@@ -3465,9 +3482,17 @@ qla2x00_free_device(scsi_qla_host_t *vha)
34653482
ha->isp_ops->disable_intrs(ha);
34663483
}
34673484

3485+
qla2x00_free_fcports(vha);
3486+
34683487
qla2x00_free_irqs(vha);
34693488

3470-
qla2x00_free_fcports(vha);
3489+
/* Flush the work queue and remove it */
3490+
if (ha->wq) {
3491+
flush_workqueue(ha->wq);
3492+
destroy_workqueue(ha->wq);
3493+
ha->wq = NULL;
3494+
}
3495+
34713496

34723497
qla2x00_mem_free(ha);
34733498

@@ -5187,8 +5212,8 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work)
51875212

51885213
base_vha->flags.init_done = 0;
51895214
qla25xx_delete_queues(base_vha);
5190-
qla2x00_free_irqs(base_vha);
51915215
qla2x00_free_fcports(base_vha);
5216+
qla2x00_free_irqs(base_vha);
51925217
qla2x00_mem_free(ha);
51935218
qla82xx_md_free(base_vha);
51945219
qla2x00_free_queues(ha);

0 commit comments

Comments
 (0)