|
9 | 9 | #include "cxlmem.h"
|
10 | 10 | #include "core.h"
|
11 | 11 | #include "cxl.h"
|
| 12 | +#include "core.h" |
12 | 13 |
|
13 | 14 | struct dsmas_entry {
|
14 | 15 | struct range dpa_range;
|
@@ -515,3 +516,67 @@ void cxl_coordinates_combine(struct access_coordinate *out,
|
515 | 516 | }
|
516 | 517 |
|
517 | 518 | 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 | +} |
0 commit comments