[PATCH] be2iscsi: switch to pci_alloc_irq_vectors

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



And get automatic MSI-X affinity for free.

Signed-off-by: Christoph Hellwig <hch@xxxxxx>
---
 drivers/scsi/be2iscsi/be_main.c | 127 +++++++++++++---------------------------
 drivers/scsi/be2iscsi/be_main.h |   2 -
 2 files changed, 42 insertions(+), 87 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 6372613..03faca8 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -801,12 +801,12 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 	struct pci_dev *pcidev = phba->pcidev;
 	struct hwi_controller *phwi_ctrlr;
 	struct hwi_context_memory *phwi_context;
-	int ret, msix_vec, i, j;
+	int ret, i, j;
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
 
-	if (phba->msix_enabled) {
+	if (pcidev->msix_enabled) {
 		for (i = 0; i < phba->num_cpus; i++) {
 			phba->msi_name[i] = kzalloc(BEISCSI_MSI_NAME,
 						    GFP_KERNEL);
@@ -817,9 +817,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 
 			sprintf(phba->msi_name[i], "beiscsi_%02x_%02x",
 				phba->shost->host_no, i);
-			msix_vec = phba->msix_entries[i].vector;
-			ret = request_irq(msix_vec, be_isr_msix, 0,
-					  phba->msi_name[i],
+			ret = request_irq(pci_irq_vector(pcidev, i),
+					  be_isr_msix, 0, phba->msi_name[i],
 					  &phwi_context->be_eq[i]);
 			if (ret) {
 				beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
@@ -837,9 +836,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 		}
 		sprintf(phba->msi_name[i], "beiscsi_mcc_%02x",
 			phba->shost->host_no);
-		msix_vec = phba->msix_entries[i].vector;
-		ret = request_irq(msix_vec, be_isr_mcc, 0, phba->msi_name[i],
-				  &phwi_context->be_eq[i]);
+		ret = request_irq(pci_irq_vector(pcidev, i), be_isr_mcc, 0,
+				  phba->msi_name[i], &phwi_context->be_eq[i]);
 		if (ret) {
 			beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT ,
 				    "BM_%d : beiscsi_init_irqs-"
@@ -861,9 +859,8 @@ static int beiscsi_init_irqs(struct beiscsi_hba *phba)
 	return 0;
 free_msix_irqs:
 	for (j = i - 1; j >= 0; j--) {
+		free_irq(pci_irq_vector(pcidev, i), &phwi_context->be_eq[j]);
 		kfree(phba->msi_name[j]);
-		msix_vec = phba->msix_entries[j].vector;
-		free_irq(msix_vec, &phwi_context->be_eq[j]);
 	}
 	return ret;
 }
@@ -3039,7 +3036,7 @@ static int beiscsi_create_eqs(struct beiscsi_hba *phba,
 	num_eq_pages = PAGES_REQUIRED(phba->params.num_eq_entries * \
 				      sizeof(struct be_eq_entry));
 
-	if (phba->msix_enabled)
+	if (phba->pcidev->msix_enabled)
 		eq_for_mcc = 1;
 	else
 		eq_for_mcc = 0;
@@ -3549,7 +3546,7 @@ static int be_mcc_queues_create(struct beiscsi_hba *phba,
 			sizeof(struct be_mcc_compl)))
 		goto err;
 	/* Ask BE to create MCC compl queue; */
-	if (phba->msix_enabled) {
+	if (phba->pcidev->msix_enabled) {
 		if (beiscsi_cmd_cq_create(ctrl, cq, &phwi_context->be_eq
 					 [phba->num_cpus].q, false, true, 0))
 		goto mcc_cq_free;
@@ -3580,42 +3577,35 @@ static int be_mcc_queues_create(struct beiscsi_hba *phba,
 	return -ENOMEM;
 }
 
-/**
- * find_num_cpus()- Get the CPU online count
- * @phba: ptr to priv structure
- *
- * CPU count is used for creating EQ.
- **/
-static void find_num_cpus(struct beiscsi_hba *phba)
+static void be2iscsi_enable_msix(struct beiscsi_hba *phba)
 {
-	int  num_cpus = 0;
-
-	num_cpus = num_online_cpus();
+	int nvec = 1;
 
 	switch (phba->generation) {
 	case BE_GEN2:
 	case BE_GEN3:
-		phba->num_cpus = (num_cpus > BEISCSI_MAX_NUM_CPUS) ?
-				  BEISCSI_MAX_NUM_CPUS : num_cpus;
+		nvec = BEISCSI_MAX_NUM_CPUS + 1;
 		break;
 	case BE_GEN4:
-		/*
-		 * If eqid_count == 1 fall back to
-		 * INTX mechanism
-		 **/
-		if (phba->fw_config.eqid_count == 1) {
-			enable_msix = 0;
-			phba->num_cpus = 1;
-			return;
-		}
-
-		phba->num_cpus =
-			(num_cpus > (phba->fw_config.eqid_count - 1)) ?
-			(phba->fw_config.eqid_count - 1) : num_cpus;
+		nvec = phba->fw_config.eqid_count;
 		break;
 	default:
-		phba->num_cpus = 1;
+		nvec = 2;
+		break;
+	}
+
+	/* if eqid_count == 1 fall back to INTX */
+	if (enable_msix && nvec > 1) {
+		const struct irq_affinity desc = { .post_vectors = 1 };
+
+		if (pci_alloc_irq_vectors_affinity(phba->pcidev, 2, nvec,
+				PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, &desc) < 0) {
+			phba->num_cpus = nvec - 1;
+			return;
+		}
 	}
+
+	phba->num_cpus = 1;
 }
 
 static void hwi_purge_eq(struct beiscsi_hba *phba)
@@ -3632,7 +3622,7 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
 
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
-	if (phba->msix_enabled)
+	if (phba->pcidev->msix_enabled)
 		eq_msix = 1;
 	else
 		eq_msix = 0;
@@ -3710,7 +3700,7 @@ static void hwi_cleanup_port(struct beiscsi_hba *phba)
 	}
 
 	be_mcc_queues_destroy(phba);
-	if (phba->msix_enabled)
+	if (phba->pcidev->msix_enabled)
 		eq_for_mcc = 1;
 	else
 		eq_for_mcc = 0;
@@ -4156,7 +4146,7 @@ static void hwi_enable_intr(struct beiscsi_hba *phba)
 		iowrite32(reg, addr);
 	}
 
-	if (!phba->msix_enabled) {
+	if (!phba->pcidev->msix_enabled) {
 		eq = &phwi_context->be_eq[0].q;
 		beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
 			    "BM_%d : eq->id=%d\n", eq->id);
@@ -5279,19 +5269,6 @@ static void beiscsi_eqd_update_work(struct work_struct *work)
 			      msecs_to_jiffies(BEISCSI_EQD_UPDATE_INTERVAL));
 }
 
-static void beiscsi_msix_enable(struct beiscsi_hba *phba)
-{
-	int i, status;
-
-	for (i = 0; i <= phba->num_cpus; i++)
-		phba->msix_entries[i].entry = i;
-
-	status = pci_enable_msix_range(phba->pcidev, phba->msix_entries,
-				       phba->num_cpus + 1, phba->num_cpus + 1);
-	if (status > 0)
-		phba->msix_enabled = true;
-}
-
 static void beiscsi_hw_tpe_check(unsigned long ptr)
 {
 	struct beiscsi_hba *phba;
@@ -5359,15 +5336,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba)
 	if (ret)
 		return ret;
 
-	if (enable_msix)
-		find_num_cpus(phba);
-	else
-		phba->num_cpus = 1;
-	if (enable_msix) {
-		beiscsi_msix_enable(phba);
-		if (!phba->msix_enabled)
-			phba->num_cpus = 1;
-	}
+	be2iscsi_enable_msix(phba);
 
 	beiscsi_get_params(phba);
 	/* Re-enable UER. If different TPE occurs then it is recoverable. */
@@ -5396,7 +5365,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba)
 		irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget, be_iopoll);
 	}
 
