All of lore.kernel.org
 help / color / mirror / Atom feed
From: William McVicker <willmcvicker@google.com>
To: Robin Murphy <robin.murphy@arm.com>
Cc: "Jingoo Han" <jingoohan1@gmail.com>,
	"Gustavo Pimentel" <gustavo.pimentel@synopsys.com>,
	"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
	"Rob Herring" <robh@kernel.org>,
	"Krzysztof Wilczyński" <kw@linux.com>,
	"Bjorn Helgaas" <bhelgaas@google.com>,
	kernel-team@android.com, "Vidya Sagar" <vidyas@nvidia.com>,
	"Christoph Hellwig" <hch@infradead.org>,
	linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	"kernel test robot" <lkp@intel.com>
Subject: Re: [PATCH v5 2/2] PCI: dwc: Add support for 64-bit MSI target address
Date: Thu, 25 Aug 2022 21:22:08 +0000	[thread overview]
Message-ID: <YwfoAKorwSVooUY2@google.com> (raw)
In-Reply-To: <335d730d-529e-7ce0-8bac-008a4daa6e3c@arm.com>

On 08/25/2022, Robin Murphy wrote:
> On 2022-08-25 19:50, Will McVicker wrote:
> > Since not all devices require a 32-bit MSI address, add support to the
> > PCIe host driver to allow setting the DMA mask to 64-bits if the 32-bit
> > allocation fails. This allows kernels to disable ZONE_DMA32 and bounce
> > buffering (swiotlb) without risking not being able to get a 32-bit address
> > during DMA allocation.
> > 
> > Basically, in the slim chance that there are no 32-bit allocations
> > available, the current PCIe host driver will fail to allocate the msi_msg
> > page due to a DMA address overflow (seen in [1]). With this patch, the
> > PCIe host can retry the allocation with a 64-bit DMA mask if the current
> > PCIe device advertises 64-bit support via its MSI capabilities.
> > 
> > [1] https://lore.kernel.org/all/Yo0soniFborDl7+C@google.com/
> > 
> > Reported-by: kernel test robot <lkp@intel.com>
> > Signed-off-by: Will McVicker <willmcvicker@google.com>
> > Reviewed-by: Rob Herring <robh@kernel.org>
> > Acked-by: Jingoo Han <jingoohan1@gmail.com>
> > ---
> >   .../pci/controller/dwc/pcie-designware-host.c | 38 ++++++++++++++-----
> >   drivers/pci/controller/dwc/pcie-designware.c  |  8 ++++
> >   drivers/pci/controller/dwc/pcie-designware.h  |  1 +
> >   3 files changed, 38 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 39f3b37d4033..8928a9a29d58 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -330,6 +330,9 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
> >   	u64 *msi_vaddr;
> >   	int ret;
> >   	u32 ctrl, num_ctrls;
> > +	bool msi_64bit = false;
> > +	bool retry_64bit = false;
> > +	u16 msi_capabilities;
> >   	for (ctrl = 0; ctrl < MAX_MSI_CTRLS; ctrl++)
> >   		pp->irq_mask[ctrl] = ~0;
> > @@ -367,16 +370,33 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
> >   						    dw_chained_msi_isr, pp);
> >   	}
> > -	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
> > -	if (ret)
> > -		dev_warn(dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n");
> > +	msi_capabilities = dw_pcie_msi_capabilities(pci);
> > +	if (msi_capabilities & PCI_MSI_FLAGS_ENABLE)
> > +		msi_64bit = msi_capabilities & PCI_MSI_FLAGS_64BIT;
> > -	msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
> > -					GFP_KERNEL);
> > -	if (!msi_vaddr) {
> > -		dev_err(dev, "Failed to alloc and map MSI data\n");
> > -		dw_pcie_free_msi(pp);
> > -		return -ENOMEM;
> > +	while (true) {
> > +		dev_dbg(dev, "Setting MSI DMA mask to %s-bit.\n",
> > +			retry_64bit ? "64" : "32");
> 
> If only we has some sort of "variable" that could could store a numerical
> value, think of the possibilities... :)

Sure, now that we're trying both 32- and 64-bit, I can do that. Thanks for the
suggestion :)

> 
> > +		ret = dma_set_mask_and_coherent(dev, retry_64bit ?
> > +						DMA_BIT_MASK(64) :
> > +						DMA_BIT_MASK(32));
> > +		if (ret)
> > +			dev_warn(dev, "Failed to set DMA mask to %s-bit.\n",
> > +				 retry_64bit ? "64" : "32");
> 
> Setting a 64-bit mask should never fail, since it represents having no
> possible limitation whatsoever (I'm not sure if there are any platforms left
> where setting a 32-bit mask can actually fail in practice either, but I have
> no strong opinion on the fate of the existing warning).

Yeah, I'm not sure how this could fail. So I just left the warning and edited
the message. It's probably cleaner to just leave the warning unconditionally
based on ret.

