diff mbox series

[3/3,RFC] PCI/ASPM: Print L1/L0s latency messages per endpoint

Message ID 20201024205548.1837770-3-ian.kumlien@gmail.com
State New
Delegated to: Bjorn Helgaas
Headers show
Series [1/3] PCI/ASPM: Use the path max in L1 ASPM latency check | expand

Commit Message

Ian Kumlien Oct. 24, 2020, 8:55 p.m. UTC
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(+)
diff mbox series

Patch

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
 }
 
 /*