Torsten Duwe b76de9
From 9832fdc917de0f28772558688d7fa6c097c9c6cc Mon Sep 17 00:00:00 2001
Torsten Duwe b76de9
From: Maksim Lukoshkov <maksim.lukoshkov@intel.com>
Torsten Duwe b76de9
Date: Wed, 1 Sep 2021 18:36:07 +0100
Torsten Duwe b76de9
Subject: [PATCH] crypto: qat - free irqs only if allocated
Torsten Duwe b76de9
Git-commit: 9832fdc917de0f28772558688d7fa6c097c9c6cc
Torsten Duwe b76de9
Patch-mainline: v5.16-rc1
Torsten Duwe b76de9
References: jsc#PED-1073
Torsten Duwe b76de9
Torsten Duwe b76de9
Change the irq allocation logic so that it is possible to free only the
Torsten Duwe b76de9
allocated irqs in case of error.
Torsten Duwe b76de9
A new flag is introduced for every PF/VF interrupt. This flag is set to
Torsten Duwe b76de9
"true" only when the interrupt is requested.
Torsten Duwe b76de9
During clean up, devm_free_irq() is only called if this flag is set.
Torsten Duwe b76de9
Torsten Duwe b76de9
Signed-off-by: Maksim Lukoshkov <maksim.lukoshkov@intel.com>
Torsten Duwe b76de9
Co-developed-by: Wojciech Ziemba <wojciech.ziemba@intel.com>
Torsten Duwe b76de9
Signed-off-by: Wojciech Ziemba <wojciech.ziemba@intel.com>
Torsten Duwe b76de9
Reviewed-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Torsten Duwe b76de9
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Torsten Duwe b76de9
Signed-off-by: Torsten Duwe <duwe@suse.de>
Torsten Duwe b76de9
Torsten Duwe b76de9
---
Torsten Duwe b76de9
 .../crypto/qat/qat_common/adf_accel_devices.h | 10 +++-
Torsten Duwe b76de9
 drivers/crypto/qat/qat_common/adf_isr.c       | 50 ++++++++-----------
Torsten Duwe b76de9
 drivers/crypto/qat/qat_common/adf_vf_isr.c    | 12 ++---
Torsten Duwe b76de9
 3 files changed, 35 insertions(+), 37 deletions(-)
Torsten Duwe b76de9
Torsten Duwe b76de9
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
Torsten Duwe b76de9
index 87de40d6c9a5f..e391ca0662bc5 100644
Torsten Duwe b76de9
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
Torsten Duwe b76de9
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
Torsten Duwe b76de9
@@ -44,8 +44,13 @@ struct adf_bar {
Torsten Duwe b76de9
 	resource_size_t size;
Torsten Duwe b76de9
 } __packed;
Torsten Duwe b76de9
 
Torsten Duwe b76de9
+struct adf_irq {
Torsten Duwe b76de9
+	bool enabled;
Torsten Duwe b76de9
+	char name[ADF_MAX_MSIX_VECTOR_NAME];
Torsten Duwe b76de9
+};
Torsten Duwe b76de9
+
Torsten Duwe b76de9
 struct adf_accel_msix {
Torsten Duwe b76de9
-	char **names;
Torsten Duwe b76de9
+	struct adf_irq *irqs;
Torsten Duwe b76de9
 	u32 num_entries;
Torsten Duwe b76de9
 } __packed;
Torsten Duwe b76de9
 
Torsten Duwe b76de9
@@ -250,7 +255,8 @@ struct adf_accel_dev {
Torsten Duwe b76de9
 			struct adf_accel_vf_info *vf_info;
Torsten Duwe b76de9
 		} pf;
