Skip to content

Commit 3d9f4a1

Browse files
davejiangdjbw
authored andcommitted
cxl/region: Calculate performance data for a region
Calculate and store the performance data for a CXL region. Find the worst read and write latency for all the included ranges from each of the devices that attributes to the region and designate that as the latency data. Sum all the read and write bandwidth data for each of the device region and that is the total bandwidth for the region. The perf list is expected to be constructed before the endpoint decoders are registered and thus there should be no early reading of the entries from the region assemble action. The calling of the region qos calculate function is under the protection of cxl_dpa_rwsem and will ensure that all DPA associated work has completed. 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-10-dave.jiang@intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 3d8be8b commit 3d9f4a1

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

drivers/cxl/core/cdat.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "cxlmem.h"
1010
#include "core.h"
1111
#include "cxl.h"
12+
#include "core.h"
1213

1314
struct dsmas_entry {
1415
struct range dpa_range;
@@ -515,3 +516,67 @@ void cxl_coordinates_combine(struct access_coordinate *out,
515516
}
516517

517518
MODULE_IMPORT_NS(CXL);
519+
520+
void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
521+
struct cxl_endpoint_decoder *cxled)
522+
{
523+
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
524+
struct cxl_port *port = cxlmd->endpoint;
525+
struct cxl_dev_state *cxlds = cxlmd->cxlds;
526+
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
527+
struct access_coordinate hb_coord[ACCESS_COORDINATE_MAX];
528+
struct access_coordinate coord;
529+
struct range dpa = {
530+
.start = cxled->dpa_res->start,
531+
.end = cxled->dpa_res->end,
532+
};
533+
struct cxl_dpa_perf *perf;
534+
int rc;
535+
536+
switch (cxlr->mode) {
537+
case CXL_DECODER_RAM:
538+
perf = &mds->ram_perf;
539+
break;
540+
case CXL_DECODER_PMEM:
541+
perf = &mds->pmem_perf;
542+
break;
543+
default:
544+
return;
545+
}
546+
547+
lockdep_assert_held(&cxl_dpa_rwsem);
548+
549+
if (!range_contains(&perf->dpa_range, &dpa))
550+
return;
551+
552+
rc = cxl_hb_get_perf_coordinates(port, hb_coord);
553+
if (rc) {
554+
dev_dbg(&port->dev, "Failed to retrieve hb perf coordinates.\n");
555+
return;
556+
}
557+
558+
for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) {
559+
/* Pickup the host bridge coords */
560+
cxl_coordinates_combine(&coord, &hb_coord[i], &perf->coord);
561+
562+
/* Get total bandwidth and the worst latency for the cxl region */
563+
cxlr->coord[i].read_latency = max_t(unsigned int,
564+
cxlr->coord[i].read_latency,
565+
coord.read_latency);
566+
cxlr->coord[i].write_latency = max_t(unsigned int,
567+
cxlr->coord[i].write_latency,
568+
coord.write_latency);
569+
cxlr->coord[i].read_bandwidth += coord.read_bandwidth;
570+
cxlr->coord[i].write_bandwidth += coord.write_bandwidth;
571+
572+
/*
573+
* Convert latency to nanosec from picosec to be consistent
574+
* with the resulting latency coordinates computed by the
575+
* HMAT_REPORTING code.
576+
*/
577+
cxlr->coord[i].read_latency =
578+
DIV_ROUND_UP(cxlr->coord[i].read_latency, 1000);
579+
cxlr->coord[i].write_latency =
580+
DIV_ROUND_UP(cxlr->coord[i].write_latency, 1000);
581+
}
582+
}

drivers/cxl/core/region.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,8 @@ static int cxl_region_attach(struct cxl_region *cxlr,
17521752
return -EINVAL;
17531753
}
17541754

1755+
cxl_region_perf_data_calculate(cxlr, cxled);
1756+
17551757
if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) {
17561758
int i;
17571759

drivers/cxl/cxl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ struct cxl_region_params {
517517
* @cxlr_pmem: (for pmem regions) cached copy of the nvdimm bridge
518518
* @flags: Region state flags
519519
* @params: active + config params for the region
520+
* @coord: QoS access coordinates for the region
520521
*/
521522
struct cxl_region {
522523
struct device dev;
@@ -527,6 +528,7 @@ struct cxl_region {
527528
struct cxl_pmem_region *cxlr_pmem;
528529
unsigned long flags;
529530
struct cxl_region_params params;
531+
struct access_coordinate coord[ACCESS_COORDINATE_MAX];
530532
};
531533

532534
struct cxl_nvdimm_bridge {
@@ -881,6 +883,8 @@ int cxl_endpoint_get_perf_coordinates(struct cxl_port *port,
881883
struct access_coordinate *coord);
882884
int cxl_hb_get_perf_coordinates(struct cxl_port *port,
883885
struct access_coordinate *coord);
886+
void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
887+
struct cxl_endpoint_decoder *cxled);
884888

885889
void cxl_memdev_update_perf(struct cxl_memdev *cxlmd);
886890

0 commit comments

Comments
 (0)