cxl: Consolidate dport access_coordinate ->hb_coord and ->sw_coord into ->coord
authorDave Jiang <dave.jiang@intel.com>
Wed, 3 Apr 2024 15:47:15 +0000 (08:47 -0700)
committerDave Jiang <dave.jiang@intel.com>
Mon, 8 Apr 2024 15:25:21 +0000 (08:25 -0700)
The driver stores access_coordinate for host bridge in ->hb_coord and
switch CDAT access_coordinate in ->sw_coord. Since neither of these
access_coordinate clobber each other, the variable name can be consolidated
into ->coord to simplify the code.

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/r/20240403154844.3403859-5-dave.jiang@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
drivers/cxl/acpi.c
drivers/cxl/core/cdat.c
drivers/cxl/core/port.c
drivers/cxl/cxl.h
drivers/cxl/cxlmem.h
tools/testing/cxl/test/cxl.c

index 566c387d43852da5934f7b3d0fa7da9e493b4d94..cb8c155a2c9b3dbdcbf00f198c5783b9559f8a89 100644 (file)
@@ -529,7 +529,7 @@ static int get_genport_coordinates(struct device *dev, struct cxl_dport *dport)
        if (kstrtou32(acpi_device_uid(hb), 0, &uid))
                return -EINVAL;
 
-       return acpi_get_genport_coordinates(uid, dport->hb_coord);
+       return acpi_get_genport_coordinates(uid, dport->coord);
 }
 
 static int add_host_bridge_dport(struct device *match, void *arg)
index f66b493b5d3c5b70348d4dcbb93a95a4383bd2a1..bb83867d9fec985634bb9b03652f1eaa34fc8a22 100644 (file)
@@ -14,7 +14,7 @@
 struct dsmas_entry {
        struct range dpa_range;
        u8 handle;
-       struct access_coordinate coord;
+       struct access_coordinate coord[ACCESS_COORDINATE_MAX];
 
        int entries;
        int qos_class;
@@ -88,8 +88,8 @@ static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg,
        return 0;
 }
 