> 
> > +
> > +		msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
> > +						GFP_KERNEL);
> > +		if (!msi_vaddr) {
> > +			dev_err(dev, "Failed to alloc and map MSI data\n");
> 
> Possibly a mattrer of personal taste, but I'd say try to avoid dev_err() for
> things that aren't actually fatal; if you're still able to continue on, at
> best it's a warning, not an error. Especially if your use-case *expects* the
> 32-bit allocation fail. There's nothing more offputting than booting a
> typical vendor kernel and watching it scream tons of errors that look
> EXTREMELY IMPORTANT yet are also apparently inconsequential.

Failing a 32-bit allocation should be a rare case, but still possible. If it
fails for both 32-bit and 64-bit, then it's very likely the PCIe device calling
dw_pcie_host_init() will fail to probe. So I'll move this down to only report
that error.

> 
> > +			if (msi_64bit && !retry_64bit) {
> > +				retry_64bit = true;
> > +				continue;
> > +			}
> > +
> > +			dw_pcie_free_msi(pp);
> > +			return -ENOMEM;
> > +		}
> > +		break;
> 
> TBH the whole loop design is a bit baroque for me, I'd have gone for a more
> straightforward tweak to the existing flow, something like:
> 
> 	msi_vaddr = NULL;
> 	ret = dma_set_mask(32);
> 	if (!ret)
> 		msi_vaddr = dma_alloc();
> 	if (!msi_vaddr && msi_64bit) {
> 		dev_warn();
> 		dma_set_mask(64);
> 		msi_vaddr = dma_alloc();
> 	}
> 	if (!msi_vaddr) {
> 		dev_err();
> 		return;
> 	}
> 		
> However I'm happy that you've captured the important functional point, so
> I'll leave the style matters up to Lorenzo.

I was trying to avoid duplicating the allocation code, but if that's preferred,
then I'm fine with it.

> 
> Thanks,
> Robin.
> 
> >   	}
> >   	return 0;
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > index c6725c519a47..650a7f22f9d0 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > @@ -82,6 +82,14 @@ u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap)
> >   }
> >   EXPORT_SYMBOL_GPL(dw_pcie_find_capability);
> > +u16 dw_pcie_msi_capabilities(struct dw_pcie *pci)
> > +{
> > +	u8 offset;
> > +
> > +	offset = dw_pcie_find_capability(pci, PCI_CAP_ID_MSI);
> > +	return dw_pcie_readw_dbi(pci, offset + PCI_MSI_FLAGS);
> > +}
> > +
> >   static u16 dw_pcie_find_next_ext_capability(struct dw_pcie *pci, u16 start,
> >   					    u8 cap)
> >   {
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
> > index a871ae7eb59e..45fcdfc8c035 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.h
> > +++ b/drivers/pci/controller/dwc/pcie-designware.h
> > @@ -332,6 +332,7 @@ void dw_pcie_version_detect(struct dw_pcie *pci);
> >   u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap);
> >   u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap);
> > +u16 dw_pcie_msi_capabilities(struct dw_pcie *pci);
> >   int dw_pcie_read(void __iomem *addr, int size, u32 *val);
> >   int dw_pcie_write(void __iomem *addr, int size, u32 val);

Thanks,
Will

  reply	other threads:[~2022-08-25 21:22 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-25 18:50 [PATCH v5 0/2] PCI: dwc: Add support for 64-bit MSI target addresses Will McVicker
2022-08-25 18:50 ` [PATCH v5 1/2] PCI: dwc: Drop dependency on ZONE_DMA32 Will McVicker
2022-09-28 11:41   ` Serge Semin
2022-09-29 18:25     ` Robin Murphy
2022-09-29 19:32       ` Serge Semin
2022-09-30 11:01         ` Robin Murphy
2022-09-30 12:57           ` Serge Semin
2022-09-30 15:39             ` Robin Murphy
2022-09-30 17:02               ` William McVicker
2022-10-03  8:04                 ` Lorenzo Pieralisi
2022-10-03 16:40                   ` William McVicker
2022-10-07 22:45               ` Serge Semin
2022-08-25 18:50 ` [PATCH v5 2/2] PCI: dwc: Add support for 64-bit MSI target address Will McVicker
2022-08-25 20:59   ` Robin Murphy
2022-08-25 21:22     ` William McVicker [this message]
2022-09-09 13:29   ` Christoph Hellwig
2022-09-09 13:47     ` Robin Murphy
2022-09-09 14:47       ` Christoph Hellwig
2022-09-09 15:00         ` Robin Murphy
2022-09-28 12:05   ` Serge Semin
2022-09-28 17:52     ` William McVicker
2022-09-29  8:13       ` Lorenzo Pieralisi
2022-09-29 18:50         ` William McVicker
2022-09-29 19:00           ` Serge Semin
2022-09-30 13:46     ` Lorenzo Pieralisi
2022-09-30 14:14       ` Serge Semin

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=YwfoAKorwSVooUY2@google.com \
    --to=willmcvicker@google.com \
    --cc=bhelgaas@google.com \
    --cc=gustavo.pimentel@synopsys.com \
    --cc=hch@infradead.org \
    --cc=jingoohan1@gmail.com \
    --cc=kernel-team@android.com \
    --cc=kw@linux.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lkp@intel.com \
    --cc=lpieralisi@kernel.org \
    --cc=robh@kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=vidyas@nvidia.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.