From: Niklas Cassel <cassel@kernel.org>
To: Shradha Todi <shradha.t@samsung.com>
Cc: "'Lorenzo Pieralisi'" <lpieralisi@kernel.org>,
"'Krzysztof Wilczyński'" <kw@linux.com>,
"'Manivannan Sadhasivam'" <manivannan.sadhasivam@linaro.org>,
"'Kishon Vijay Abraham I'" <kishon@kernel.org>,
"'Bjorn Helgaas'" <bhelgaas@google.com>,
linux-pci@vger.kernel.org
Subject: Re: [PATCH 2/2] PCI: endpoint: Set prefetch when allocating memory for 64-bit BARs
Date: Fri, 1 Mar 2024 15:15:38 +0100 [thread overview]
Message-ID: <ZeHjCm13UHpPnHOi@fedora> (raw)
In-Reply-To: <001001da6bc4$725e36b0$571aa410$@samsung.com>
Hello Shradha,
On Fri, Mar 01, 2024 at 04:07:21PM +0530, Shradha Todi wrote:
>
>
> > -----Original Message-----
> > From: Niklas Cassel <cassel@kernel.org>
> > Sent: 01 March 2024 00:08
> > To: Lorenzo Pieralisi <lpieralisi@kernel.org>; Krzysztof Wilczyński
> > <kw@linux.com>; Manivannan Sadhasivam
> > <manivannan.sadhasivam@linaro.org>; Kishon Vijay Abraham I
> > <kishon@kernel.org>; Bjorn Helgaas <bhelgaas@google.com>
> > Cc: Shradha Todi <shradha.t@samsung.com>; linux-pci@vger.kernel.org
> > Subject: Re: [PATCH 2/2] PCI: endpoint: Set prefetch when allocating memory
> for
> > 64-bit BARs
> >
> > On Thu, Feb 29, 2024 at 11:48:59AM +0100, Niklas Cassel wrote:
> > > From the PCIe 6.0 base spec:
> > > "Generally only 64-bit BARs are good candidates, since only Legacy
> > > Endpoints are permitted to set the Prefetchable bit in 32-bit BARs,
> > > and most scalable platforms map all 32-bit Memory BARs into
> > > non-prefetchable Memory Space regardless of the Prefetchable bit value."
> > >
> > > "For a PCI Express Endpoint, 64-bit addressing must be supported for
> > > all BARs that have the Prefetchable bit Set. 32-bit addressing is
> > > permitted for all BARs that do not have the Prefetchable bit Set."
> > >
> > > "Any device that has a range that behaves like normal memory should
> > > mark the range as prefetchable. A linear frame buffer in a graphics
> > > device is an example of a range that should be marked prefetchable."
> > >
> > > The PCIe spec tells us that we should have the prefetchable bit set
> > > for 64-bit BARs backed by "normal memory". The backing memory that we
> > > allocate for a 64-bit BAR using pci_epf_alloc_space() (which calls
> > > dma_alloc_coherent()) is obviously "normal memory".
> > >
> > > Thus, set the prefetchable bit when allocating backing memory for a
> > > 64-bit BAR.
> > >
> > > Signed-off-by: Niklas Cassel <cassel@kernel.org>
> > > ---
> > > drivers/pci/endpoint/pci-epf-core.c | 3 ++-
> > > 1 file changed, 2 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/pci/endpoint/pci-epf-core.c
> > > b/drivers/pci/endpoint/pci-epf-core.c
> > > index e7dbbeb1f0de..10264d662abf 100644
> > > --- a/drivers/pci/endpoint/pci-epf-core.c
> > > +++ b/drivers/pci/endpoint/pci-epf-core.c
> > > @@ -305,7 +305,8 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t
> > size, enum pci_barno bar,
> > > epf_bar[bar].size = size;
> > > epf_bar[bar].barno = bar;
> > > if (upper_32_bits(size) || epc_features->bar[bar].only_64bit)
> > > - epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
> > > + epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_64 |
> > > + PCI_BASE_ADDRESS_MEM_PREFETCH;
> > > else
> > > epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_32;
> >
> > This should probably be:
> >
> > if (upper_32_bits(size) || epc_features->bar[bar].only_64bit)
> > epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_64; else
> > epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_TYPE_32;
> >
> > if (epf_bar[bar].flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
> > epf_bar[bar].flags |= PCI_BASE_ADDRESS_MEM_PREFETCH;
> >
> > so that we set PREFETCH even for a EPF driver that had
> > PCI_BASE_ADDRESS_MEM_TYPE_64 set in flags even before calling
> > pci_epf_alloc_space. Will fix in V2.
> >
> >
> >
> >
> > I also found a bug in the existing code.
> > If pci_epf_alloc_space() allocated a 64-bit BAR because of bits in size, then
> the
> > increment in pci_epf_test_alloc_space() was incorrect.
> > (I guess no one uses BARs > 4GB).
> >
> > --- a/drivers/pci/endpoint/functions/pci-epf-test.c
> > +++ b/drivers/pci/endpoint/functions/pci-epf-test.c
> > @@ -865,6 +865,12 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
> > dev_err(dev, "Failed to allocate space for BAR%d\n",
> > bar);
> > epf_test->reg[bar] = base;
> > +
> > + /*
> > + * pci_epf_alloc_space() might have given us a 64-bit BAR,
> > + * even if we only requested a 32-bit BAR.
> > + */
> > + add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ?
> > + 2 : 1;
> >
> > Will send a separate fix with the above.
> >
> >
> > Kind regards,
> > Niklas
>
> Hi Niklas,
>
> A similar fix should go for pci_epf_test_set_bar() as well, since
> pci_epc_set_bar()
> may change the flags.
I do see that this text is here:
https://github.com/torvalds/linux/blob/v6.8-rc6/drivers/pci/endpoint/functions/pci-epf-test.c#L725-L729
Looking at the orginal author of that text:
https://github.com/torvalds/linux/commit/fca83058753456528bef62579ae2b50799d7a473
(turned out that it was me :p)
I see that the reason was that epc->ops->set_bar() for Cadence EP controller
could set PCI_BASE_ADDRESS_MEM_TYPE_64 even if only 32 bits BAR was requested.
Looking at the Cadence set_bar():
https://github.com/torvalds/linux/blob/master/drivers/pci/controller/cadence/pcie-cadence-ep.c#L107-L108
They do set a 64-bit even if a user only requested a 32-bit BAR,
if the requested BAR size was > 4G.
However, we have this check:
https://github.com/torvalds/linux/commit/f25b5fae29d4e5fe6ae17d3f898a959d72519b6a
So that would never happen. pci_epc_set_bar() would error out before calling
the lower level device driver with such a requested configuration.
Now when we have epc_features, if a BAR requires 64-bits, they should set that
as a hardware requirement in epc_features.
A epc->ops->set_bar() should never be allowed to override whas is being
requested IMO.
(It could give an error if it can't fulfill the requested configuration though.)
So what I think should be done:
1) Clean up the Cadence driver, since that code is dead code.
2) Remove the "pci_epc_set_bar() might have given us a 64-bit BAR",
since it is not true.
Note that pci_epf_test_set_bar() still needs to do:
https://github.com/torvalds/linux/blob/master/drivers/pci/endpoint/functions/pci-epf-test.c#L730
But that is because pci_epf_alloc_space() could have set
PCI_BASE_ADDRESS_MEM_TYPE_64. But I don't think that we need a comment for this,
just like how the "add =" in pci_epf_test_alloc_space() does not have a comment:
https://github.com/torvalds/linux/blob/v6.8-rc6/drivers/pci/endpoint/functions/pci-epf-test.c#L860
Kind regards,
Niklas
prev parent reply other threads:[~2024-03-01 14:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-29 10:48 [PATCH 0/2] PCI: endpoint: set prefetchable bit Niklas Cassel
2024-02-29 10:48 ` [PATCH 1/2] PCI: endpoint: Move .only_64bit check to core Niklas Cassel
2024-02-29 10:48 ` [PATCH 2/2] PCI: endpoint: Set prefetch when allocating memory for 64-bit BARs Niklas Cassel
2024-02-29 18:37 ` Niklas Cassel
2024-03-01 10:37 ` Shradha Todi
2024-03-01 14:15 ` Niklas Cassel [this message]
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=ZeHjCm13UHpPnHOi@fedora \
--to=cassel@kernel.org \
--cc=bhelgaas@google.com \
--cc=kishon@kernel.org \
--cc=kw@linux.com \
--cc=linux-pci@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=manivannan.sadhasivam@linaro.org \
--cc=shradha.t@samsung.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox