@@ -2110,6 +2110,17 @@ static void combine_coordinates(struct access_coordinate *c1,
c1->read_latency += c2->read_latency;
}
+static bool coordinates_valid(struct access_coordinate *c)
+{
+ return c->read_bandwidth && c->write_bandwidth &&
+ c->read_latency && c->write_latency;
+}
+
+static bool parent_port_is_cxl_root(struct cxl_port *port)
+{
+ return is_cxl_root(to_cxl_port(port->dev.parent));
+}
+
/**
* cxl_endpoint_get_perf_coordinates - Retrieve performance numbers stored in dports
* of CXL path
@@ -2133,23 +2144,22 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
if (!is_cxl_endpoint(port))
return -EINVAL;
- dport = iter->parent_dport;
-
/*
- * Exit the loop when the parent port of the current port is cxl root.
- * The iterative loop starts at the endpoint and gathers the
- * latency of the CXL link from the current iter to the next downstream
- * port each iteration. If the parent is cxl root then there is
- * nothing to gather.
+ * Exit the loop when the parent port of the current iter port is cxl
+ * root. The iterative loop starts at the endpoint and gathers the
+ * latency of the CXL link from the current device/port to the connected
+ * downstream port each iteration.
*/
- while (!is_cxl_root(to_cxl_port(iter->dev.parent))) {
+ do {
+ dport = iter->parent_dport;
+ if (!coordinates_valid(&dport->coord))
+ return -EINVAL;
combine_coordinates(&c, &dport->coord);
c.write_latency += dport->link_latency;
c.read_latency += dport->link_latency;
iter = to_cxl_port(iter->dev.parent);
- dport = iter->parent_dport;
- }
+ } while (!parent_port_is_cxl_root(iter));
/* Get the calculated PCI paths bandwidth */
pdev = to_pci_dev(port->uport_dev->parent);