All of lore.kernel.org
 help / color / mirror / Atom feed
From: Niklas Cassel <cassel@kernel.org>
To: Manivannan Sadhasivam <mani@kernel.org>
Cc: "Jingoo Han" <jingoohan1@gmail.com>,
	"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
	"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
	"Rob Herring" <robh@kernel.org>,
	"Bjorn Helgaas" <bhelgaas@google.com>,
	"Randolph Lin" <randolph@andestech.com>,
	"Samuel Holland" <samuel.holland@sifive.com>,
	"Frank Li" <Frank.Li@nxp.com>,
	"Charles Mirabile" <cmirabil@redhat.com>,
	tim609@andestech.com,
	"Krishna Chaitanya Chundru" <krishna.chundru@oss.qualcomm.com>,
	"Maciej W. Rozycki" <macro@orcam.me.uk>,
	linux-pci@vger.kernel.org
Subject: Re: [PATCH v2 3/4] PCI: dwc: Clean up iatu index usage in dw_pcie_iatu_setup()
Date: Fri, 23 Jan 2026 09:18:58 +0100	[thread overview]
Message-ID: <aXMu8pbSwlOXOdfZ@ryzen> (raw)
In-Reply-To: <sjaogswwqy56c23a24bdiapcjj3ms6otzglfr2745biwnwxwld@2trag56fufue>

On Fri, Jan 23, 2026 at 01:45:07PM +0530, Manivannan Sadhasivam wrote:
> On Thu, Jan 22, 2026 at 11:29:17PM +0100, Niklas Cassel wrote:
> > The current iatu index usage in dw_pcie_iatu_setup() is a mess.
> > 
> 
> s/iatu/iATU here and below.
> 
> > For outbound address translation the index is incremented before usage.
> > For inbound address translation the index is incremented after usage.
> > 
> > Incrementing the index after usage make much more sense, and:
> > Make the index usage consistent for both outbound and inbound address
> > translation.
> > 
> > Most likely, the overly complicated logic for the outbound address
> > translation is because the iatu at index 0 is reserved for CFG IOs
> > (dw_pcie_other_conf_map_bus()), however, we should be able to use the
> > exact same logic for the indexing of the outbound and inbound iatus.
> > (Only the starting index should be different.)
> > 
> > Create two new variables ob_iatu_index_to_use, ib_iatu_index_to_use,
> > which makes it clear from the name itself that it is the index before
> > increment.
> > 
> > Since we always check if there is an index available immediately before
> > programming the iATU, we can remove the useless "ranges exceed outbound
> > iATU size" warnings, as the code is already unreachable. For the same
> > reason, we can also remove the useless breaks outside of the while loops.
> > 
> > Also switch to use the more logical, but equivalent check if index is
> > smaller than length, which is the most common pattern when e.g. looping
> > through an array which has length items (0 to length-1), such that it is
> > even clearer to the reader that this is a zeroes based index.
> > 
> > No functional changes intended.
> > 
> > Signed-off-by: Niklas Cassel <cassel@kernel.org>
> > ---
> >  .../pci/controller/dwc/pcie-designware-host.c | 59 ++++++++++---------
> >  1 file changed, 32 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 991fe5b9a7b3..76be24af7cfd 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -892,9 +892,10 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >  	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> >  	struct dw_pcie_ob_atu_cfg atu = { 0 };
> >  	struct resource_entry *entry;
> > +	int ob_iatu_index_to_use;
> > +	int ib_iatu_index_to_use;
> 
> I'd prefer ob_iatu_index, ib_iatu_index

Ok.

