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

Commit b95b9452 authored by Sawan Chandak's avatar Sawan Chandak Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: Fix crash due to mismatch mumber of Q-pair creation for Multi queue



when driver is loaded with Multi Queue enabled, it was noticed that
there was one less queue pair created.

Following message would indicate this:

"No resources to create additional q pair."

The result of one less queue pair means that system can crash, if the
block mq layer thinks there is an extra hardware queue available, and
the driver will use a NULL ptr qpair in that instance.

Following stack trace is seen in one of the crash:

irq_create_affinity_masks+0x98/0x530
irq_create_affinity_masks+0x98/0x530
__pci_enable_msix+0x321/0x4e0
mutex_lock+0x12/0x40
pci_alloc_irq_vectors_affinity+0xb5/0x140
qla24xx_enable_msix+0x79/0x530 [qla2xxx]
qla2x00_request_irqs+0x61/0x2d0 [qla2xxx]
qla2x00_probe_one+0xc73/0x2390 [qla2xxx]
ida_simple_get+0x98/0x100
kernfs_next_descendant_post+0x40/0x50
local_pci_probe+0x45/0xa0
pci_device_probe+0xfc/0x140
driver_probe_device+0x2c5/0x470
__driver_attach+0xdd/0xe0
driver_probe_device+0x470/0x470
bus_for_each_dev+0x6c/0xc0
driver_attach+0x1e/0x20
bus_add_driver+0x45/0x270
driver_register+0x60/0xe0
__pci_register_driver+0x4c/0x50
qla2x00_module_init+0x1ce/0x21e [qla2xxx]

Cc: <stable@vger.kernel.org> # v4.10+
Signed-off-by: default avatarSawan Chandak <sawan.chandak@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 0ea88662
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3425,6 +3425,7 @@ struct qla_hw_data {
	uint8_t 	max_req_queues;
	uint8_t 	max_rsp_queues;
	uint8_t		max_qpairs;
	uint8_t		num_qpairs;
	struct qla_qpair *base_qpair;
	struct qla_npiv_entry *npiv_info;
	uint16_t	nvram_npiv_size;
+4 −1
Original line number Diff line number Diff line
@@ -7543,12 +7543,13 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
		/* Assign available que pair id */
		mutex_lock(&ha->mq_lock);
		qpair_id = find_first_zero_bit(ha->qpair_qid_map, ha->max_qpairs);
		if (qpair_id >= ha->max_qpairs) {
		if (ha->num_qpairs >= ha->max_qpairs) {
			mutex_unlock(&ha->mq_lock);
			ql_log(ql_log_warn, vha, 0x0183,
			    "No resources to create additional q pair.\n");
			goto fail_qid_map;
		}
		ha->num_qpairs++;
		set_bit(qpair_id, ha->qpair_qid_map);
		ha->queue_pair_map[qpair_id] = qpair;
		qpair->id = qpair_id;
@@ -7635,6 +7636,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v
fail_msix:
	ha->queue_pair_map[qpair_id] = NULL;
	clear_bit(qpair_id, ha->qpair_qid_map);
	ha->num_qpairs--;
	mutex_unlock(&ha->mq_lock);
fail_qid_map:
	kfree(qpair);
@@ -7660,6 +7662,7 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
	mutex_lock(&ha->mq_lock);
	ha->queue_pair_map[qpair->id] = NULL;
	clear_bit(qpair->id, ha->qpair_qid_map);
	ha->num_qpairs--;
	list_del(&qpair->qp_list_elem);
	if (list_empty(&vha->qp_list))
		vha->flags.qpairs_available = 0;