diff mbox series

[RESEND,v5,05/18] PCI: dwc: Deallocate EPC memory on EP init error

Message ID 20220624143428.8334-6-Sergey.Semin@baikalelectronics.ru (mailing list archive)
State Accepted
Headers show
Series PCI: dwc: Various fixes and cleanups | expand

Commit Message

Serge Semin June 24, 2022, 2:34 p.m. UTC
If the dw_pcie_ep_init() method fails to perform any action after the EPC
memory is initialized and the MSI memory region is allocated, the later
parts won't be undone thus causing the memory leak.  Let's fix that by
introducing the cleanup-on-error path in the dw_pcie_ep_init() method,
which will be taken should any consequent erroneous situation happens.

Fixes: 2fd0c9d966cc ("PCI: designware-ep: Pre-allocate memory for MSI in dw_pcie_ep_init")
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Rob Herring <robh@kernel.org>

---

Changelog v2:
- This is a new patch create as a result of the discussion in:
  Link: https://lore.kernel.org/linux-pci/20220324014836.19149-26-Sergey.Semin@baikalelectronics.ru
---
 .../pci/controller/dwc/pcie-designware-ep.c    | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

Comments

Manivannan Sadhasivam June 28, 2022, 6:35 a.m. UTC | #1
On Fri, Jun 24, 2022 at 05:34:15PM +0300, Serge Semin wrote:
> If the dw_pcie_ep_init() method fails to perform any action after the EPC
> memory is initialized and the MSI memory region is allocated, the later
> parts won't be undone thus causing the memory leak.  Let's fix that by
> introducing the cleanup-on-error path in the dw_pcie_ep_init() method,
> which will be taken should any consequent erroneous situation happens.
> 
> Fixes: 2fd0c9d966cc ("PCI: designware-ep: Pre-allocate memory for MSI in dw_pcie_ep_init")
> Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Thanks,
Mani

> Tested-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Reviewed-by: Rob Herring <robh@kernel.org>
> 
> ---
> 
> Changelog v2:
> - This is a new patch create as a result of the discussion in:
>   Link: https://lore.kernel.org/linux-pci/20220324014836.19149-26-Sergey.Semin@baikalelectronics.ru
> ---
>  .../pci/controller/dwc/pcie-designware-ep.c    | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 0eda8236c125..13c2e73f0eaf 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -780,8 +780,9 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>  	ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
>  					     epc->mem->window.page_size);
>  	if (!ep->msi_mem) {
> +		ret = -ENOMEM;
>  		dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
> -		return -ENOMEM;
> +		goto err_exit_epc_mem;
>  	}
>  
>  	if (ep->ops->get_features) {
> @@ -790,6 +791,19 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
>  			return 0;
>  	}
>  
> -	return dw_pcie_ep_init_complete(ep);
> +	ret = dw_pcie_ep_init_complete(ep);
> +	if (ret)
> +		goto err_free_epc_mem;
> +
> +	return 0;
> +
> +err_free_epc_mem:
> +	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
> +			      epc->mem->window.page_size);
> +
> +err_exit_epc_mem:
> +	pci_epc_mem_exit(epc);
> +
> +	return ret;
>  }
>  EXPORT_SYMBOL_GPL(dw_pcie_ep_init);
> -- 
> 2.35.1
>
diff mbox series

Patch

diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
index 0eda8236c125..13c2e73f0eaf 100644
--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
+++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
@@ -780,8 +780,9 @@  int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 	ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
 					     epc->mem->window.page_size);
 	if (!ep->msi_mem) {
+		ret = -ENOMEM;
 		dev_err(dev, "Failed to reserve memory for MSI/MSI-X\n");
-		return -ENOMEM;
+		goto err_exit_epc_mem;
 	}
 
 	if (ep->ops->get_features) {
@@ -790,6 +791,19 @@  int dw_pcie_ep_init(struct dw_pcie_ep *ep)
 			return 0;
 	}
 
-	return dw_pcie_ep_init_complete(ep);
+	ret = dw_pcie_ep_init_complete(ep);
+	if (ret)
+		goto err_free_epc_mem;
+
+	return 0;
+
+err_free_epc_mem:
+	pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
+			      epc->mem->window.page_size);
+
+err_exit_epc_mem:
+	pci_epc_mem_exit(epc);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(dw_pcie_ep_init);