@@ -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
}
/*
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@gmail.com> --- drivers/pci/pcie/aspm.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)