mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 05:02:31 +00:00
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: 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>
This commit is contained in:
parent
51293c565c
commit
001c5d1934
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user