-	i = (phba->msix_enabled) ? i : 0;
+	i = (phba->pcidev->msix_enabled) ? i : 0;
 	/* Work item for MCC handling */
 	pbe_eq = &phwi_context->be_eq[i];
 	INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work);
@@ -5434,9 +5403,7 @@ static int beiscsi_enable_port(struct beiscsi_hba *phba)
 	hwi_cleanup_port(phba);
 
 disable_msix:
-	if (phba->msix_enabled)
-		pci_disable_msix(phba->pcidev);
-
+	pci_free_irq_vectors(phba->pcidev);
 	return ret;
 }
 
@@ -5453,7 +5420,7 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload)
 	struct hwi_context_memory *phwi_context;
 	struct hwi_controller *phwi_ctrlr;
 	struct be_eq_obj *pbe_eq;
-	unsigned int i, msix_vec;
+	unsigned int i;
 
 	if (!test_and_clear_bit(BEISCSI_HBA_ONLINE, &phba->state))
 		return;
@@ -5461,16 +5428,16 @@ static void beiscsi_disable_port(struct beiscsi_hba *phba, int unload)
 	phwi_ctrlr = phba->phwi_ctrlr;
 	phwi_context = phwi_ctrlr->phwi_ctxt;
 	hwi_disable_intr(phba);
