Message ID | 70cb1754e3f0da3b84712460b1017ac707cd2616.1553078908.git.lukas@wunner.de (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
Series | Link bandwidth notification fixes | expand |
On 3/20/19 6:15 AM, Lukas Wunner wrote: > > [EXTERNAL EMAIL] > > If a multi-function device's bandwidth is already limited when it is > enumerated, a message is logged only for function 0. By contrast, when > downtraining occurs after enumeration, a message is logged for all > functions. That's because the former uses pcie_report_downtraining(), > whereas the latter uses __pcie_print_link_status() (which doesn't filter > functions != 0). I am seeing this happen on a MacBookPro9,1 with a GPU > (function 0) and an integrated HDA controller (function 1). > > Avoid this incongruence by calling pcie_report_downtraining() in both > cases. Good catch! Thank you for engineering the fixes. > Signed-off-by: Lukas Wunner <lukas@wunner.de> Reviewed-by: Alexandru Gagniuc <alex.gagniuc@dellteam.com> > --- > drivers/pci/pci.h | 1 + > drivers/pci/pcie/bw_notification.c | 2 +- > drivers/pci/probe.c | 2 +- > 3 files changed, 3 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h > index 224d88634115..d994839a3e24 100644 > --- a/drivers/pci/pci.h > +++ b/drivers/pci/pci.h > @@ -273,6 +273,7 @@ enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev); > u32 pcie_bandwidth_capable(struct pci_dev *dev, enum pci_bus_speed *speed, > enum pcie_link_width *width); > void __pcie_print_link_status(struct pci_dev *dev, bool verbose); > +void pcie_report_downtraining(struct pci_dev *dev); > > /* Single Root I/O Virtualization */ > struct pci_sriov { > diff --git a/drivers/pci/pcie/bw_notification.c b/drivers/pci/pcie/bw_notification.c > index 69e6ba2558bf..c26045f2a890 100644 > --- a/drivers/pci/pcie/bw_notification.c > +++ b/drivers/pci/pcie/bw_notification.c > @@ -76,7 +76,7 @@ static irqreturn_t pcie_bw_notification_handler(int irq, void *context) > */ > down_read(&pci_bus_sem); > list_for_each_entry(dev, &port->subordinate->devices, bus_list) > - __pcie_print_link_status(dev, false); > + pcie_report_downtraining(dev); > up_read(&pci_bus_sem); > > pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status); > diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c > index 2ec0df04e0dc..7e12d0163863 100644 > --- a/drivers/pci/probe.c > +++ b/drivers/pci/probe.c > @@ -2388,7 +2388,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) > return dev; > } > > -static void pcie_report_downtraining(struct pci_dev *dev) > +void pcie_report_downtraining(struct pci_dev *dev) > { > if (!pci_is_pcie(dev)) > return; >
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 224d88634115..d994839a3e24 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -273,6 +273,7 @@ enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev); u32 pcie_bandwidth_capable(struct pci_dev *dev, enum pci_bus_speed *speed, enum pcie_link_width *width); void __pcie_print_link_status(struct pci_dev *dev, bool verbose); +void pcie_report_downtraining(struct pci_dev *dev); /* Single Root I/O Virtualization */ struct pci_sriov { diff --git a/drivers/pci/pcie/bw_notification.c b/drivers/pci/pcie/bw_notification.c index 69e6ba2558bf..c26045f2a890 100644 --- a/drivers/pci/pcie/bw_notification.c +++ b/drivers/pci/pcie/bw_notification.c @@ -76,7 +76,7 @@ static irqreturn_t pcie_bw_notification_handler(int irq, void *context) */ down_read(&pci_bus_sem); list_for_each_entry(dev, &port->subordinate->devices, bus_list) - __pcie_print_link_status(dev, false); + pcie_report_downtraining(dev); up_read(&pci_bus_sem); pcie_capability_read_word(port, PCI_EXP_LNKSTA, &link_status); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2ec0df04e0dc..7e12d0163863 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2388,7 +2388,7 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) return dev; } -static void pcie_report_downtraining(struct pci_dev *dev) +void pcie_report_downtraining(struct pci_dev *dev) { if (!pci_is_pcie(dev)) return;
If a multi-function device's bandwidth is already limited when it is enumerated, a message is logged only for function 0. By contrast, when downtraining occurs after enumeration, a message is logged for all functions. That's because the former uses pcie_report_downtraining(), whereas the latter uses __pcie_print_link_status() (which doesn't filter functions != 0). I am seeing this happen on a MacBookPro9,1 with a GPU (function 0) and an integrated HDA controller (function 1). Avoid this incongruence by calling pcie_report_downtraining() in both cases. Signed-off-by: Lukas Wunner <lukas@wunner.de> --- drivers/pci/pci.h | 1 + drivers/pci/pcie/bw_notification.c | 2 +- drivers/pci/probe.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-)