Skip to content

Commit 863027d

Browse files
davejiangdjbw
authored andcommitted
cxl: Split out host bridge access coordinates
The difference between access class 0 and access class 1 for 'struct access_coordinate', if any, is that class 0 is for the distance from the target to the closest initiator and that class 1 is for the distance from the target to the closest CPU. For CXL memory, the nearest initiator may not necessarily be a CPU node. The performance path from the CXL endpoint to the host bridge should remain the same. However, the numbers extracted and stored from HMAT is the difference for the two access classes. Split out the performance numbers for the host bridge (generic target) from the calculation of the entire path in order to allow calculation of both access classes for a CXL region. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Tested-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/20240308220055.2172956-7-dave.jiang@intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 032f7b3 commit 863027d

File tree

3 files changed

+56
-9
lines changed

3 files changed

+56
-9
lines changed

drivers/cxl/core/cdat.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -162,15 +162,22 @@ static int cxl_cdat_endpoint_process(struct cxl_port *port,
162162
static int cxl_port_perf_data_calculate(struct cxl_port *port,
163163
struct xarray *dsmas_xa)
164164
{
165-
struct access_coordinate c;
165+
struct access_coordinate ep_c;
166+
struct access_coordinate coord[ACCESS_COORDINATE_MAX];
166167
struct dsmas_entry *dent;
167168
int valid_entries = 0;
168169
unsigned long index;
169170
int rc;
170171

171-
rc = cxl_endpoint_get_perf_coordinates(port, &c);
172+
rc = cxl_endpoint_get_perf_coordinates(port, &ep_c);
172173
if (rc) {
173-
dev_dbg(&port->dev, "Failed to retrieve perf coordinates.\n");
174+
dev_dbg(&port->dev, "Failed to retrieve ep perf coordinates.\n");
175+
return rc;
176+
}
177+
178+
rc = cxl_hb_get_perf_coordinates(port, coord);
179+
if (rc) {
180+
dev_dbg(&port->dev, "Failed to retrieve hb perf coordinates.\n");
174181
return rc;
175182
}
176183

@@ -185,10 +192,19 @@ static int cxl_port_perf_data_calculate(struct cxl_port *port,
185192
xa_for_each(dsmas_xa, index, dent) {
186193
int qos_class;
187194

188-
cxl_coordinates_combine(&dent->coord, &dent->coord, &c);
195+
cxl_coordinates_combine(&dent->coord, &dent->coord, &ep_c);
196+
/*
197+
* Keeping the host bridge coordinates separate from the dsmas
198+
* coordinates in order to allow calculation of access class
199+
* 0 and 1 for region later.
200+
*/
201+
cxl_coordinates_combine(&coord[ACCESS_COORDINATE_LOCAL],
202+
&coord[ACCESS_COORDINATE_LOCAL],
203+
&dent->coord);
189204
dent->entries = 1;
190-
rc = cxl_root->ops->qos_class(cxl_root, &dent->coord, 1,
191-
&qos_class);
205+
rc = cxl_root->ops->qos_class(cxl_root,
206+
&coord[ACCESS_COORDINATE_LOCAL],
207+
1, &qos_class);
192208
if (rc != 1)
193209
continue;
194210

drivers/cxl/core/port.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2096,6 +2096,38 @@ bool schedule_cxl_memdev_detach(struct cxl_memdev *cxlmd)
20962096
}
20972097
EXPORT_SYMBOL_NS_GPL(schedule_cxl_memdev_detach, CXL);
20982098

2099+
/**
2100+
* cxl_hb_get_perf_coordinates - Retrieve performance numbers between initiator
2101+
* and host bridge
2102+
*
2103+
* @port: endpoint cxl_port
2104+
* @coord: output access coordinates
2105+
*
2106+
* Return: errno on failure, 0 on success.
2107+
*/
2108+
int cxl_hb_get_perf_coordinates(struct cxl_port *port,
2109+
struct access_coordinate *coord)
2110+
{
2111+
struct cxl_port *iter = port;
2112+
struct cxl_dport *dport;
2113+
2114+
if (!is_cxl_endpoint(port))
2115+
return -EINVAL;
2116+
2117+
dport = iter->parent_dport;
2118+
while (iter && !is_cxl_root(to_cxl_port(iter->dev.parent))) {
2119+
iter = to_cxl_port(iter->dev.parent);
2120+
dport = iter->parent_dport;
2121+
}
2122+
2123+
coord[ACCESS_COORDINATE_LOCAL] =
2124+
dport->hb_coord[ACCESS_COORDINATE_LOCAL];
2125+
coord[ACCESS_COORDINATE_CPU] =
2126+
dport->hb_coord[ACCESS_COORDINATE_CPU];
2127+
2128+
return 0;
2129+
}
2130+
20992131
/**
21002132
* cxl_endpoint_get_perf_coordinates - Retrieve performance numbers stored in dports
21012133
* of CXL path
@@ -2137,9 +2169,6 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
21372169
dport = iter->parent_dport;
21382170
}
21392171

2140-
/* Augment with the generic port (host bridge) perf data */
2141-
cxl_coordinates_combine(&c, &c, &dport->hb_coord[ACCESS_COORDINATE_LOCAL]);
2142-
21432172
/* Get the calculated PCI paths bandwidth */
21442173
pdev = to_pci_dev(port->uport_dev->parent);
21452174
bw = pcie_bandwidth_available(pdev, NULL, NULL, NULL);

drivers/cxl/cxl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,8 @@ void cxl_switch_parse_cdat(struct cxl_port *port);
879879

880880
int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
881881
struct access_coordinate *coord);
882+
int cxl_hb_get_perf_coordinates(struct cxl_port *port,
883+
struct access_coordinate *coord);
882884

883885
void cxl_memdev_update_perf(struct cxl_memdev *cxlmd);
884886

0 commit comments

Comments
 (0)