From: Dave Jiang <dave.jiang@intel.com>
To: linux-cxl@vger.kernel.org
Cc: dan.j.williams@intel.com, ira.weiny@intel.com,
vishal.l.verma@intel.com, alison.schofield@intel.com,
Jonathan.Cameron@huawei.com, dave@stgolabs.net,
Jonathan Cameron <Jonathan.Cameron@Huawei.com>
Subject: [PATCH] cxl: Calculate region bandwidth of targets with shared upstream link
Date: Tue, 9 Apr 2024 11:50:23 -0700 [thread overview]
Message-ID: <20240409185023.151885-1-dave.jiang@intel.com> (raw)
For a topology where multiple targets sharing the same upstream link, the
bandwidth must be divided amongst all the sharing targets.
cxl_rr->num_targets keeps track of the numbers of targets sharing the same
upstream port. The bandwidth should be divided amongst all those targets.
Take the min of that bandwidth and the whole path bandwidth as the actual
bandwidth for each of the target.
Suggested-by: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
Link: https://lore.kernel.org/linux-cxl/20240405143242.0000363a@Huawei.com/
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
drivers/cxl/core/cdat.c | 24 ++++++++++++++++++++++--
drivers/cxl/core/core.h | 3 +++
drivers/cxl/core/pci.c | 17 +++++++++++++++++
drivers/cxl/core/region.c | 10 ++++++++++
4 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c
index 4b717d2f5a9d..af5c02ab49e3 100644
--- a/drivers/cxl/core/cdat.c
+++ b/drivers/cxl/core/cdat.c
@@ -551,7 +551,10 @@ void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
.start = cxled->dpa_res->start,
.end = cxled->dpa_res->end,
};
+ struct cxl_port *port = cxlmd->endpoint;
+ struct pci_dev *pdev = to_pci_dev(port->uport_dev);
struct cxl_dpa_perf *perf;
+ int usp_bw, targets;
switch (cxlr->mode) {
case CXL_DECODER_RAM:
@@ -569,6 +572,19 @@ void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
if (!range_contains(&perf->dpa_range, &dpa))
return;
+ usp_bw = cxl_pci_get_bandwidth(pdev);
+ if (usp_bw < 0)
+ return;
+
+ /*
+ * Get the number of targets that share the upstream link. If there are more
+ * than 1 shared targets, the upstream port bandwidth is divided equally
+ * amongst all the targets.
+ */
+ targets = cxl_region_targets(port, cxlr);
+ if (!targets)
+ return;
+
for (int i = 0; i < ACCESS_COORDINATE_MAX; i++) {
/* Get total bandwidth and the worst latency for the cxl region */
cxlr->coord[i].read_latency = max_t(unsigned int,
@@ -577,8 +593,12 @@ void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
cxlr->coord[i].write_latency = max_t(unsigned int,
cxlr->coord[i].write_latency,
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;
+ cxlr->coord[i].read_bandwidth += min_t(unsigned int,
+ perf->coord[i].read_bandwidth,
+ usp_bw / targets);
+ cxlr->coord[i].write_bandwidth += min_t(unsigned int,
+ perf->coord[i].write_bandwidth,
+ usp_bw / targets);
}
}
diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h
index bc5a95665aa0..3eccd5ea1ae4 100644
--- a/drivers/cxl/core/core.h
+++ b/drivers/cxl/core/core.h
@@ -89,9 +89,12 @@ enum cxl_poison_trace_type {
};
long cxl_pci_get_latency(struct pci_dev *pdev);
+int cxl_pci_get_bandwidth(struct pci_dev *pdev);
int cxl_update_hmat_access_coordinates(int nid, struct cxl_region *cxlr,
enum access_coordinate_class access);
bool cxl_need_node_perf_attrs_update(int nid);
+int cxl_region_targets(struct cxl_port *port, struct cxl_region *cxlr);
+
#endif /* __CXL_CORE_H__ */
diff --git a/drivers/cxl/core/pci.c b/drivers/cxl/core/pci.c
index 0df09bd79408..8fbfc5115cd0 100644
--- a/drivers/cxl/core/pci.c
+++ b/drivers/cxl/core/pci.c
@@ -1045,3 +1045,20 @@ long cxl_pci_get_latency(struct pci_dev *pdev)
return cxl_flit_size(pdev) * MEGA / bw;
}
+
+int cxl_pci_get_bandwidth(struct pci_dev *pdev)
+{
+ u16 lnksta;
+ u32 width;
+ int speed;
+
+ speed = pcie_link_speed_mbps(pdev);
+ if (speed < 0)
+ return 0;
+ speed /= BITS_PER_BYTE;
+
+ pcie_capability_read_word(pdev, PCI_EXP_LNKSTA, &lnksta);
+ width = FIELD_GET(PCI_EXP_LNKSTA_NLW, lnksta);
+
+ return speed * width;
+}
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 5c186e0a39b9..9b8bdb01ff0f 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -222,6 +222,16 @@ static struct cxl_region_ref *cxl_rr_load(struct cxl_port *port,
return xa_load(&port->regions, (unsigned long)cxlr);
}
+int cxl_region_targets(struct cxl_port *port, struct cxl_region *cxlr)
+{
+ struct cxl_region_ref *cxl_rr = cxl_rr_load(port, cxlr);
+
+ if (!cxl_rr)
+ return 0;
+
+ return cxl_rr->nr_targets;
+}
+
static int cxl_region_invalidate_memregion(struct cxl_region *cxlr)
{
if (!cpu_cache_has_invalidate_memregion()) {
--
2.44.0
next reply other threads:[~2024-04-09 18:50 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-09 18:50 Dave Jiang [this message]
2024-04-09 22:03 ` [PATCH] cxl: Calculate region bandwidth of targets with shared upstream link Dan Williams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240409185023.151885-1-dave.jiang@intel.com \
--to=dave.jiang@intel.com \
--cc=Jonathan.Cameron@huawei.com \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave@stgolabs.net \
--cc=ira.weiny@intel.com \
--cc=linux-cxl@vger.kernel.org \
--cc=vishal.l.verma@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).