Print information on where along the path we disable L1 or L0s per endpoint. I think the infromation could be useful in the normal dmesg. Signed-off-by: Ian Kumlien <ian.kumlien@xxxxxxxxx> --- drivers/pci/pcie/aspm.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index dbe3ce60c1ff..8bec24119f3e 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -436,6 +436,7 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint) { u32 latency, l1_max_latency = 0, l1_switch_latency = 0, l0s_latency_up = 0, l0s_latency_dw = 0; + bool aspm_disable = 0; struct aspm_latency *acceptable; struct pcie_link_state *link; @@ -447,19 +448,35 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint) link = endpoint->bus->self->link_state; acceptable = &link->acceptable[PCI_FUNC(endpoint->devfn)]; +#define aspm_info(device, type, down, up) \ + if (!aspm_disable) \ + { \ + pr_cont("pci %s: ASPM latency exceeded, disabling: %s:%s-%s", \ + pci_name(device), type, pci_name(down), pci_name(up)); \ + aspm_disable = 1; \ + } \ + else \ + pr_cont(", %s:%s-%s", type, pci_name(down), pci_name(up)); + while (link) { /* Check upstream direction L0s latency */ if (link->aspm_capable & ASPM_STATE_L0S_UP) { l0s_latency_up += link->latency_up.l0s; if (l0s_latency_up > acceptable->l0s) + { link->aspm_capable &= ~ASPM_STATE_L0S_UP; + aspm_info(endpoint, "L0s-up", link->downstream, link->pdev); + } } /* Check downstream direction L0s latency */ if (link->aspm_capable & ASPM_STATE_L0S_DW) { l0s_latency_dw += link->latency_dw.l0s; if (l0s_latency_dw > acceptable->l0s) + { link->aspm_capable &= ~ASPM_STATE_L0S_DW; + aspm_info(endpoint, "L0s-dw", link->downstream, link->pdev); + } } /* @@ -482,12 +499,18 @@ static void pcie_aspm_check_latency(struct pci_dev *endpoint) latency = max_t(u32, link->latency_up.l1, link->latency_dw.l1); l1_max_latency = max_t(u32, latency, l1_max_latency); if (l1_max_latency + l1_switch_latency > acceptable->l1) + { link->aspm_capable &= ~ASPM_STATE_L1; + aspm_info(endpoint, "L1", link->downstream, link->pdev); + } l1_switch_latency += 1000; } link = link->parent; } + if (aspm_disable) + pr_cont("\n"); +#undef aspm_info } /* -- 2.29.1