All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
To: Rob Herring <robh@kernel.org>
Cc: Kishon Vijay Abraham I <kishon@ti.com>,
	Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Jingoo Han <jingoohan1@gmail.com>,
	Gustavo Pimentel <gustavo.pimentel@synopsys.com>,
	Thierry Reding <treding@nvidia.com>,
	Vidya Sagar <vidyas@nvidia.com>,
	linux-omap <linux-omap@vger.kernel.org>,
	PCI <linux-pci@vger.kernel.org>,
	linux-arm-kernel <linux-arm-kernel@lists.infradead.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] PCI: dwc: Move allocate and map page for msi out of dw_pcie_msi_init()
Date: Thu, 24 Sep 2020 15:02:16 +0800	[thread overview]
Message-ID: <20200924150216.47f04296@xhacker.debian> (raw)
In-Reply-To: <CAL_JsqJV_8sCVB2fAi6kk19ZLbO+nKbk-kYsBNEbN+jR84LUgg@mail.gmail.com>

Hi Rob,

On Wed, 23 Sep 2020 10:41:45 -0600 Rob Herring wrote:

> 
> On Wed, Sep 23, 2020 at 12:27 AM Jisheng Zhang
> <Jisheng.Zhang@synaptics.com> wrote:
> >
> > Currently, dw_pcie_msi_init() allocates and maps page for msi, then
> > program the PCIE_MSI_ADDR_LO and PCIE_MSI_ADDR_HI. The Root Complex
> > may lose power during suspend-to-RAM, so when we resume, we want to
> > redo the latter but not the former. If designware based driver (for
> > example, pcie-tegra194.c) calls dw_pcie_msi_init() in resume path, the
> > previous msi page will be leaked.  
> 
> It's worse than this. I think there's also error paths too leaking the

I think you mean the leaking in pcie-tegra194.c's error path. Synaptics
SoC pcie driver(not mainlined) needs to call dw_pcie_msi_init() in resume
path, pcie-tegra194.c shares the same problem, so I mentioned it in the commit
msg, but the patch isn't targeting to fix all the leaking issues in
pcie-tegra194.c. This patch at least fix one of the issue. 

> page. Also, there's never a dma_unmap_page call which should happen
> before freeing.

Thanks for pointing it out. I will add it in v2

> 
> > Move the allocate and map msi page from dw_pcie_msi_init() to
> > dw_pcie_host_init() to fix this problem.
> >
> > Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support")
> > Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
> > ---
> >  drivers/pci/controller/dwc/pci-dra7xx.c       | 18 ++++++++++++-
> >  .../pci/controller/dwc/pcie-designware-host.c | 27 +++++++++----------
> >  2 files changed, 30 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
> > index dc387724cf08..4301cf844a4c 100644
> > --- a/drivers/pci/controller/dwc/pci-dra7xx.c
> > +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
> > @@ -490,7 +490,9 @@ static struct irq_chip dra7xx_pci_msi_bottom_irq_chip = {
> >  static int dra7xx_pcie_msi_host_init(struct pcie_port *pp)
> >  {
> >         struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > +       struct device *dev = pci->dev;
> >         u32 ctrl, num_ctrls;
> > +       int ret;
> >
> >         pp->msi_irq_chip = &dra7xx_pci_msi_bottom_irq_chip;
> >
> > @@ -506,7 +508,21 @@ static int dra7xx_pcie_msi_host_init(struct pcie_port *pp)
> >                                     ~0);
> >         }
> >
> > -       return dw_pcie_allocate_domains(pp);
> > +       ret = dw_pcie_allocate_domains(pp);
> > +       if (ret)
> > +               return ret;
> > +
> > +       pp->msi_page = alloc_page(GFP_KERNEL);
> > +       pp->msi_data = dma_map_page(dev, pp->msi_page, 0, PAGE_SIZE,
> > +                                   DMA_FROM_DEVICE);
> > +       ret = dma_mapping_error(dev, pp->msi_data);
> > +       if (ret) {
> > +               dev_err(dev, "Failed to map MSI data\n");
> > +               __free_page(pp->msi_page);
> > +               pp->msi_page = NULL;
> > +               dw_pcie_free_msi(pp);
> > +       }  
> 
> I don't like having 2 copies of the same thing. Also, doesn't keystone
> need this too?

what about introduce dw_pcie_msi_alloc() to do this?

IIUC, keystone doesn't need this.

> 
> The other thing is .msi_host_init() is abused by having an empty
> function to disable MSI support. We should have a flag instead to
> enable/disable MSI support and then we can key off of that in the
> common code.

FWICT, the .msi_host_init() is to init soc's own msi support rather
than init the DWC's integrated MSI module. So the usage is correct.

> 
> > +       return ret;
> >  }
> >
> >  static const struct dw_pcie_host_ops dra7xx_pcie_host_ops = {
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 9dafecba347f..c23ba64f64fe 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -294,20 +294,7 @@ void dw_pcie_free_msi(struct pcie_port *pp)
> >
> >  void dw_pcie_msi_init(struct pcie_port *pp)  
> 
> Might be good to rename this function with exactly what it does.
> There's too many 'init' and 'setup' functions...

If we move the msi page allocation out of dw_pcie_msi_init(), then
it only initializes the integrated MSI.

Thanks

> 
> >  {
> > -       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > -       struct device *dev = pci->dev;
> > -       u64 msi_target;
> > -
> > -       pp->msi_page = alloc_page(GFP_KERNEL);
> > -       pp->msi_data = dma_map_page(dev, pp->msi_page, 0, PAGE_SIZE,
> > -                                   DMA_FROM_DEVICE);
> > -       if (dma_mapping_error(dev, pp->msi_data)) {
> > -               dev_err(dev, "Failed to map MSI data\n");
> > -               __free_page(pp->msi_page);
> > -               pp->msi_page = NULL;
> > -               return;
> > -       }
> > -       msi_target = (u64)pp->msi_data;
> > +       u64 msi_target = (u64)pp->msi_data;
> >
> >         /* Program the msi_data */
> >         dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4,
> > @@ -440,6 +427,18 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >                                 irq_set_chained_handler_and_data(pp->msi_irq,
> >                                                             dw_chained_msi_isr,
> >                                                             pp);
> > +
> > +                       pp->msi_page = alloc_page(GFP_KERNEL);
> > +                       pp->msi_data = dma_map_page(pci->dev, pp->msi_page,
> > +                                                   0, PAGE_SIZE,
> > +                                                   DMA_FROM_DEVICE);
> > +                       ret = dma_mapping_error(pci->dev, pp->msi_data);
> > +                       if (ret) {
> > +                               dev_err(pci->dev, "Failed to map MSI data\n");
> > +                               __free_page(pp->msi_page);
> > +                               pp->msi_page = NULL;
> > +                               goto err_free_msi;
> > +                       }
> >                 } else {
> >                         ret = pp->ops->msi_host_init(pp);
> >                         if (ret < 0)
> > --
> > 2.28.0
> >  


WARNING: multiple messages have this Message-ID (diff)
From: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
To: Rob Herring <robh@kernel.org>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	Jingoo Han <jingoohan1@gmail.com>,
	Vidya Sagar <vidyas@nvidia.com>, PCI <linux-pci@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	Kishon Vijay Abraham I <kishon@ti.com>,
	linux-omap <linux-omap@vger.kernel.org>,
	Gustavo Pimentel <gustavo.pimentel@synopsys.com>,
	Bjorn Helgaas <bhelgaas@google.com>,
	Thierry Reding <treding@nvidia.com>,
	linux-arm-kernel <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH] PCI: dwc: Move allocate and map page for msi out of dw_pcie_msi_init()
Date: Thu, 24 Sep 2020 15:02:16 +0800	[thread overview]
Message-ID: <20200924150216.47f04296@xhacker.debian> (raw)
In-Reply-To: <CAL_JsqJV_8sCVB2fAi6kk19ZLbO+nKbk-kYsBNEbN+jR84LUgg@mail.gmail.com>

Hi Rob,

On Wed, 23 Sep 2020 10:41:45 -0600 Rob Herring wrote:

> 
> On Wed, Sep 23, 2020 at 12:27 AM Jisheng Zhang
> <Jisheng.Zhang@synaptics.com> wrote:
> >
> > Currently, dw_pcie_msi_init() allocates and maps page for msi, then
> > program the PCIE_MSI_ADDR_LO and PCIE_MSI_ADDR_HI. The Root Complex
> > may lose power during suspend-to-RAM, so when we resume, we want to
> > redo the latter but not the former. If designware based driver (for
> > example, pcie-tegra194.c) calls dw_pcie_msi_init() in resume path, the
> > previous msi page will be leaked.  
> 
> It's worse than this. I think there's also error paths too leaking the

I think you mean the leaking in pcie-tegra194.c's error path. Synaptics
SoC pcie driver(not mainlined) needs to call dw_pcie_msi_init() in resume
path, pcie-tegra194.c shares the same problem, so I mentioned it in the commit
msg, but the patch isn't targeting to fix all the leaking issues in
pcie-tegra194.c. This patch at least fix one of the issue. 

> page. Also, there's never a dma_unmap_page call which should happen
> before freeing.

Thanks for pointing it out. I will add it in v2

> 
> > Move the allocate and map msi page from dw_pcie_msi_init() to
> > dw_pcie_host_init() to fix this problem.
> >
> > Fixes: 56e15a238d92 ("PCI: tegra: Add Tegra194 PCIe support")
> > Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
> > ---
> >  drivers/pci/controller/dwc/pci-dra7xx.c       | 18 ++++++++++++-
> >  .../pci/controller/dwc/pcie-designware-host.c | 27 +++++++++----------
> >  2 files changed, 30 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
> > index dc387724cf08..4301cf844a4c 100644
> > --- a/drivers/pci/controller/dwc/pci-dra7xx.c
> > +++ b/drivers/pci/controller/dwc/pci-dra7xx.c
> > @@ -490,7 +490,9 @@ static struct irq_chip dra7xx_pci_msi_bottom_irq_chip = {
> >  static int dra7xx_pcie_msi_host_init(struct pcie_port *pp)
> >  {
> >         struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > +       struct device *dev = pci->dev;
> >         u32 ctrl, num_ctrls;
> > +       int ret;
> >
> >         pp->msi_irq_chip = &dra7xx_pci_msi_bottom_irq_chip;
> >
> > @@ -506,7 +508,21 @@ static int dra7xx_pcie_msi_host_init(struct pcie_port *pp)
> >                                     ~0);
> >         }
> >
> > -       return dw_pcie_allocate_domains(pp);
> > +       ret = dw_pcie_allocate_domains(pp);
> > +       if (ret)
> > +               return ret;
> > +
> > +       pp->msi_page = alloc_page(GFP_KERNEL);
> > +       pp->msi_data = dma_map_page(dev, pp->msi_page, 0, PAGE_SIZE,
> > +                                   DMA_FROM_DEVICE);
> > +       ret = dma_mapping_error(dev, pp->msi_data);
> > +       if (ret) {
> > +               dev_err(dev, "Failed to map MSI data\n");
> > +               __free_page(pp->msi_page);
> > +               pp->msi_page = NULL;
> > +               dw_pcie_free_msi(pp);
> > +       }  
> 
> I don't like having 2 copies of the same thing. Also, doesn't keystone
> need this too?

what about introduce dw_pcie_msi_alloc() to do this?

IIUC, keystone doesn't need this.

> 
> The other thing is .msi_host_init() is abused by having an empty
> function to disable MSI support. We should have a flag instead to
> enable/disable MSI support and then we can key off of that in the
> common code.

FWICT, the .msi_host_init() is to init soc's own msi support rather
than init the DWC's integrated MSI module. So the usage is correct.

> 
> > +       return ret;
> >  }
> >
> >  static const struct dw_pcie_host_ops dra7xx_pcie_host_ops = {
> > diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
> > index 9dafecba347f..c23ba64f64fe 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware-host.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware-host.c
> > @@ -294,20 +294,7 @@ void dw_pcie_free_msi(struct pcie_port *pp)
> >
> >  void dw_pcie_msi_init(struct pcie_port *pp)  
> 
> Might be good to rename this function with exactly what it does.
> There's too many 'init' and 'setup' functions...

If we move the msi page allocation out of dw_pcie_msi_init(), then
it only initializes the integrated MSI.

Thanks

> 
> >  {
> > -       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
> > -       struct device *dev = pci->dev;
> > -       u64 msi_target;
> > -
> > -       pp->msi_page = alloc_page(GFP_KERNEL);
> > -       pp->msi_data = dma_map_page(dev, pp->msi_page, 0, PAGE_SIZE,
> > -                                   DMA_FROM_DEVICE);
> > -       if (dma_mapping_error(dev, pp->msi_data)) {
> > -               dev_err(dev, "Failed to map MSI data\n");
> > -               __free_page(pp->msi_page);
> > -               pp->msi_page = NULL;
> > -               return;
> > -       }
> > -       msi_target = (u64)pp->msi_data;
> > +       u64 msi_target = (u64)pp->msi_data;
> >
> >         /* Program the msi_data */
> >         dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4,
> > @@ -440,6 +427,18 @@ int dw_pcie_host_init(struct pcie_port *pp)
> >                                 irq_set_chained_handler_and_data(pp->msi_irq,
> >                                                             dw_chained_msi_isr,
> >                                                             pp);
> > +
> > +                       pp->msi_page = alloc_page(GFP_KERNEL);
> > +                       pp->msi_data = dma_map_page(pci->dev, pp->msi_page,
> > +                                                   0, PAGE_SIZE,
> > +                                                   DMA_FROM_DEVICE);
> > +                       ret = dma_mapping_error(pci->dev, pp->msi_data);
> > +                       if (ret) {
> > +                               dev_err(pci->dev, "Failed to map MSI data\n");
> > +                               __free_page(pp->msi_page);
> > +                               pp->msi_page = NULL;
> > +                               goto err_free_msi;
> > +                       }
> >                 } else {
> >                         ret = pp->ops->msi_host_init(pp);
> >                         if (ret < 0)
> > --
> > 2.28.0
> >  


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2020-09-24  7:05 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-23  6:26 [PATCH] PCI: dwc: Move allocate and map page for msi out of dw_pcie_msi_init() Jisheng Zhang
2020-09-23  6:26 ` Jisheng Zhang
2020-09-23 16:41 ` Rob Herring
2020-09-23 16:41   ` Rob Herring
2020-09-24  7:02   ` Jisheng Zhang [this message]
2020-09-24  7:02     ` Jisheng Zhang
2020-09-24 11:00 ` Ard Biesheuvel
2020-09-24 11:00   ` Ard Biesheuvel
2020-09-24 13:28   ` Rob Herring
2020-09-24 13:28     ` Rob Herring
2020-09-24 13:45     ` Ard Biesheuvel
2020-09-24 13:45       ` Ard Biesheuvel
2020-09-24 14:32       ` Ard Biesheuvel
2020-09-24 14:32         ` Ard Biesheuvel
2020-09-24 15:09         ` Rob Herring
2020-09-24 15:09           ` Rob Herring
2020-09-25  8:56     ` Jisheng Zhang
2020-09-25  8:56       ` Jisheng Zhang

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=20200924150216.47f04296@xhacker.debian \
    --to=jisheng.zhang@synaptics.com \
    --cc=bhelgaas@google.com \
    --cc=gustavo.pimentel@synopsys.com \
    --cc=jingoohan1@gmail.com \
    --cc=kishon@ti.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=robh@kernel.org \
    --cc=treding@nvidia.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.