-	if (phba->msix_enabled) {
+	if (phba->pcidev->msix_enabled) {
 		for (i = 0; i <= phba->num_cpus; i++) {
-			msix_vec = phba->msix_entries[i].vector;
-			free_irq(msix_vec, &phwi_context->be_eq[i]);
+			free_irq(pci_irq_vector(phba->pcidev, i),
+				&phwi_context->be_eq[i]);
 			kfree(phba->msi_name[i]);
 		}
 	} else
 		if (phba->pcidev->irq)
 			free_irq(phba->pcidev->irq, phba);
-	pci_disable_msix(phba->pcidev);
+	pci_free_irq_vectors(phba->pcidev);
 
 	for (i = 0; i < phba->num_cpus; i++) {
 		pbe_eq = &phwi_context->be_eq[i];
@@ -5680,21 +5647,12 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
 	beiscsi_get_params(phba);
 	beiscsi_set_uer_feature(phba);
 
-	if (enable_msix)
-		find_num_cpus(phba);
-	else
-		phba->num_cpus = 1;
+	be2iscsi_enable_msix(phba);
 
 	beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_INIT,
 		    "BM_%d : num_cpus = %d\n",
 		    phba->num_cpus);
 
-	if (enable_msix) {
-		beiscsi_msix_enable(phba);
-		if (!phba->msix_enabled)
-			phba->num_cpus = 1;
-	}
-
 	phba->shost->max_id = phba->params.cxns_per_ctrl;
 	phba->shost->can_queue = phba->params.ios_per_ctrl;
 	ret = beiscsi_get_memory(phba);
@@ -5744,7 +5702,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
 		irq_poll_init(&pbe_eq->iopoll, be_iopoll_budget, be_iopoll);
 	}
 
-	i = (phba->msix_enabled) ? i : 0;
+	i = (phba->pcidev->msix_enabled) ? i : 0;
 	/* Work item for MCC handling */
 	pbe_eq = &phwi_context->be_eq[i];
 	INIT_WORK(&pbe_eq->mcc_work, beiscsi_mcc_work);
@@ -5815,8 +5773,7 @@ static int beiscsi_dev_probe(struct pci_dev *pcidev,
 			   phba->ctrl.mbox_mem_alloced.dma);
 	beiscsi_unmap_pci_function(phba);
 hba_free:
-	if (phba->msix_enabled)
-		pci_disable_msix(phba->pcidev);
+	pci_disable_msix(phba->pcidev);
 	pci_dev_put(phba->pcidev);
 	iscsi_host_free(phba->shost);
 	pci_set_drvdata(pcidev, NULL);
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h
index 2188579..d1d03ee 100644
--- a/drivers/scsi/be2iscsi/be_main.h
+++ b/drivers/scsi/be2iscsi/be_main.h
@@ -323,9 +323,7 @@ struct beiscsi_hba {
 	struct pci_dev *pcidev;
 	unsigned int num_cpus;
 	unsigned int nxt_cqid;
-	struct msix_entry msix_entries[MAX_CPUS];
 	char *msi_name[MAX_CPUS];
-	bool msix_enabled;
 	struct be_mem_descriptor *init_mem;
 
 	unsigned short io_sgl_alloc_index;
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux