Re: [PATCH] PCI: dwc: ep: Do not map more memory than needed to raise a MSI/MSI-X IRQ

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

 



On Mon, Nov 04, 2024 at 09:51:44PM +0100, Niklas Cassel wrote:
> In dw_pcie_ep_init() we allocate memory from the EPC address space that we
> will later use to raise a MSI/MSI-X IRQ. This memory is only freed in
> dw_pcie_ep_deinit().
> 
> Performing this allocation in dw_pcie_ep_init() is to ensure that we will
> not fail to allocate memory from the EPC address space when trying to raise
> a MSI/MSI-X IRQ.
> 
> We still map/unmap this memory every time we raise an IRQ, in order to not
> constantly occupy an iATU, especially for controllers with few iATUs.
> (So we can still fail to raise an MSI/MSI-X IRQ if all iATUs are occupied.)
> 
> When allocating this memory in dw_pcie_ep_init(), we allocate
> epc->mem->window.page_size memory, which is the smallest unit that we can
> allocate from the EPC address space.
> 
> However, when writing/sending the msg data, which is only 2 bytes for MSI,
> 4 bytes for MSI-X, in either case a single writel() is sufficient. Thus,
> the size that we need to map is a single PCI DWORD (4 bytes).
> 
> This is the size that we should send in to the pci_epc_ops::align_addr()
> API. It is align_addr()'s responsibility to return a size that is aligned
> to the EPC page size, for platforms that need a special alignment.
> 
> Modify the align_addr() call to send in the proper size that we need to
> map.
> 
> Before this patch on a system with a EPC page size 64k, we would
> incorrectly map 128k (which is larger than our allocation) instead of 64k.
> 
> After this patch, we will correctly map 64k (a single page). (We should
> never need to map more than a page to write a single DWORD.)
> 
> Fixes: f68da9a67173 ("PCI: dwc: ep: Use align addr function for dw_pcie_ep_raise_{msi,msix}_irq()")
> Signed-off-by: Niklas Cassel <cassel@xxxxxxxxxx>

FWIW,

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

- Mani

> ---
> Feel free to squash this with the patch that it fixes, if you so prefer.
> 
>  drivers/pci/controller/dwc/pcie-designware-ep.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c
> index 9bafa62bed1dc..507e40bd18c8f 100644
> --- a/drivers/pci/controller/dwc/pcie-designware-ep.c
> +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
> @@ -503,7 +503,7 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
>  	u32 msg_addr_lower, msg_addr_upper, reg;
>  	struct dw_pcie_ep_func *ep_func;
>  	struct pci_epc *epc = ep->epc;
> -	size_t msi_mem_size = epc->mem->window.page_size;
> +	size_t map_size = sizeof(u32);
>  	size_t offset;
>  	u16 msg_ctrl, msg_data;
>  	bool has_upper;
> @@ -532,9 +532,9 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no,
>  	}
>  	msg_addr = ((u64)msg_addr_upper) << 32 | msg_addr_lower;
>  
> -	msg_addr = dw_pcie_ep_align_addr(epc, msg_addr, &msi_mem_size, &offset);
> +	msg_addr = dw_pcie_ep_align_addr(epc, msg_addr, &map_size, &offset);
>  	ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
> -				  msi_mem_size);
> +				  map_size);
>  	if (ret)
>  		return ret;
>  
> @@ -589,7 +589,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
>  	struct pci_epf_msix_tbl *msix_tbl;
>  	struct dw_pcie_ep_func *ep_func;
>  	struct pci_epc *epc = ep->epc;
> -	size_t msi_mem_size = epc->mem->window.page_size;
> +	size_t map_size = sizeof(u32);
>  	size_t offset;
>  	u32 reg, msg_data, vec_ctrl;
>  	u32 tbl_offset;
> @@ -616,9 +616,9 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no,
>  		return -EPERM;
>  	}
>  
> -	msg_addr = dw_pcie_ep_align_addr(epc, msg_addr, &msi_mem_size, &offset);
> +	msg_addr = dw_pcie_ep_align_addr(epc, msg_addr, &map_size, &offset);
>  	ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
> -				  epc->mem->window.page_size);
> +				  map_size);
>  	if (ret)
>  		return ret;
>  
> -- 
> 2.47.0
> 

-- 
மணிவண்ணன் சதாசிவம்




[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux