All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mingchuang Qiao <mingchuang.qiao@mediatek.com>
To: Bjorn Helgaas <helgaas@kernel.org>
Cc: <bhelgaas@google.com>, <matthias.bgg@gmail.com>,
	<kerun.zhu@mediatek.com>, <linux-pci@vger.kernel.org>,
	<lambert.wang@mediatek.com>, <linux-kernel@vger.kernel.org>,
	<linux-mediatek@lists.infradead.org>, <haijun.liu@mediatek.com>,
	<linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH] pci: avoid unsync of LTR mechanism configuration
Date: Mon, 18 Jan 2021 10:55:33 +0800	[thread overview]
Message-ID: <1610938533.5980.11.camel@mcddlt001> (raw)
In-Reply-To: <20210112213635.GA1854447@bjorn-Precision-5520>

On Tue, 2021-01-12 at 15:36 -0600, Bjorn Helgaas wrote:
> Note subject line tips at https://lore.kernel.org/r/20171026223701.GA25649@bhelgaas-glaptop.roam.corp.google.com
> 
> On Tue, Jan 12, 2021 at 03:27:39PM +0800, mingchuang.qiao@mediatek.com wrote:
> > From: Mingchuang Qiao <mingchuang.qiao@mediatek.com>
> > 
> > In pci bus scan flow, the LTR mechanism enable bit of DEVCTL2 register
> > is configured in pci_configure_ltr(). If device and it's bridge both
> > support LTR mechanism, LTR mechanism of device and it's bridge will
> > be enabled in DEVCTL2 register. And the flag pci_dev->ltr_path will
> > be set as 1.
> 
> s/it's/its/ twice above.
> It's == It is.
> Its == belonging to 'it'.
> Weird, I know, but that's English for you :)
> 
> > For some pcie products, pcie link becomes down when device reset. And then
> > the LTR mechanism enable bit of bridge will become 0 based on description
> > in PCIE r4.0, sec 7.8.16. However, the pci_dev->ltr_path value of bridge
> > is still 1. Remove and rescan flow could be triggered to recover after
> > device reset. In the bus rescan flow, the LTR mechanism of device will be
> > enabled in pci_configure_ltr() due to ltr_path of its bridge is still 1.
> 
> s/pcie/PCIe/ twice above.
> s/PCIE/PCIe/; also reference r5.0 instead of r4.0 if possible.
> 

Sorry for the misspelling and inconvenience. Thanks for the correction
and I will follow the suggestion in later patch.

> This sounds like a general problem of most device config bits being
> cleared by reset.  Usually these are restored by pci_restore_state().
> Is that function missing a restore for PCI_EXP_DEVCTL2?  I'd rather
> have a general-purpose way of restoring all the config state than
> little pieces scattered all over.
> 

Actually it’s not PCI_EXP_DEVCTL2 restore missing issue. The
PCI_EXP_DEVCTL2 is correctly saved/restored during bridge runtime
suspend/resume.

It’s the issue that ltr_path value of the bridge mismatches the actual
value in bridge’s PCI_EXP_DEVCTL2.

Here is the scenario for the issue:
1.PCI bus scan done
   -For both PCIe Device and bridge:
      -"LTR Mechanism Enable" bit in PCI_EXP_DEVCTL2 is 1
      - ltr_path value is 1

2.Device resets and PCIe link is down, then "LTR Mechanism Enable" bit
of bridge changes to 0 according to PCIe r5.0, sec 7.5.3.16.
   -The ltr_path value of bridge is still 1 but the "LTR Mechanism
Enable" bit within PCI_EXP_DEVCTL2 changed to 0.

3.Trigger device removal and bridge enters runtime suspend flow.
   -"LTR Mechanism Enable" bit of bridge is 0 and saved by
pci_save_state().

4.Trigger bus rescan and bridge enters runtime resume flow.
   -"LTR Mechanism Enable" bit of bridge is restored by
pci_restore_state() and the value is 0.

5.Scan device and configure device's LTR in pci_configure_ltr().
   -"LTR Mechanism Enable" bit of device is configured as 1 due to
bridge's ltr_path value is 1.

6.The "LTR Mechanism Enable" bit of device and bridge is different now.
   -When device sends LTR Message, bridge will treat the Message as
Unsupported Request according to PCIe r5.0, sec 6.18.

This patch is used to make bridge's ltr_path value match "LTR Mechanism
Enable" bit within DEVCTL2 register and avoid the Unsupported Request.

> > When device's LTR mechanism is enabled, device will send LTR message to
> > bridge. Bridge receives the device's LTR message and found bridge's LTR
> > mechanism is disabled. Then the bridge will generate unsupported request
> > and other error handling flow will be triggered such as AER Non-Fatal
> > error handling.
> > 
> > This patch is used to avoid this unsupported request and make the bridge's
> > ltr_path value is aligned with DEVCTL2 register value. Check bridge
> > register value if aligned with ltr_path in pci_configure_ltr(). If
> > register value is disable and the ltr_path is 1, we need configure
> > the register value as enable.
> > 
> > Signed-off-by: Mingchuang Qiao <mingchuang.qiao@mediatek.com>
> > ---
> >  drivers/pci/probe.c | 18 +++++++++++++++---
> >  1 file changed, 15 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > index 953f15abc850..49355cf4af54 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -2132,9 +2132,21 @@ static void pci_configure_ltr(struct pci_dev *dev)
> >  	 * Complex and all intermediate Switches indicate support for LTR.
> >  	 * PCIe r4.0, sec 6.18.
> >  	 */
> > -	if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
> > -	    ((bridge = pci_upstream_bridge(dev)) &&
> > -	      bridge->ltr_path)) {
> > +	if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
> > +		pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
> > +					 PCI_EXP_DEVCTL2_LTR_EN);
> > +		dev->ltr_path = 1;
> > +		return;
> > +	}
> > +
> > +	bridge = pci_upstream_bridge(dev);
> > +	if (bridge && bridge->ltr_path) {
> > +		pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, &ctl);
> > +		if (!(ctl & PCI_EXP_DEVCTL2_LTR_EN)) {
> > +			pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2,
> > +						 PCI_EXP_DEVCTL2_LTR_EN);
> > +		}
> > +
> >  		pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
> >  					 PCI_EXP_DEVCTL2_LTR_EN);
> >  		dev->ltr_path = 1;
> > -- 
> > 2.18.0
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel


WARNING: multiple messages have this Message-ID (diff)
From: Mingchuang Qiao <mingchuang.qiao@mediatek.com>
To: Bjorn Helgaas <helgaas@kernel.org>
Cc: kerun.zhu@mediatek.com, linux-pci@vger.kernel.org,
	lambert.wang@mediatek.com, linux-kernel@vger.kernel.org,
	matthias.bgg@gmail.com, linux-mediatek@lists.infradead.org,
	haijun.liu@mediatek.com, bhelgaas@google.com,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] pci: avoid unsync of LTR mechanism configuration
Date: Mon, 18 Jan 2021 10:55:33 +0800	[thread overview]
Message-ID: <1610938533.5980.11.camel@mcddlt001> (raw)
In-Reply-To: <20210112213635.GA1854447@bjorn-Precision-5520>

On Tue, 2021-01-12 at 15:36 -0600, Bjorn Helgaas wrote:
> Note subject line tips at https://lore.kernel.org/r/20171026223701.GA25649@bhelgaas-glaptop.roam.corp.google.com
> 
> On Tue, Jan 12, 2021 at 03:27:39PM +0800, mingchuang.qiao@mediatek.com wrote:
> > From: Mingchuang Qiao <mingchuang.qiao@mediatek.com>
> > 
> > In pci bus scan flow, the LTR mechanism enable bit of DEVCTL2 register
> > is configured in pci_configure_ltr(). If device and it's bridge both
> > support LTR mechanism, LTR mechanism of device and it's bridge will
> > be enabled in DEVCTL2 register. And the flag pci_dev->ltr_path will
> > be set as 1.
> 
> s/it's/its/ twice above.
> It's == It is.
> Its == belonging to 'it'.
> Weird, I know, but that's English for you :)
> 
> > For some pcie products, pcie link becomes down when device reset. And then
> > the LTR mechanism enable bit of bridge will become 0 based on description
> > in PCIE r4.0, sec 7.8.16. However, the pci_dev->ltr_path value of bridge
> > is still 1. Remove and rescan flow could be triggered to recover after
> > device reset. In the bus rescan flow, the LTR mechanism of device will be
> > enabled in pci_configure_ltr() due to ltr_path of its bridge is still 1.
> 
> s/pcie/PCIe/ twice above.
> s/PCIE/PCIe/; also reference r5.0 instead of r4.0 if possible.
> 

Sorry for the misspelling and inconvenience. Thanks for the correction
and I will follow the suggestion in later patch.

> This sounds like a general problem of most device config bits being
> cleared by reset.  Usually these are restored by pci_restore_state().
> Is that function missing a restore for PCI_EXP_DEVCTL2?  I'd rather
> have a general-purpose way of restoring all the config state than
> little pieces scattered all over.
> 

Actually it’s not PCI_EXP_DEVCTL2 restore missing issue. The
PCI_EXP_DEVCTL2 is correctly saved/restored during bridge runtime
suspend/resume.

It’s the issue that ltr_path value of the bridge mismatches the actual
value in bridge’s PCI_EXP_DEVCTL2.

Here is the scenario for the issue:
1.PCI bus scan done
   -For both PCIe Device and bridge:
      -"LTR Mechanism Enable" bit in PCI_EXP_DEVCTL2 is 1
      - ltr_path value is 1

2.Device resets and PCIe link is down, then "LTR Mechanism Enable" bit
of bridge changes to 0 according to PCIe r5.0, sec 7.5.3.16.
   -The ltr_path value of bridge is still 1 but the "LTR Mechanism
Enable" bit within PCI_EXP_DEVCTL2 changed to 0.

3.Trigger device removal and bridge enters runtime suspend flow.
   -"LTR Mechanism Enable" bit of bridge is 0 and saved by
pci_save_state().

4.Trigger bus rescan and bridge enters runtime resume flow.
   -"LTR Mechanism Enable" bit of bridge is restored by
pci_restore_state() and the value is 0.

5.Scan device and configure device's LTR in pci_configure_ltr().
   -"LTR Mechanism Enable" bit of device is configured as 1 due to
bridge's ltr_path value is 1.

6.The "LTR Mechanism Enable" bit of device and bridge is different now.
   -When device sends LTR Message, bridge will treat the Message as
Unsupported Request according to PCIe r5.0, sec 6.18.

This patch is used to make bridge's ltr_path value match "LTR Mechanism
Enable" bit within DEVCTL2 register and avoid the Unsupported Request.

> > When device's LTR mechanism is enabled, device will send LTR message to
> > bridge. Bridge receives the device's LTR message and found bridge's LTR
> > mechanism is disabled. Then the bridge will generate unsupported request
> > and other error handling flow will be triggered such as AER Non-Fatal
> > error handling.
> > 
> > This patch is used to avoid this unsupported request and make the bridge's
> > ltr_path value is aligned with DEVCTL2 register value. Check bridge
> > register value if aligned with ltr_path in pci_configure_ltr(). If
> > register value is disable and the ltr_path is 1, we need configure
> > the register value as enable.
> > 
> > Signed-off-by: Mingchuang Qiao <mingchuang.qiao@mediatek.com>
> > ---
> >  drivers/pci/probe.c | 18 +++++++++++++++---
> >  1 file changed, 15 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > index 953f15abc850..49355cf4af54 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -2132,9 +2132,21 @@ static void pci_configure_ltr(struct pci_dev *dev)
> >  	 * Complex and all intermediate Switches indicate support for LTR.
> >  	 * PCIe r4.0, sec 6.18.
> >  	 */
> > -	if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
> > -	    ((bridge = pci_upstream_bridge(dev)) &&
> > -	      bridge->ltr_path)) {
> > +	if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
> > +		pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
> > +					 PCI_EXP_DEVCTL2_LTR_EN);
> > +		dev->ltr_path = 1;
> > +		return;
> > +	}
> > +
> > +	bridge = pci_upstream_bridge(dev);
> > +	if (bridge && bridge->ltr_path) {
> > +		pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, &ctl);
> > +		if (!(ctl & PCI_EXP_DEVCTL2_LTR_EN)) {
> > +			pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2,
> > +						 PCI_EXP_DEVCTL2_LTR_EN);
> > +		}
> > +
> >  		pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
> >  					 PCI_EXP_DEVCTL2_LTR_EN);
> >  		dev->ltr_path = 1;
> > -- 
> > 2.18.0
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek

WARNING: multiple messages have this Message-ID (diff)
From: Mingchuang Qiao <mingchuang.qiao@mediatek.com>
To: Bjorn Helgaas <helgaas@kernel.org>
Cc: kerun.zhu@mediatek.com, linux-pci@vger.kernel.org,
	lambert.wang@mediatek.com, linux-kernel@vger.kernel.org,
	matthias.bgg@gmail.com, linux-mediatek@lists.infradead.org,
	haijun.liu@mediatek.com, bhelgaas@google.com,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] pci: avoid unsync of LTR mechanism configuration
Date: Mon, 18 Jan 2021 10:55:33 +0800	[thread overview]
Message-ID: <1610938533.5980.11.camel@mcddlt001> (raw)
In-Reply-To: <20210112213635.GA1854447@bjorn-Precision-5520>

On Tue, 2021-01-12 at 15:36 -0600, Bjorn Helgaas wrote:
> Note subject line tips at https://lore.kernel.org/r/20171026223701.GA25649@bhelgaas-glaptop.roam.corp.google.com
> 
> On Tue, Jan 12, 2021 at 03:27:39PM +0800, mingchuang.qiao@mediatek.com wrote:
> > From: Mingchuang Qiao <mingchuang.qiao@mediatek.com>
> > 
> > In pci bus scan flow, the LTR mechanism enable bit of DEVCTL2 register
> > is configured in pci_configure_ltr(). If device and it's bridge both
> > support LTR mechanism, LTR mechanism of device and it's bridge will
> > be enabled in DEVCTL2 register. And the flag pci_dev->ltr_path will
> > be set as 1.
> 
> s/it's/its/ twice above.
> It's == It is.
> Its == belonging to 'it'.
> Weird, I know, but that's English for you :)
> 
> > For some pcie products, pcie link becomes down when device reset. And then
> > the LTR mechanism enable bit of bridge will become 0 based on description
> > in PCIE r4.0, sec 7.8.16. However, the pci_dev->ltr_path value of bridge
> > is still 1. Remove and rescan flow could be triggered to recover after
> > device reset. In the bus rescan flow, the LTR mechanism of device will be
> > enabled in pci_configure_ltr() due to ltr_path of its bridge is still 1.
> 
> s/pcie/PCIe/ twice above.
> s/PCIE/PCIe/; also reference r5.0 instead of r4.0 if possible.
> 

Sorry for the misspelling and inconvenience. Thanks for the correction
and I will follow the suggestion in later patch.

> This sounds like a general problem of most device config bits being
> cleared by reset.  Usually these are restored by pci_restore_state().
> Is that function missing a restore for PCI_EXP_DEVCTL2?  I'd rather
> have a general-purpose way of restoring all the config state than
> little pieces scattered all over.
> 

Actually it’s not PCI_EXP_DEVCTL2 restore missing issue. The
PCI_EXP_DEVCTL2 is correctly saved/restored during bridge runtime
suspend/resume.

It’s the issue that ltr_path value of the bridge mismatches the actual
value in bridge’s PCI_EXP_DEVCTL2.

Here is the scenario for the issue:
1.PCI bus scan done
   -For both PCIe Device and bridge:
      -"LTR Mechanism Enable" bit in PCI_EXP_DEVCTL2 is 1
      - ltr_path value is 1

2.Device resets and PCIe link is down, then "LTR Mechanism Enable" bit
of bridge changes to 0 according to PCIe r5.0, sec 7.5.3.16.
   -The ltr_path value of bridge is still 1 but the "LTR Mechanism
