Commit 001c5d19 authored by Dave Jiang's avatar Dave Jiang
Browse files

cxl: Consolidate dport access_coordinate ->hb_coord and ->sw_coord into ->coord



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: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: default avatarDavidlohr Bueso <dave@stgolabs.net>
Reviewed-by: default avatarDan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/r/20240403154844.3403859-5-dave.jiang@intel.com


Signed-off-by: default avatarDave Jiang <dave.jiang@intel.com>
parent 51293c56
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)
+47 −27
Original line number Diff line number Diff line
@@ -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,7 +88,7 @@ static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg,
	return 0;
}

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)
{
	switch (access) {
@@ -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,12 +488,13 @@ 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);
			}
		}
	}

	return 0;
}
@@ -502,14 +514,7 @@ void cxl_switch_parse_cdat(struct cxl_port *port)
}
EXPORT_SYMBOL_NS_GPL(cxl_switch_parse_cdat, CXL);

/**
 * cxl_coordinates_combine - Combine the two input coordinates
 *
 * @out: Output coordinate of c1 and c2 combined
 * @c1: input coordinates
 * @c2: input coordinates
 */
void cxl_coordinates_combine(struct access_coordinate *out,
static void __cxl_coordinates_combine(struct access_coordinate *out,
				      struct access_coordinate *c1,
				      struct access_coordinate *c2)
{
@@ -524,6 +529,21 @@ void cxl_coordinates_combine(struct access_coordinate *out,
		out->read_latency = c1->read_latency + c2->read_latency;
}

/**
 * cxl_coordinates_combine - Combine the two input coordinates
 *
 * @out: Output coordinate of c1 and c2 combined
 * @c1: input coordinates
 * @c2: input coordinates
 */
void cxl_coordinates_combine(struct access_coordinate *out,
			     struct access_coordinate *c1,
			     struct access_coordinate *c2)
{
	for (int i = 0; i < ACCESS_COORDINATE_MAX; i++)
		__cxl_coordinates_combine(&out[i], &c1[i], &c2[i]);
}

MODULE_IMPORT_NS(CXL);

void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
@@ -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;
	}
}

+37 −11
Original line number Diff line number Diff line
@@ -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 = {
	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;
}
+2 −4
Original line number Diff line number Diff line
@@ -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;
};

+1 −1
Original line number Diff line number Diff line
@@ -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;
};

Loading