> 
> >  	int i, ret;
> >  
> > -	/* Note the very first outbound ATU is used for CFG IOs */
> >  	if (!pci->num_ob_windows) {
> >  		dev_err(pci->dev, "No outbound iATU found\n");
> >  		return -EINVAL;
> > @@ -910,16 +911,18 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >  	for (i = 0; i < pci->num_ib_windows; i++)
> >  		dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, i);
> >  
> > -	i = 0;
> > +	/*
> > +	 * NOTE: For outbound address translation, outbound iATU at index 0 is
> > +	 * reserved for CFG IOs (dw_pcie_other_conf_map_bus()), thus start at
> > +	 * index 1.
> > +	 */
> > +	ob_iatu_index_to_use = 1;
> >  	resource_list_for_each_entry(entry, &pp->bridge->windows) {
> >  		resource_size_t res_size;
> >  
> >  		if (resource_type(entry->res) != IORESOURCE_MEM)
> >  			continue;
> >  
> > -		if (pci->num_ob_windows <= i + 1)
> > -			break;
> > -
> >  		atu.type = PCIE_ATU_TYPE_MEM;
> >  		atu.parent_bus_addr = entry->res->start - pci->parent_bus_offset;
> >  		atu.pci_addr = entry->res->start - entry->offset;
> > @@ -937,13 +940,13 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >  			 * middle. Otherwise, we would end up only partially
> >  			 * mapping a single resource.
> >  			 */
> > -			if (pci->num_ob_windows <= ++i) {
> > -				dev_err(pci->dev, "Exhausted outbound windows for region: %pr\n",
> > +			if (!(ob_iatu_index_to_use < pci->num_ob_windows)) {
> 
> 			if (ob_iatu_index >= pci->num_ob_windows) ?

Since both you and Frank have commented on this,
I guess I am the weird one.

I will change it.


> 
> > +				dev_err(pci->dev, "Cannot add outbound window for region: %pr\n",
> >  					entry->res);
> >  				return -ENOMEM;
> >  			}
> >  
> > -			atu.index = i;
> > +			atu.index = ob_iatu_index_to_use;
> >  			atu.size = MIN(pci->region_limit + 1, res_size);
> >  
> >  			ret = dw_pcie_prog_outbound_atu(pci, &atu);
> > @@ -953,6 +956,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >  				return ret;
> >  			}
> >  
> > +			ob_iatu_index_to_use++;
> >  			atu.parent_bus_addr += atu.size;
> >  			atu.pci_addr += atu.size;
> >  			res_size -= atu.size;
> > @@ -960,8 +964,8 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >  	}
> >  
> >  	if (pp->io_size) {
> > -		if (pci->num_ob_windows > ++i) {
> > -			atu.index = i;
> > +		if (ob_iatu_index_to_use < pci->num_ob_windows) {
> > +			atu.index = ob_iatu_index_to_use;
> >  			atu.type = PCIE_ATU_TYPE_IO;
> >  			atu.parent_bus_addr = pp->io_base - pci->parent_bus_offset;
> >  			atu.pci_addr = pp->io_bus_addr;
> > @@ -973,34 +977,37 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >  					entry->res);
> >  				return ret;
> >  			}
> > +			ob_iatu_index_to_use++;
> >  		} else {
> > +			/*
> > +			 * If there are not enough outbound windows to give I/O
> > +			 * space its own iATU, the outbound iATU at index 0 will
> > +			 * be shared between I/O space and CFG IOs, by
> > +			 * temporarily reconfiguring the iATU to CFG space, in
> > +			 * order to do a CFG IO, and then immediately restoring
> > +			 * it to I/O space.
> > +			 */
> >  			pp->cfg0_io_shared = true;
> >  		}
> >  	}
> >  
> > -	if (pci->num_ob_windows <= i)
> > -		dev_warn(pci->dev, "Ranges exceed outbound iATU size (%d)\n",
> > -			 pci->num_ob_windows);
> > -
> >  	if (pp->use_atu_msg) {
> > -		if (pci->num_ob_windows > ++i) {
> > -			pp->msg_atu_index = i;
> > +		if (ob_iatu_index_to_use < pci->num_ob_windows) {
> > +			pp->msg_atu_index = ob_iatu_index_to_use;
> > +			ob_iatu_index_to_use++;
> >  		} else {
> >  			dev_err(pci->dev, "Cannot add outbound window for MSG TLP\n");
> >  			return -ENOMEM;
> 
> Let's also be consistent with error checking as well:
> 
> 		if (ob_iatu_index >= pci->num_ob_windows) {
> 			dev_err();
> 			return -ENOMEM;
> 		}
> 
> 		pp->msg_atu_index = ob_iatu_index++;


Yes, I replied this to myself as well:
https://lore.kernel.org/linux-pci/aXKpHS20vHDyh4fL@ryzen/

> 
> >  		}
> >  	}
> >  
> > -	i = 0;
> > +	ib_iatu_index_to_use = 0;
> >  	resource_list_for_each_entry(entry, &pp->bridge->dma_ranges) {
> >  		resource_size_t res_start, res_size, window_size;
> >  
> >  		if (resource_type(entry->res) != IORESOURCE_MEM)
> >  			continue;
> >  
> > -		if (pci->num_ib_windows <= i)
> > -			break;
> > -
> >  		res_size = resource_size(entry->res);
> >  		res_start = entry->res->start;
> >  		while (res_size > 0) {
> > @@ -1009,14 +1016,15 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp)
> >  			 * middle. Otherwise, we would end up only partially
> >  			 * mapping a single resource.
> >  			 */
> > -			if (pci->num_ib_windows <= i) {
> > -				dev_err(pci->dev, "Exhausted inbound windows for region: %pr\n",
> > +			if (!(ib_iatu_index_to_use < pci->num_ib_windows)) {
> 
> 			if (ib_iatu_index >= pci->num_ib_windows) ?

Yes, if I change it in one place, I will change it everywhere.



Kind regards,
Niklas

  reply	other threads:[~2026-01-23  8:19 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-22 22:29 [PATCH v2 0/4] PCI: dwc: Clean up iatu index mess Niklas Cassel
2026-01-22 22:29 ` [PATCH v2 1/4] PCI: dwc: Fix msg_atu_index assignment Niklas Cassel
2026-01-23  2:06   ` Shawn Lin
2026-01-22 22:29 ` [PATCH v2 2/4] PCI: dwc: Improve msg_atu_index error handling Niklas Cassel
2026-01-23  2:07   ` Shawn Lin
2026-01-23  7:51     ` Niklas Cassel
2026-01-22 22:29 ` [PATCH v2 3/4] PCI: dwc: Clean up iatu index usage in dw_pcie_iatu_setup() Niklas Cassel
2026-01-22 22:47   ` Niklas Cassel
2026-01-23  8:15   ` Manivannan Sadhasivam
2026-01-23  8:18     ` Niklas Cassel [this message]
2026-01-22 22:29 ` [PATCH v2 4/4] PCI: dwc: Fix missing iATU setup when ECAM is enabled Niklas Cassel
2026-01-23  8:17   ` Manivannan Sadhasivam

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aXMu8pbSwlOXOdfZ@ryzen \
    --to=cassel@kernel.org \
    --cc=Frank.Li@nxp.com \
    --cc=bhelgaas@google.com \
    --cc=cmirabil@redhat.com \
    --cc=jingoohan1@gmail.com \
    --cc=krishna.chundru@oss.qualcomm.com \
    --cc=kwilczynski@kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lpieralisi@kernel.org \
    --cc=macro@orcam.me.uk \
    --cc=mani@kernel.org \
    --cc=randolph@andestech.com \
    --cc=robh@kernel.org \
    --cc=samuel.holland@sifive.com \
    --cc=tim609@andestech.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.