Enable" bit within PCI_EXP_DEVCTL2 changed to 0.

3.Trigger device removal and bridge enters runtime suspend flow.
   -"LTR Mechanism Enable" bit of bridge is 0 and saved by
pci_save_state().

4.Trigger bus rescan and bridge enters runtime resume flow.
   -"LTR Mechanism Enable" bit of bridge is restored by
pci_restore_state() and the value is 0.

5.Scan device and configure device's LTR in pci_configure_ltr().
   -"LTR Mechanism Enable" bit of device is configured as 1 due to
bridge's ltr_path value is 1.

6.The "LTR Mechanism Enable" bit of device and bridge is different now.
   -When device sends LTR Message, bridge will treat the Message as
Unsupported Request according to PCIe r5.0, sec 6.18.

This patch is used to make bridge's ltr_path value match "LTR Mechanism
Enable" bit within DEVCTL2 register and avoid the Unsupported Request.

> > When device's LTR mechanism is enabled, device will send LTR message to
> > bridge. Bridge receives the device's LTR message and found bridge's LTR
> > mechanism is disabled. Then the bridge will generate unsupported request
> > and other error handling flow will be triggered such as AER Non-Fatal
> > error handling.
> > 
> > This patch is used to avoid this unsupported request and make the bridge's
> > ltr_path value is aligned with DEVCTL2 register value. Check bridge
> > register value if aligned with ltr_path in pci_configure_ltr(). If
> > register value is disable and the ltr_path is 1, we need configure
> > the register value as enable.
> > 
> > Signed-off-by: Mingchuang Qiao <mingchuang.qiao@mediatek.com>
> > ---
> >  drivers/pci/probe.c | 18 +++++++++++++++---
> >  1 file changed, 15 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> > index 953f15abc850..49355cf4af54 100644
> > --- a/drivers/pci/probe.c
> > +++ b/drivers/pci/probe.c
> > @@ -2132,9 +2132,21 @@ static void pci_configure_ltr(struct pci_dev *dev)
> >  	 * Complex and all intermediate Switches indicate support for LTR.
> >  	 * PCIe r4.0, sec 6.18.
> >  	 */
> > -	if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT ||
> > -	    ((bridge = pci_upstream_bridge(dev)) &&
> > -	      bridge->ltr_path)) {
> > +	if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) {
> > +		pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
> > +					 PCI_EXP_DEVCTL2_LTR_EN);
> > +		dev->ltr_path = 1;
> > +		return;
> > +	}
> > +
> > +	bridge = pci_upstream_bridge(dev);
> > +	if (bridge && bridge->ltr_path) {
> > +		pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, &ctl);
> > +		if (!(ctl & PCI_EXP_DEVCTL2_LTR_EN)) {
> > +			pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2,
> > +						 PCI_EXP_DEVCTL2_LTR_EN);
> > +		}
> > +
> >  		pcie_capability_set_word(dev, PCI_EXP_DEVCTL2,
> >  					 PCI_EXP_DEVCTL2_LTR_EN);
> >  		dev->ltr_path = 1;
> > -- 
> > 2.18.0
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel@lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

  reply	other threads:[~2021-01-18  2:56 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-12  7:27 [PATCH] pci: avoid unsync of LTR mechanism configuration mingchuang.qiao
2021-01-12  7:27 ` mingchuang.qiao
2021-01-12  7:27 ` mingchuang.qiao
2021-01-12 21:36 ` Bjorn Helgaas
2021-01-12 21:36   ` Bjorn Helgaas
2021-01-12 21:36   ` Bjorn Helgaas
2021-01-18  2:55   ` Mingchuang Qiao [this message]
2021-01-18  2:55     ` Mingchuang Qiao
2021-01-18  2:55     ` Mingchuang Qiao

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=1610938533.5980.11.camel@mcddlt001 \
    --to=mingchuang.qiao@mediatek.com \
    --cc=bhelgaas@google.com \
    --cc=haijun.liu@mediatek.com \
    --cc=helgaas@kernel.org \
    --cc=kerun.zhu@mediatek.com \
    --cc=lambert.wang@mediatek.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=matthias.bgg@gmail.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.