From: Huang Ying <ying.huang@intel.com>
To: Dan Williams <dan.j.williams@intel.com>,
Dave Jiang <dave.jiang@intel.com>
Cc: linux-cxl@vger.kernel.org, linux-kernel@vger.kernel.org,
Huang Ying <ying.huang@intel.com>,
Gregory Price <gourry@gourry.net>,
Davidlohr Bueso <dave@stgolabs.net>,
Jonathan Cameron <jonathan.cameron@huawei.com>,
Alison Schofield <alison.schofield@intel.com>,
Vishal Verma <vishal.l.verma@intel.com>,
Ira Weiny <ira.weiny@intel.com>,
Alejandro Lucero <alucerop@amd.com>,
Ben Cheatham <benjamin.cheatham@amd.com>
Subject: [PATCH 3/5] cxl: Separate coherence from target type
Date: Tue, 15 Oct 2024 14:57:11 +0800 [thread overview]
Message-ID: <20241015065713.308671-4-ying.huang@intel.com> (raw)
In-Reply-To: <20241015065713.308671-1-ying.huang@intel.com>
Previously, target type (expander or accelerator) and
coherence (HOSTONLY (HDM-H) or DEV (HDM-D/DB)) are synonym. So
current kernel uses target type to designate coherence too. However,
it's possible for expanders to use HDM-DB now. So, the patch
separates coherence from target type.
Accordingly, the patch sets the HOSTONLY field of decoder ctrl
register (CXL_HDM_DECODER0_CTRL_HOSTONLY) according to the coherence
instead of the target type.
Because we cannot determine the coherence of decoders via target type,
the patch lets accelerator/expander device drivers specify coherence
explicitly via newly added coherence field in struct cxl_dev_state.
The coherence of each end points in a region needs to be same. So,
the patch records the coherence of the first added end point in struct
region. Then, it checks whether the coherence of all other end points
is same.
Signed-off-by: "Huang, Ying" <ying.huang@intel.com>
Reviewed-by: Gregory Price <gourry@gourry.net>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Jonathan Cameron <jonathan.cameron@huawei.com>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Alison Schofield <alison.schofield@intel.com>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: Ira Weiny <ira.weiny@intel.com>
Cc: Alejandro Lucero <alucerop@amd.com>
Cc: Ben Cheatham <benjamin.cheatham@amd.com>
---
drivers/cxl/core/hdm.c | 22 +++++++++++++++-------
drivers/cxl/core/mbox.c | 1 +
drivers/cxl/core/port.c | 1 +
drivers/cxl/core/region.c | 37 ++++++++++++++++++++++++++++++++++---
drivers/cxl/cxl.h | 10 ++++++++++
drivers/cxl/cxlmem.h | 12 ++++++++++++
6 files changed, 73 insertions(+), 10 deletions(-)
diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c
index 57b54ecdb000..478fb6691759 100644
--- a/drivers/cxl/core/hdm.c
+++ b/drivers/cxl/core/hdm.c
@@ -569,10 +569,10 @@ static void cxld_set_interleave(struct cxl_decoder *cxld, u32 *ctrl)
*ctrl |= CXL_HDM_DECODER0_CTRL_COMMIT;
}
-static void cxld_set_type(struct cxl_decoder *cxld, u32 *ctrl)
+static void cxld_set_coherence(struct cxl_decoder *cxld, u32 *ctrl)
{
u32p_replace_bits(ctrl,
- !!(cxld->target_type == CXL_DECODER_EXPANDER),
+ !!(cxld->coherence == CXL_DECODER_HOSTONLYCOH),
CXL_HDM_DECODER0_CTRL_HOSTONLY);
}
@@ -667,7 +667,7 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld)
/* common decoder settings */
ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(cxld->id));
cxld_set_interleave(cxld, &ctrl);
- cxld_set_type(cxld, &ctrl);
+ cxld_set_coherence(cxld, &ctrl);
base = cxld->hpa_range.start;
size = range_len(&cxld->hpa_range);
@@ -846,10 +846,13 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
cxld->flags |= CXL_DECODER_F_ENABLE;
if (ctrl & CXL_HDM_DECODER0_CTRL_LOCK)
cxld->flags |= CXL_DECODER_F_LOCK;
- if (FIELD_GET(CXL_HDM_DECODER0_CTRL_HOSTONLY, ctrl))
+ if (FIELD_GET(CXL_HDM_DECODER0_CTRL_HOSTONLY, ctrl)) {
cxld->target_type = CXL_DECODER_EXPANDER;
- else
+ cxld->coherence = CXL_DECODER_HOSTONLYCOH;
+ } else {
cxld->target_type = CXL_DECODER_ACCEL;
+ cxld->coherence = CXL_DECODER_DEVCOH;
+ }
guard(rwsem_write)(&cxl_region_rwsem);
if (cxld->id != cxl_num_decoders_committed(port)) {
@@ -879,13 +882,18 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
cxld->target_type = CXL_DECODER_EXPANDER;
else
cxld->target_type = CXL_DECODER_ACCEL;
+ if (cxlds->coherence == CXL_DEVCOH_HOSTONLY)
+ cxld->coherence = CXL_DECODER_HOSTONLYCOH;
+ else
+ cxld->coherence = CXL_DECODER_DEVCOH;
} else {
- /* To be overridden by region type at commit time */
+ /* To be overridden by region type/coherence at commit time */
cxld->target_type = CXL_DECODER_EXPANDER;
+ cxld->coherence = CXL_DECODER_HOSTONLYCOH;
}
if (!FIELD_GET(CXL_HDM_DECODER0_CTRL_HOSTONLY, ctrl) &&
- cxld->target_type == CXL_DECODER_EXPANDER) {
+ cxld->coherence == CXL_DECODER_HOSTONLYCOH) {
ctrl |= CXL_HDM_DECODER0_CTRL_HOSTONLY;
writel(ctrl, hdm + CXL_HDM_DECODER0_CTRL_OFFSET(which));
}
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 5175138c4fb7..fb98cd1a8b61 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -1450,6 +1450,7 @@ struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
mds->cxlds.reg_map.host = dev;
mds->cxlds.reg_map.resource = CXL_RESOURCE_NONE;
mds->cxlds.type = CXL_DEVTYPE_CLASSMEM;
+ mds->cxlds.coherence = CXL_DEVCOH_HOSTONLY;
mds->ram_perf.qos_class = CXL_QOS_CLASS_INVALID;
mds->pmem_perf.qos_class = CXL_QOS_CLASS_INVALID;
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index e80b0af3d812..9ebbffcea26a 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1769,6 +1769,7 @@ static int cxl_decoder_init(struct cxl_port *port, struct cxl_decoder *cxld)
cxld->interleave_ways = 1;
cxld->interleave_granularity = PAGE_SIZE;
cxld->target_type = CXL_DECODER_EXPANDER;
+ cxld->coherence = CXL_DECODER_HOSTONLYCOH;
cxld->hpa_range = (struct range) {
.start = 0,
.end = -1,
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
index 036356bc4204..21b877d8582f 100644
--- a/drivers/cxl/core/region.c
+++ b/drivers/cxl/core/region.c
@@ -1005,9 +1005,10 @@ static int cxl_rr_alloc_decoder(struct cxl_port *port, struct cxl_region *cxlr,
}
/*
- * Endpoints should already match the region type, but backstop that
- * assumption with an assertion. Switch-decoders change mapping-type
- * based on what is mapped when they are assigned to a region.
+ * Endpoints should already match the region type/coherence, but
+ * backstop that assumption with an assertion. Switch-decoders change
+ * mapping-type/coherence based on what is mapped when they are assigned
+ * to a region.
*/
dev_WARN_ONCE(&cxlr->dev,
port == cxled_to_port(cxled) &&
@@ -1016,6 +1017,13 @@ static int cxl_rr_alloc_decoder(struct cxl_port *port, struct cxl_region *cxlr,
dev_name(&cxled_to_memdev(cxled)->dev),
dev_name(&cxld->dev), cxld->target_type, cxlr->type);
cxld->target_type = cxlr->type;
+ dev_WARN_ONCE(&cxlr->dev,
+ port == cxled_to_port(cxled) &&
+ cxld->coherence != cxlr->coherence,
+ "%s:%s mismatch decoder coherence %d -> %d\n",
+ dev_name(&cxled_to_memdev(cxled)->dev),
+ dev_name(&cxld->dev), cxld->coherence, cxlr->coherence);
+ cxld->coherence = cxlr->coherence;
cxl_rr->decoder = cxld;
return 0;
}
@@ -1925,6 +1933,29 @@ static int cxl_region_attach(struct cxl_region *cxlr,
return -ENXIO;
}
+ /* Set the coherence of region to that of the first endpoint */
+ if (cxlr->coherence == CXL_DECODER_INVALIDCOH) {
+ unsigned long flags = cxlrd->cxlsd.cxld.flags;
+ enum cxl_decoder_coherence coherence = cxled->cxld.coherence;
+
+ cxlr->coherence = coherence;
+ if ((coherence == CXL_DECODER_HOSTONLYCOH &&
+ !(flags & CXL_DECODER_F_HOSTONLYCOH)) ||
+ (coherence == CXL_DECODER_DEVCOH &&
+ !(flags & CXL_DECODER_F_DEVCOH))) {
+ dev_dbg(&cxlr->dev,
+"%s:%s endpoint coherence: %d isn't supported by root decoder: %#lx\n",
+ dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
+ coherence, flags);
+ return -ENXIO;
+ }
+ } else if (cxled->cxld.coherence != cxlr->coherence) {
+ dev_dbg(&cxlr->dev, "%s:%s coherence mismatch: %d vs %d\n",
+ dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev),
+ cxled->cxld.coherence, cxlr->coherence);
+ return -ENXIO;
+ }
+
if (!cxled->dpa_res) {
dev_dbg(&cxlr->dev, "%s:%s: missing DPA allocation.\n",
dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev));
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index f95101994238..1927a1849d82 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -328,6 +328,12 @@ enum cxl_decoder_type {
CXL_DECODER_EXPANDER = 3,
};
+enum cxl_decoder_coherence {
+ CXL_DECODER_INVALIDCOH,
+ CXL_DECODER_HOSTONLYCOH,
+ CXL_DECODER_DEVCOH,
+};
+
/*
* Current specification goes up to 8, double that seems a reasonable
* software max for the foreseeable future
@@ -344,6 +350,7 @@ enum cxl_decoder_type {
* @interleave_ways: number of cxl_dports in this decode
* @interleave_granularity: data stride per dport
* @target_type: accelerator vs expander (type2 vs type3) selector
+ * @coherence: host only vs device coherence selector
* @region: currently assigned region for this decoder
* @flags: memory type capabilities and locking
* @commit: device/decoder-type specific callback to commit settings to hw
@@ -356,6 +363,7 @@ struct cxl_decoder {
int interleave_ways;
int interleave_granularity;
enum cxl_decoder_type target_type;
+ enum cxl_decoder_coherence coherence;
struct cxl_region *region;
unsigned long flags;
int (*commit)(struct cxl_decoder *cxld);
@@ -517,6 +525,7 @@ struct cxl_region_params {
* @id: This region's id. Id is globally unique across all regions
* @mode: Endpoint decoder allocation / access mode
* @type: Endpoint decoder target type
+ * @coherence: Endpoint decoder coherence
* @cxl_nvb: nvdimm bridge for coordinating @cxlr_pmem setup / shutdown
* @cxlr_pmem: (for pmem regions) cached copy of the nvdimm bridge
* @flags: Region state flags
@@ -530,6 +539,7 @@ struct cxl_region {
int id;
enum cxl_decoder_mode mode;
enum cxl_decoder_type type;
+ enum cxl_decoder_coherence coherence;
struct cxl_nvdimm_bridge *cxl_nvb;
struct cxl_pmem_region *cxlr_pmem;
unsigned long flags;
diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h
index 2a25d1957ddb..f9156c578bde 100644
--- a/drivers/cxl/cxlmem.h
+++ b/drivers/cxl/cxlmem.h
@@ -394,6 +394,16 @@ enum cxl_devtype {
CXL_DEVTYPE_CLASSMEM,
};
+/*
+ * enum cxl_devcoherence - the coherence of the cxl device
+ * @CXL_DEVCOH_DEV - HDM-D (type 2) or HDM-DB (type 2/3)
+ * @CXL_DEVCOH_HOSTONLY - HDM-H (type 3)
+ */
+enum cxl_devcoherence {
+ CXL_DEVCOH_DEV,
+ CXL_DEVCOH_HOSTONLY,
+};
+
/**
* struct cxl_dpa_perf - DPA performance property entry
* @dpa_range: range for DPA address
@@ -427,6 +437,7 @@ struct cxl_dpa_perf {
* @ram_res: Active Volatile memory capacity configuration
* @serial: PCIe Device Serial Number
* @type: Generic Memory Class device or Vendor Specific Memory device
+ * @coherence: Device or Host only coherence
* @cxl_mbox: CXL mailbox context
*/
struct cxl_dev_state {
@@ -442,6 +453,7 @@ struct cxl_dev_state {
struct resource ram_res;
u64 serial;
enum cxl_devtype type;
+ enum cxl_devcoherence coherence;
struct cxl_mailbox cxl_mbox;
};
--
2.39.2
next prev parent reply other threads:[~2024-10-15 6:58 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-15 6:57 [PATCH 0/5] cxl: Some preparation work for type2 accelerators support Huang Ying
2024-10-15 6:57 ` [PATCH 1/5] cxl: Rename ACPI_CEDT_CFMWS_RESTRICT_TYPE2/TYPE3 Huang Ying
2024-10-15 6:57 ` [PATCH 2/5] cxl: Rename CXL_DECODER_HOSTONLYMEM/DEVMEM Huang Ying
2024-10-17 22:21 ` Dan Williams
2024-10-18 6:18 ` Huang, Ying
2024-10-18 21:17 ` Dan Williams
2024-10-21 4:40 ` Huang, Ying
2024-10-15 6:57 ` Huang Ying [this message]
2024-10-17 22:25 ` [PATCH 3/5] cxl: Separate coherence from target type Dan Williams
2024-10-15 6:57 ` [PATCH 4/5] cxl: Set type of region to that of the first endpoint Huang Ying
2024-10-17 22:33 ` Dan Williams
2024-10-18 6:50 ` Huang, Ying
2024-10-18 21:19 ` Dan Williams
2024-10-21 6:33 ` Huang, Ying
2024-10-21 9:47 ` Alejandro Lucero Palau
2024-10-15 6:57 ` [PATCH 5/5] cxl: Avoid to create dax regions for type2 accelerators Huang Ying
2024-10-15 8:51 ` Alejandro Lucero Palau
2024-10-17 6:29 ` Huang, Ying
2024-10-17 7:27 ` Alejandro Lucero Palau
2024-10-17 7:48 ` Huang, Ying
2024-10-18 9:57 ` Jonathan Cameron
2024-10-21 11:37 ` Huang, Ying
2024-10-17 23:15 ` Dan Williams
2024-10-21 11:52 ` Huang, Ying
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=20241015065713.308671-4-ying.huang@intel.com \
--to=ying.huang@intel.com \
--cc=alison.schofield@intel.com \
--cc=alucerop@amd.com \
--cc=benjamin.cheatham@amd.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=gourry@gourry.net \
--cc=ira.weiny@intel.com \
--cc=jonathan.cameron@huawei.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@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