-static void cxl_access_coordinate_set(struct access_coordinate *coord,
-                                     int access, unsigned int val)
+static void __cxl_access_coordinate_set(struct access_coordinate *coord,
+                                       int access, unsigned int val)
 {
        switch (access) {
        case ACPI_HMAT_ACCESS_LATENCY:
@@ -115,6 +115,13 @@ static void cxl_access_coordinate_set(struct access_coordinate *coord,
        }
 }
 
+static void cxl_access_coordinate_set(struct access_coordinate *coord,
+                                     int access, unsigned int val)
+{
+       for (int i = 0; i < ACCESS_COORDINATE_MAX; i++)
+               __cxl_access_coordinate_set(&coord[i], access, val);
+}
+
 static int cdat_dslbis_handler(union acpi_subtable_headers *header, void *arg,
                               const unsigned long end)
 {
@@ -156,7 +163,7 @@ static int cdat_dslbis_handler(union acpi_subtable_headers *header, void *arg,
        val = cdat_normalize(le16_to_cpu(le_val), le64_to_cpu(le_base),
                             dslbis->data_type);
 
-       cxl_access_coordinate_set(&dent->coord, dslbis->data_type, val);
+       cxl_access_coordinate_set(dent->coord, dslbis->data_type, val);
 
        return 0;
 }
@@ -190,13 +197,13 @@ static int cxl_cdat_endpoint_process(struct cxl_port *port,
 static int cxl_port_perf_data_calculate(struct cxl_port *port,
                                        struct xarray *dsmas_xa)
 {
-       struct access_coordinate ep_c;
+       struct access_coordinate ep_c[ACCESS_COORDINATE_MAX];
        struct dsmas_entry *dent;
        int valid_entries = 0;
        unsigned long index;
        int rc;
 
-       rc = cxl_endpoint_get_perf_coordinates(port, &ep_c);
+       rc = cxl_endpoint_get_perf_coordinates(port, ep_c);
        if (rc) {
                dev_dbg(&port->dev, "Failed to retrieve ep perf coordinates.\n");
                return rc;
@@ -213,10 +220,11 @@ static int cxl_port_perf_data_calculate(struct cxl_port *port,
        xa_for_each(dsmas_xa, index, dent) {
                int qos_class;
 
-               cxl_coordinates_combine(&dent->coord, &dent->coord, &ep_c);
+               cxl_coordinates_combine(dent->coord, dent->coord, ep_c);
                dent->entries = 1;
-               rc = cxl_root->ops->qos_class(cxl_root, &dent->coord, 1,
-                                             &qos_class);
+               rc = cxl_root->ops->qos_class(cxl_root,
+                                             &dent->coord[ACCESS_COORDINATE_CPU],
+                                             1, &qos_class);
                if (rc != 1)
                        continue;
 
@@ -233,14 +241,17 @@ static int cxl_port_perf_data_calculate(struct cxl_port *port,
 static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
                              struct cxl_dpa_perf *dpa_perf)
 {
+       for (int i = 0; i < ACCESS_COORDINATE_MAX; i++)
+               dpa_perf->coord[i] = dent->coord[i];
        dpa_perf->dpa_range = dent->dpa_range;
-       dpa_perf->coord = dent->coord;
        dpa_perf->qos_class = dent->qos_class;
        dev_dbg(dev,
                "DSMAS: dpa: %#llx qos: %d read_bw: %d write_bw %d read_lat: %d write_lat: %d\n",
                dent->dpa_range.start, dpa_perf->qos_class,
-               dent->coord.read_bandwidth, dent->coord.write_bandwidth,
-               dent->coord.read_latency, dent->coord.write_latency);
+               dent->coord[ACCESS_COORDINATE_CPU].read_bandwidth,
+               dent->coord[ACCESS_COORDINATE_CPU].write_bandwidth,
+               dent->coord[ACCESS_COORDINATE_CPU].read_latency,
+               dent->coord[ACCESS_COORDINATE_CPU].write_latency);
 }
 
 static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
@@ -477,10 +488,11 @@ static int cdat_sslbis_handler(union acpi_subtable_headers *header, void *arg,
 
                xa_for_each(&port->dports, index, dport) {
                        if (dsp_id == ACPI_CDAT_SSLBIS_ANY_PORT ||
-                           dsp_id == dport->port_id)
-                               cxl_access_coordinate_set(&dport->sw_coord,
+                           dsp_id == dport->port_id) {
+                               cxl_access_coordinate_set(dport->coord,
                                                          sslbis->data_type,
                                                          val);
+                       }
                }
        }
 
@@ -502,6 +514,21 @@ void cxl_switch_parse_cdat(struct cxl_port *port)
 }
 EXPORT_SYMBOL_NS_GPL(cxl_switch_parse_cdat, CXL);
 
+static void __cxl_coordinates_combine(struct access_coordinate *out,
+                                     struct access_coordinate *c1,
+                                     struct access_coordinate *c2)
+{
+               if (c1->write_bandwidth && c2->write_bandwidth)
+                       out->write_bandwidth = min(c1->write_bandwidth,
+                                                  c2->write_bandwidth);
+               out->write_latency = c1->write_latency + c2->write_latency;
+
+               if (c1->read_bandwidth && c2->read_bandwidth)
+                       out->read_bandwidth = min(c1->read_bandwidth,
+                                                 c2->read_bandwidth);
+               out->read_latency = c1->read_latency + c2->read_latency;
+}
+
 /**
  * cxl_coordinates_combine - Combine the two input coordinates
  *
@@ -513,15 +540,8 @@ void cxl_coordinates_combine(struct access_coordinate *out,
                             struct access_coordinate *c1,
                             struct access_coordinate *c2)
 {
-               if (c1->write_bandwidth && c2->write_bandwidth)
-                       out->write_bandwidth = min(c1->write_bandwidth,
-                                                  c2->write_bandwidth);
-               out->write_latency = c1->write_latency + c2->write_latency;
-
-               if (c1->read_bandwidth && c2->read_bandwidth)
-                       out->read_bandwidth = min(c1->read_bandwidth,
-                                                 c2->read_bandwidth);
-               out->read_latency = c1->read_latency + c2->read_latency;
+       for (int i = 0; i < ACCESS_COORDINATE_MAX; i++)
+               __cxl_coordinates_combine(&out[i], &c1[i], &c2[i]);
 }
 
 MODULE_IMPORT_NS(CXL);
@@ -558,12 +578,12 @@ void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
                /* Get total bandwidth and the worst latency for the cxl region */
                cxlr->coord[i].read_latency = max_t(unsigned int,
                                                    cxlr->coord[i].read_latency,
-                                                   perf->coord.read_latency);
+                                                   perf->coord[i].read_latency);
                cxlr->coord[i].write_latency = max_t(unsigned int,
                                                     cxlr->coord[i].write_latency,
-                                                    perf->coord.write_latency);
-               cxlr->coord[i].read_bandwidth += perf->coord.read_bandwidth;
-               cxlr->coord[i].write_bandwidth += perf->coord.write_bandwidth;
+                                                    perf->coord[i].write_latency);
+               cxlr->coord[i].read_bandwidth += perf->coord[i].read_bandwidth;
+               cxlr->coord[i].write_bandwidth += perf->coord[i].write_bandwidth;
        }
 }
 
index c7c00eb373af690bbdb28097ff763816a60ffdca..801c4018a1ddeb7d6bcda21f9be698e56db7d721 100644 (file)
@@ -2133,6 +2133,29 @@ bool schedule_cxl_memdev_detach(struct cxl_memdev *cxlmd)
 }
 EXPORT_SYMBOL_NS_GPL(schedule_cxl_memdev_detach, CXL);
 
+static void add_latency(struct access_coordinate *c, long latency)
+{
+       for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) {
+               c[i].write_latency += latency;
+               c[i].read_latency += latency;
+       }
+}
+
+static void set_min_bandwidth(struct access_coordinate *c, unsigned int bw)
+{
+       for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) {
+               c[i].write_bandwidth = min(c[i].write_bandwidth, bw);
+               c[i].read_bandwidth = min(c[i].read_bandwidth, bw);
+       }
+}
+
+static void set_access_coordinates(struct access_coordinate *out,
+                                  struct access_coordinate *in)
+{
+       for (int i = 0; i < ACCESS_COORDINATE_MAX; i++)
+               out[i] = in[i];
+}
+
 static bool parent_port_is_cxl_root(struct cxl_port *port)
 {
        return is_cxl_root(to_cxl_port(port->dev.parent));
@@ -2149,9 +2172,15 @@ static bool parent_port_is_cxl_root(struct cxl_port *port)
 int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
                                      struct access_coordinate *coord)
 {
-       struct access_coordinate c = {
-               .read_bandwidth = UINT_MAX,
-               .write_bandwidth = UINT_MAX,
+       struct access_coordinate c[] = {
+               {
+                       .read_bandwidth = UINT_MAX,
+                       .write_bandwidth = UINT_MAX,
+               },
+               {
+                       .read_bandwidth = UINT_MAX,
+                       .write_bandwidth = UINT_MAX,
+               },
        };
        struct cxl_port *iter = port;
        struct cxl_dport *dport;
@@ -2178,14 +2207,13 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
                 * have CDAT and therefore needs to be skipped.
                 */
                if (!is_cxl_root)
-                       cxl_coordinates_combine(&c, &c, &dport->sw_coord);
-               c.write_latency += dport->link_latency;
-               c.read_latency += dport->link_latency;
+                       cxl_coordinates_combine(c, c, dport->coord);
+               add_latency(c, dport->link_latency);
        } while (!is_cxl_root);
 
        dport = iter->parent_dport;
        /* Retrieve HB coords */
-       cxl_coordinates_combine(&c, &c, dport->hb_coord);
+       cxl_coordinates_combine(c, c, dport->coord);
 
        /* Get the calculated PCI paths bandwidth */
        pdev = to_pci_dev(port->uport_dev->parent);
@@ -2194,10 +2222,8 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
                return -ENXIO;
        bw /= BITS_PER_BYTE;
 
-       c.write_bandwidth = min(c.write_bandwidth, bw);
-       c.read_bandwidth = min(c.read_bandwidth, bw);
-
-       *coord = c;
+       set_min_bandwidth(c, bw);
+       set_access_coordinates(coord, c);
 
        return 0;
 }
index ed02373ce3d9051b6179699162dc97531cf968e6..036d17db68e0068752277adf0e5b56c7b526e566 100644 (file)
@@ -663,8 +663,7 @@ struct cxl_rcrb_info {
  * @rch: Indicate whether this dport was enumerated in RCH or VH mode
  * @port: reference to cxl_port that contains this downstream port
  * @regs: Dport parsed register blocks
- * @sw_coord: access coordinates (performance) for switch from CDAT
- * @hb_coord: access coordinates (performance) from ACPI generic port (host bridge)
+ * @coord: access coordinates (bandwidth and latency performance attributes)
  * @link_latency: calculated PCIe downstream latency
  */
 struct cxl_dport {
@@ -675,8 +674,7 @@ struct cxl_dport {
        bool rch;
        struct cxl_port *port;
        struct cxl_regs regs;
-       struct access_coordinate sw_coord;
-       struct access_coordinate hb_coord[ACCESS_COORDINATE_MAX];
+       struct access_coordinate coord[ACCESS_COORDINATE_MAX];
        long link_latency;
 };
 
index 20fb3b35e89e0473ee8ad42dcd17407086fb8cdb..36cee9c30cebd20488ec5afd216187ef82497e54 100644 (file)
@@ -401,7 +401,7 @@ enum cxl_devtype {
  */
 struct cxl_dpa_perf {
        struct range dpa_range;
-       struct access_coordinate coord;
+       struct access_coordinate coord[ACCESS_COORDINATE_MAX];
        int qos_class;
 };
 
index 908e0d0839369c2e41f090bddc2e9a9b9121b4c9..61c69297e7978fceed700be3ad43a7a870d20de2 100644 (file)
@@ -986,10 +986,12 @@ static void dpa_perf_setup(struct cxl_port *endpoint, struct range *range,
 {
        dpa_perf->qos_class = FAKE_QTG_ID;
        dpa_perf->dpa_range = *range;
-       dpa_perf->coord.read_latency = 500;
-       dpa_perf->coord.write_latency = 500;
-       dpa_perf->coord.read_bandwidth = 1000;
-       dpa_perf->coord.write_bandwidth = 1000;
+       for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) {
+               dpa_perf->coord[i].read_latency = 500;
+               dpa_perf->coord[i].write_latency = 500;
+               dpa_perf->coord[i].read_bandwidth = 1000;
+               dpa_perf->coord[i].write_bandwidth = 1000;
+       }
 }
 
 static void mock_cxl_endpoint_parse_cdat(struct cxl_port *port)