Torsten Duwe b76de9
 		struct {
Torsten Duwe b76de9
-			char *irq_name;
Torsten Duwe b76de9
+			bool irq_enabled;
Torsten Duwe b76de9
+			char irq_name[ADF_MAX_MSIX_VECTOR_NAME];
Torsten Duwe b76de9
 			struct tasklet_struct pf2vf_bh_tasklet;
Torsten Duwe b76de9
 			struct mutex vf2pf_lock; /* protect CSR access */
Torsten Duwe b76de9
 			struct completion iov_msg_completion;
Torsten Duwe b76de9
diff --git a/drivers/crypto/qat/qat_common/adf_isr.c b/drivers/crypto/qat/qat_common/adf_isr.c
Torsten Duwe b76de9
index 26b546d3f8215..861a9368b9db0 100644
Torsten Duwe b76de9
--- a/drivers/crypto/qat/qat_common/adf_isr.c
Torsten Duwe b76de9
+++ b/drivers/crypto/qat/qat_common/adf_isr.c
Torsten Duwe b76de9
@@ -130,6 +130,7 @@ static int adf_request_irqs(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 {
Torsten Duwe b76de9
 	struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
Torsten Duwe b76de9
 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
Torsten Duwe b76de9
+	struct adf_irq *irqs = pci_dev_info->msix_entries.irqs;
Torsten Duwe b76de9
 	struct adf_etr_data *etr_data = accel_dev->transport;
Torsten Duwe b76de9
 	int clust_irq = hw_data->num_banks;
Torsten Duwe b76de9
 	int ret, irq, i = 0;
Torsten Duwe b76de9
@@ -141,7 +142,7 @@ static int adf_request_irqs(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 			struct adf_etr_bank_data *bank = &etr_data->banks[i];
Torsten Duwe b76de9
 			unsigned int cpu, cpus = num_online_cpus();
Torsten Duwe b76de9
 
Torsten Duwe b76de9
-			name = *(pci_dev_info->msix_entries.names + i);
Torsten Duwe b76de9
+			name = irqs[i].name;
Torsten Duwe b76de9
 			snprintf(name, ADF_MAX_MSIX_VECTOR_NAME,
Torsten Duwe b76de9
 				 "qat%d-bundle%d", accel_dev->accel_id, i);
Torsten Duwe b76de9
 			irq = pci_irq_vector(pci_dev_info->pci_dev, i);
Torsten Duwe b76de9
@@ -163,11 +164,12 @@ static int adf_request_irqs(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 			cpu = ((accel_dev->accel_id * hw_data->num_banks) +
Torsten Duwe b76de9
 			       i) % cpus;
Torsten Duwe b76de9
 			irq_set_affinity_hint(irq, get_cpu_mask(cpu));
Torsten Duwe b76de9
+			irqs[i].enabled = true;
Torsten Duwe b76de9
 		}
Torsten Duwe b76de9
 	}
Torsten Duwe b76de9
 
Torsten Duwe b76de9
 	/* Request msix irq for AE */
Torsten Duwe b76de9
-	name = *(pci_dev_info->msix_entries.names + i);
Torsten Duwe b76de9
+	name = irqs[i].name;
Torsten Duwe b76de9
 	snprintf(name, ADF_MAX_MSIX_VECTOR_NAME,
Torsten Duwe b76de9
 		 "qat%d-ae-cluster", accel_dev->accel_id);
Torsten Duwe b76de9
 	irq = pci_irq_vector(pci_dev_info->pci_dev, clust_irq);
Torsten Duwe b76de9
@@ -183,6 +185,7 @@ static int adf_request_irqs(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 			"Failed to allocate IRQ %d for %s\n", irq, name);
Torsten Duwe b76de9
 		return ret;
Torsten Duwe b76de9
 	}
Torsten Duwe b76de9
+	irqs[i].enabled = true;
Torsten Duwe b76de9
 	return ret;
Torsten Duwe b76de9
 }
Torsten Duwe b76de9
 
Torsten Duwe b76de9
@@ -190,60 +193,51 @@ static void adf_free_irqs(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 {
Torsten Duwe b76de9
 	struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev;
Torsten Duwe b76de9
 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
Torsten Duwe b76de9
+	struct adf_irq *irqs = pci_dev_info->msix_entries.irqs;
Torsten Duwe b76de9
 	struct adf_etr_data *etr_data = accel_dev->transport;
Torsten Duwe b76de9
 	int clust_irq = hw_data->num_banks;
Torsten Duwe b76de9
 	int irq, i = 0;
Torsten Duwe b76de9
 
Torsten Duwe b76de9
 	if (pci_dev_info->msix_entries.num_entries > 1) {
Torsten Duwe b76de9
 		for (i = 0; i < hw_data->num_banks; i++) {
Torsten Duwe b76de9
-			irq = pci_irq_vector(pci_dev_info->pci_dev, i);
Torsten Duwe b76de9
-			irq_set_affinity_hint(irq, NULL);
Torsten Duwe b76de9
-			free_irq(irq, &etr_data->banks[i]);
Torsten Duwe b76de9
+			if (irqs[i].enabled) {
Torsten Duwe b76de9
+				irq = pci_irq_vector(pci_dev_info->pci_dev, i);
Torsten Duwe b76de9
+				irq_set_affinity_hint(irq, NULL);
Torsten Duwe b76de9
+				free_irq(irq, &etr_data->banks[i]);
Torsten Duwe b76de9
+			}
Torsten Duwe b76de9
 		}
Torsten Duwe b76de9
 	}
Torsten Duwe b76de9
 
Torsten Duwe b76de9
-	irq = pci_irq_vector(pci_dev_info->pci_dev, clust_irq);
Torsten Duwe b76de9
-	free_irq(irq, accel_dev);
Torsten Duwe b76de9
+	if (irqs[i].enabled) {
Torsten Duwe b76de9
+		irq = pci_irq_vector(pci_dev_info->pci_dev, clust_irq);
Torsten Duwe b76de9
+		free_irq(irq, accel_dev);
Torsten Duwe b76de9
+	}
Torsten Duwe b76de9
 }
Torsten Duwe b76de9
 
Torsten Duwe b76de9
 static int adf_isr_alloc_msix_vectors_data(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 {
Torsten Duwe b76de9
-	int i;
Torsten Duwe b76de9
-	char **names;
Torsten Duwe b76de9
 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
Torsten Duwe b76de9
 	u32 msix_num_entries = 1;
Torsten Duwe b76de9
+	struct adf_irq *irqs;
Torsten Duwe b76de9
 
Torsten Duwe b76de9
 	/* If SR-IOV is disabled (vf_info is NULL), add entries for each bank */
Torsten Duwe b76de9
 	if (!accel_dev->pf.vf_info)
Torsten Duwe b76de9
 		msix_num_entries += hw_data->num_banks;
Torsten Duwe b76de9
 
Torsten Duwe b76de9
-	names = kcalloc(msix_num_entries, sizeof(char *), GFP_KERNEL);
Torsten Duwe b76de9
-	if (!names)
Torsten Duwe b76de9
+	irqs = kzalloc_node(msix_num_entries * sizeof(*irqs),
Torsten Duwe b76de9
+			    GFP_KERNEL, dev_to_node(&GET_DEV(accel_dev)));
Torsten Duwe b76de9
+	if (!irqs)
Torsten Duwe b76de9
 		return -ENOMEM;
Torsten Duwe b76de9
 
Torsten Duwe b76de9
-	for (i = 0; i < msix_num_entries; i++) {
Torsten Duwe b76de9
-		*(names + i) = kzalloc(ADF_MAX_MSIX_VECTOR_NAME, GFP_KERNEL);
Torsten Duwe b76de9
-		if (!(*(names + i)))
Torsten Duwe b76de9
-			goto err;
Torsten Duwe b76de9
-	}
Torsten Duwe b76de9
 	accel_dev->accel_pci_dev.msix_entries.num_entries = msix_num_entries;
Torsten Duwe b76de9
-	accel_dev->accel_pci_dev.msix_entries.names = names;
Torsten Duwe b76de9
+	accel_dev->accel_pci_dev.msix_entries.irqs = irqs;
Torsten Duwe b76de9
 	return 0;
Torsten Duwe b76de9
-err:
Torsten Duwe b76de9
-	for (i = 0; i < msix_num_entries; i++)
Torsten Duwe b76de9
-		kfree(*(names + i));
Torsten Duwe b76de9
-	kfree(names);
Torsten Duwe b76de9
-	return -ENOMEM;
Torsten Duwe b76de9
 }
Torsten Duwe b76de9
 
Torsten Duwe b76de9
 static void adf_isr_free_msix_vectors_data(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 {
Torsten Duwe b76de9
-	char **names = accel_dev->accel_pci_dev.msix_entries.names;
Torsten Duwe b76de9
-	int i;
Torsten Duwe b76de9
-
Torsten Duwe b76de9
-	for (i = 0; i < accel_dev->accel_pci_dev.msix_entries.num_entries; i++)
Torsten Duwe b76de9
-		kfree(*(names + i));
Torsten Duwe b76de9
-	kfree(names);
Torsten Duwe b76de9
+	kfree(accel_dev->accel_pci_dev.msix_entries.irqs);
Torsten Duwe b76de9
+	accel_dev->accel_pci_dev.msix_entries.irqs = NULL;
Torsten Duwe b76de9
 }
Torsten Duwe b76de9
 
Torsten Duwe b76de9
 static int adf_setup_bh(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
diff --git a/drivers/crypto/qat/qat_common/adf_vf_isr.c b/drivers/crypto/qat/qat_common/adf_vf_isr.c
Torsten Duwe b76de9
index 695c5050b6f34..07f81682c19b5 100644
Torsten Duwe b76de9
--- a/drivers/crypto/qat/qat_common/adf_vf_isr.c
Torsten Duwe b76de9
+++ b/drivers/crypto/qat/qat_common/adf_vf_isr.c
Torsten Duwe b76de9
@@ -61,10 +61,6 @@ static int adf_enable_msi(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 		return stat;
Torsten Duwe b76de9
 	}
Torsten Duwe b76de9
 
Torsten Duwe b76de9
-	accel_dev->vf.irq_name = kzalloc(ADF_MAX_MSIX_VECTOR_NAME, GFP_KERNEL);
Torsten Duwe b76de9
-	if (!accel_dev->vf.irq_name)
Torsten Duwe b76de9
-		return -ENOMEM;
Torsten Duwe b76de9
-
Torsten Duwe b76de9
 	return 0;
Torsten Duwe b76de9
 }
Torsten Duwe b76de9
 
Torsten Duwe b76de9
@@ -72,7 +68,6 @@ static void adf_disable_msi(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 {
Torsten Duwe b76de9
 	struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
Torsten Duwe b76de9
 
Torsten Duwe b76de9
-	kfree(accel_dev->vf.irq_name);
Torsten Duwe b76de9
 	pci_free_irq_vectors(pdev);
Torsten Duwe b76de9
 }
Torsten Duwe b76de9
 
Torsten Duwe b76de9
@@ -240,6 +235,7 @@ static int adf_request_msi_irq(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 	}
Torsten Duwe b76de9
 	cpu = accel_dev->accel_id % num_online_cpus();
Torsten Duwe b76de9
 	irq_set_affinity_hint(pdev->irq, get_cpu_mask(cpu));
Torsten Duwe b76de9
+	accel_dev->vf.irq_enabled = true;
Torsten Duwe b76de9
 
Torsten Duwe b76de9
 	return ret;
Torsten Duwe b76de9
 }
Torsten Duwe b76de9
@@ -271,8 +267,10 @@ void adf_vf_isr_resource_free(struct adf_accel_dev *accel_dev)
Torsten Duwe b76de9
 {
Torsten Duwe b76de9
 	struct pci_dev *pdev = accel_to_pci_dev(accel_dev);
Torsten Duwe b76de9
 
Torsten Duwe b76de9
-	irq_set_affinity_hint(pdev->irq, NULL);
Torsten Duwe b76de9
-	free_irq(pdev->irq, (void *)accel_dev);
Torsten Duwe b76de9
+	if (accel_dev->vf.irq_enabled) {
Torsten Duwe b76de9
+		irq_set_affinity_hint(pdev->irq, NULL);
Torsten Duwe b76de9
+		free_irq(pdev->irq, accel_dev);
Torsten Duwe b76de9
+	}
Torsten Duwe b76de9
 	adf_cleanup_bh(accel_dev);
Torsten Duwe b76de9
 	adf_cleanup_pf2vf_bh(accel_dev);
Torsten Duwe b76de9
 	adf_disable_msi(accel_dev);
Torsten Duwe b76de9
-- 
Torsten Duwe b76de9
2.35.3
Torsten Duwe b76de9