* [PATCH v2] PCI: Check for PCIe downtraining conditions
@ 2018-06-01 15:01 Alexandru Gagniuc
2018-06-01 15:03 ` Sinan Kaya
2018-06-01 15:12 ` Andy Shevchenko
0 siblings, 2 replies; 7+ messages in thread
From: Alexandru Gagniuc @ 2018-06-01 15:01 UTC (permalink / raw)
To: bhelgaas
Cc: alex_gagniuc, austin_bolen, shyam_iyer, keith.busch, okaya,
Alexandru Gagniuc, linux-pci, linux-kernel
PCIe downtraining happens when both the device and PCIe port are
capable of a larger bus width or higher speed than negotiated.
Downtraining might be indicative of other problems in the system, and
identifying this from userspace is neither intuitive, nor straigh
forward.
The easiest way to detect this is with pcie_print_link_status(),
since the bottleneck is usually the link that is downtrained. It's not
a perfect solution, but it works extremely well in most cases.
Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com>
---
drivers/pci/probe.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ac91b6fd0bcd..e8e158046cab 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2146,6 +2146,25 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
return dev;
}
+static void pcie_check_upstream_link(struct pci_dev *dev)
+{
+
+ if (!pci_is_pcie(dev))
+ return;
+
+ /* Look from the device up to avoid downstream ports with no devices. */
+ if ((pci_pcie_type(dev) != PCI_EXP_TYPE_ENDPOINT) &&
+ (pci_pcie_type(dev) != PCI_EXP_TYPE_LEG_END) &&
+ (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM))
+ return;
+
+ /* Multi-function PCIe share the same link/status. */
+ if (PCI_FUNC(dev->devfn) != 0)
+ return;
+
+ pcie_print_link_status(dev);
+}
+
static void pci_init_capabilities(struct pci_dev *dev)
{
/* Enhanced Allocation */
@@ -2181,6 +2200,9 @@ static void pci_init_capabilities(struct pci_dev *dev)
/* Advanced Error Reporting */
pci_aer_init(dev);
+ /* Check link and detect downtrain errors */
+ pcie_check_upstream_link(dev);
+
if (pci_probe_reset_function(dev) == 0)
dev->reset_fn = 1;
}
--
2.14.3
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2] PCI: Check for PCIe downtraining conditions
2018-06-01 15:01 [PATCH v2] PCI: Check for PCIe downtraining conditions Alexandru Gagniuc
@ 2018-06-01 15:03 ` Sinan Kaya
2018-06-01 15:06 ` Alex G.
2018-06-01 15:12 ` Andy Shevchenko
1 sibling, 1 reply; 7+ messages in thread
From: Sinan Kaya @ 2018-06-01 15:03 UTC (permalink / raw)
To: Alexandru Gagniuc, bhelgaas
Cc: alex_gagniuc, austin_bolen, shyam_iyer, keith.busch, linux-pci,
linux-kernel
On 6/1/2018 11:01 AM, Alexandru Gagniuc wrote:
> + /* Multi-function PCIe share the same link/status. */
> + if (PCI_FUNC(dev->devfn) != 0)
> + return;
How about virtual functions?
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] PCI: Check for PCIe downtraining conditions
2018-06-01 15:03 ` Sinan Kaya
@ 2018-06-01 15:06 ` Alex G.
2018-06-01 15:10 ` Sinan Kaya
0 siblings, 1 reply; 7+ messages in thread
From: Alex G. @ 2018-06-01 15:06 UTC (permalink / raw)
To: Sinan Kaya, bhelgaas
Cc: alex_gagniuc, austin_bolen, shyam_iyer, keith.busch, linux-pci,
linux-kernel
On 06/01/2018 10:03 AM, Sinan Kaya wrote:
> On 6/1/2018 11:01 AM, Alexandru Gagniuc wrote:
>> + /* Multi-function PCIe share the same link/status. */
>> + if (PCI_FUNC(dev->devfn) != 0)
>> + return;
>
> How about virtual functions?
I have almost no clue about those. Is your concern that we might end up
printing more than our fair share of link statuses?
Alex
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] PCI: Check for PCIe downtraining conditions
2018-06-01 15:06 ` Alex G.
@ 2018-06-01 15:10 ` Sinan Kaya
2018-06-01 15:50 ` Alex G.
0 siblings, 1 reply; 7+ messages in thread
From: Sinan Kaya @ 2018-06-01 15:10 UTC (permalink / raw)
To: Alex G., bhelgaas
Cc: alex_gagniuc, austin_bolen, shyam_iyer, keith.busch, linux-pci,
linux-kernel
On 6/1/2018 11:06 AM, Alex G. wrote:
> On 06/01/2018 10:03 AM, Sinan Kaya wrote:
>> On 6/1/2018 11:01 AM, Alexandru Gagniuc wrote:
>>> + /* Multi-function PCIe share the same link/status. */
>>> + if (PCI_FUNC(dev->devfn) != 0)
>>> + return;
>>
>> How about virtual functions?
>
> I have almost no clue about those. Is your concern that we might end up
> printing more than our fair share of link statuses?
Yes, struct pci_dev also has a flag called is_virtfn that you should bail out
here too.
>
> Alex
>
>
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] PCI: Check for PCIe downtraining conditions
2018-06-01 15:01 [PATCH v2] PCI: Check for PCIe downtraining conditions Alexandru Gagniuc
2018-06-01 15:03 ` Sinan Kaya
@ 2018-06-01 15:12 ` Andy Shevchenko
2018-06-01 15:29 ` Alex G.
1 sibling, 1 reply; 7+ messages in thread
From: Andy Shevchenko @ 2018-06-01 15:12 UTC (permalink / raw)
To: Alexandru Gagniuc
Cc: Bjorn Helgaas, alex_gagniuc, austin_bolen, shyam_iyer,
Keith Busch, Sinan Kaya, linux-pci, Linux Kernel Mailing List
On Fri, Jun 1, 2018 at 6:01 PM, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
> PCIe downtraining happens when both the device and PCIe port are
> capable of a larger bus width or higher speed than negotiated.
> Downtraining might be indicative of other problems in the system, and
> identifying this from userspace is neither intuitive, nor straigh
> forward.
>
> The easiest way to detect this is with pcie_print_link_status(),
> since the bottleneck is usually the link that is downtrained. It's not
> a perfect solution, but it works extremely well in most cases.
> +static void pcie_check_upstream_link(struct pci_dev *dev)
> +{
> +
This is redundant, but...
> + if (!pci_is_pcie(dev))
> + return;
> +
> + /* Look from the device up to avoid downstream ports with no devices. */
> + if ((pci_pcie_type(dev) != PCI_EXP_TYPE_ENDPOINT) &&
> + (pci_pcie_type(dev) != PCI_EXP_TYPE_LEG_END) &&
> + (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM))
> + return;
...wouldn't be better
int type = pci_pcie_type(dev);
?
But also possible, looking at existing code,
static inline bool pci_is_pcie_type(dev, type)
{
return pci_is_pcie(dev) ? pci_pcie_type(dev) == type : false;
}
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] PCI: Check for PCIe downtraining conditions
2018-06-01 15:12 ` Andy Shevchenko
@ 2018-06-01 15:29 ` Alex G.
0 siblings, 0 replies; 7+ messages in thread
From: Alex G. @ 2018-06-01 15:29 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Bjorn Helgaas, alex_gagniuc, austin_bolen, shyam_iyer,
Keith Busch, Sinan Kaya, linux-pci, Linux Kernel Mailing List
On 06/01/2018 10:12 AM, Andy Shevchenko wrote:
> On Fri, Jun 1, 2018 at 6:01 PM, Alexandru Gagniuc <mr.nuke.me@gmail.com> wrote:
>> PCIe downtraining happens when both the device and PCIe port are
>> capable of a larger bus width or higher speed than negotiated.
>> Downtraining might be indicative of other problems in the system, and
>> identifying this from userspace is neither intuitive, nor straigh
>> forward.
>>
>> The easiest way to detect this is with pcie_print_link_status(),
>> since the bottleneck is usually the link that is downtrained. It's not
>> a perfect solution, but it works extremely well in most cases.
>
>> +static void pcie_check_upstream_link(struct pci_dev *dev)
>> +{
>
>> +
>
> This is redundant, but...
Hmm. I thought it's not safe to call pci_pcie_type() on non-pcie devices.
I see the pci_is_pcie() check followed by pci_pcie_type() is not
uncommon. I didn't think it would be an issue, as long as it's
consistent with the rest of the code.
>> + if (!pci_is_pcie(dev))
>> + return;
>> +
>> + /* Look from the device up to avoid downstream ports with no devices. */
>> + if ((pci_pcie_type(dev) != PCI_EXP_TYPE_ENDPOINT) &&
>> + (pci_pcie_type(dev) != PCI_EXP_TYPE_LEG_END) &&
>> + (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM))
>> + return;
>
> ...wouldn't be better
>
> int type = pci_pcie_type(dev);
>
> ?
An extra local variable when the compiler knows how to optimize it out?
To me, it doesn't seem like it would improve readability, but it would
make the code longer.
> But also possible, looking at existing code,
>
> static inline bool pci_is_pcie_type(dev, type)
> {
> return pci_is_pcie(dev) ? pci_pcie_type(dev) == type : false;
> }
return pci_is_pcie(dev) && (pci_pcie_type(dev) == type);
seems cleaner. Although this sort of cleanup is beyond the scope of this
change.
Thanks,
Alex
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2] PCI: Check for PCIe downtraining conditions
2018-06-01 15:10 ` Sinan Kaya
@ 2018-06-01 15:50 ` Alex G.
0 siblings, 0 replies; 7+ messages in thread
From: Alex G. @ 2018-06-01 15:50 UTC (permalink / raw)
To: Sinan Kaya, bhelgaas
Cc: alex_gagniuc, austin_bolen, shyam_iyer, keith.busch, linux-pci,
linux-kernel
On 06/01/2018 10:10 AM, Sinan Kaya wrote:
> On 6/1/2018 11:06 AM, Alex G. wrote:
>> On 06/01/2018 10:03 AM, Sinan Kaya wrote:
>>> On 6/1/2018 11:01 AM, Alexandru Gagniuc wrote:
>>>> + /* Multi-function PCIe share the same link/status. */
>>>> + if (PCI_FUNC(dev->devfn) != 0)
>>>> + return;
>>>
>>> How about virtual functions?
>>
>> I have almost no clue about those. Is your concern that we might end up
>> printing more than our fair share of link statuses?
>
> Yes, struct pci_dev also has a flag called is_virtfn that you should bail out
> here too.
Will be fixed in v3.
Thanks,
Alex
>>
>> Alex
>>
>>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2018-06-01 15:50 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-01 15:01 [PATCH v2] PCI: Check for PCIe downtraining conditions Alexandru Gagniuc
2018-06-01 15:03 ` Sinan Kaya
2018-06-01 15:06 ` Alex G.
2018-06-01 15:10 ` Sinan Kaya
2018-06-01 15:50 ` Alex G.
2018-06-01 15:12 ` Andy Shevchenko
2018-06-01 15:29 ` Alex G.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox