Linux CXL
 help / color / mirror / Atom feed
From: Dave Jiang <dave.jiang@intel.com>
To: linux-cxl@vger.kernel.org
Cc: alison.schofield@intel.com
Subject: [NDCTL PATCH 4/5] cxl: Associate CXL features device with CXL endpoint
Date: Wed, 22 Jan 2025 17:22:03 -0700	[thread overview]
Message-ID: <20250123002304.2758417-5-dave.jiang@intel.com> (raw)
In-Reply-To: <20250123002304.2758417-1-dave.jiang@intel.com>

Add support of cxl_features_get_bus() by setting up the association
between 'cxl endpoint' and 'cxl features'. Add related helper functions
for assisting the setup of the relationship with 'features' and 'endpoint'.
The 'endpoint' is considered as the parent device of 'features' given a
'features' device is exported per CXL mailbox. The association is
established by matching the feature's parent device with the endpoint's
uport deivce. For example, on cxl_test bus provider, both should match
to cxl_memN device.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
---
 cxl/lib/libcxl.c   | 107 +++++++++++++++++++++++++++++++++++++++++++++
 cxl/lib/libcxl.sym |   4 ++
 cxl/lib/private.h  |   3 ++
 cxl/libcxl.h       |   4 ++
 4 files changed, 118 insertions(+)

diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index f2da48278cb0..f13b0055f332 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -213,6 +213,7 @@ static void free_port(struct cxl_port *port, struct list_head *head)
 static void free_endpoint(struct cxl_endpoint *endpoint, struct list_head *head)
 {
 	__free_port(&endpoint->port, head);
+	free(endpoint->uport_host);
 	free(endpoint);
 }
 
@@ -2044,6 +2045,7 @@ static void *add_cxl_endpoint(void *parent, int id, const char *cxlep_base)
 	struct cxl_endpoint *endpoint, *endpoint_dup;
 	struct cxl_port *port = parent;
 	struct cxl_ctx *ctx = cxl_port_get_ctx(port);
+	char *uport_path, *host_path;
 	int rc;
 
 	dbg(ctx, "%s: base: \'%s\'\n", devname, cxlep_base);
@@ -2057,6 +2059,17 @@ static void *add_cxl_endpoint(void *parent, int id, const char *cxlep_base)
 	if (rc)
 		goto err;
 
+
+	uport_path = strdup(endpoint->port.uport);
+	if (!uport_path)
+		goto err;
+
+	host_path = dirname(uport_path);
+	endpoint->uport_host = strdup(devpath_to_devname(host_path));
+	free(uport_path);
+	if (!endpoint->uport_host)
+		goto err;
+
 	cxl_endpoint_foreach(port, endpoint_dup)
 		if (endpoint_dup->port.id == endpoint->port.id) {
 			free_endpoint(endpoint, NULL);
@@ -2168,6 +2181,11 @@ cxl_endpoint_get_memdev(struct cxl_endpoint *endpoint)
 	return NULL;
 }
 
+CXL_EXPORT const char *cxl_endpoint_get_uport_hostname(struct cxl_endpoint *endpoint)
+{
+	return endpoint->uport_host;
+}
+
 static bool cxl_region_is_configured(struct cxl_region *region)
 {
 	return region->size && (region->decode_state != CXL_DECODE_RESET);
@@ -4884,3 +4902,92 @@ CXL_EXPORT int cxl_features_get_minor(struct cxl_features *features)
 {
 	return features->minor;
 }
+
+CXL_EXPORT const char *cxl_features_get_hostname(struct cxl_features *features)
+{
+	return features->hostname;
+}
+
+CXL_EXPORT const char *cxl_features_get_devname(struct cxl_features *features)
+{
+	return devpath_to_devname(features->dev_path);
+}
+
+static struct cxl_endpoint *
+cxl_port_recurse_endpoint_by_features(struct cxl_port *parent_port,
+				      struct cxl_features *features)
+{
+	struct cxl_endpoint *endpoint;
+	struct cxl_port *port;
+
+	cxl_port_foreach(parent_port, port) {
+		cxl_endpoint_foreach(port, endpoint)
+			if (strcmp(cxl_endpoint_get_uport_hostname(endpoint),
+				   cxl_features_get_hostname(features)) == 0)
+				return endpoint;
+		endpoint = cxl_port_recurse_endpoint_by_features(port, features);
+		if (endpoint)
+			return endpoint;
+	}
+
+	return NULL;
+}
+
+static struct cxl_endpoint *
+cxl_port_find_endpoint_by_features(struct cxl_port *parent_port,
+				   struct cxl_features *features)
+{
+	struct cxl_endpoint *endpoint;
+
+	cxl_endpoint_foreach(parent_port, endpoint)
+		if (strcmp(cxl_endpoint_get_uport_hostname(endpoint),
+			   cxl_features_get_hostname(features)) == 0)
+			return endpoint;
+	return cxl_port_recurse_endpoint_by_features(parent_port, features);
+}
+
+CXL_EXPORT struct cxl_endpoint *
+cxl_features_get_endpoint(struct cxl_features *features)
+{
+	struct cxl_ctx *ctx = cxl_features_get_ctx(features);
+	struct cxl_endpoint *endpoint = NULL;
+	struct cxl_bus *bus;
+
+	if (features->endpoint)
+		return features->endpoint;
+
+	cxl_bus_foreach(ctx, bus) {
+		struct cxl_port *port = cxl_bus_get_port(bus);
+
+		endpoint = cxl_port_find_endpoint_by_features(port, features);
+		if (endpoint)
+			break;
+	}
+
+	if (!endpoint)
+		return NULL;
+
+	if (endpoint->features && endpoint->features != features)
+		err(ctx, "%s assigned to %s not %s\n",
+		    cxl_endpoint_get_devname(endpoint),
+		    cxl_features_get_devname(endpoint->features),
+		    cxl_features_get_devname(features));
+	features->endpoint = endpoint;
+	endpoint->features = features;
+
+	return endpoint;
+}
+
+CXL_EXPORT struct cxl_bus *cxl_features_get_bus(struct cxl_features *features)
+{
+	struct cxl_endpoint *endpoint = cxl_features_get_endpoint(features);
+
+	if (!endpoint)
+		return NULL;
+	return cxl_endpoint_get_bus(endpoint);
+}
+
+CXL_EXPORT struct cxl_ctx *cxl_features_get_ctx(struct cxl_features *features)
+{
+	return features->ctx;
+}
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
index 6d70d5b90377..a29d42e1414b 100644
--- a/cxl/lib/libcxl.sym
+++ b/cxl/lib/libcxl.sym
@@ -296,4 +296,8 @@ global:
 	cxl_features_get_next;
 	cxl_features_get_major;
 	cxl_features_get_minor;
+	cxl_features_get_hostname;
+	cxl_features_get_bus;
+	cxl_features_get_ctx;
+	cxl_features_get_devname;
 } LIBECXL_8;
diff --git a/cxl/lib/private.h b/cxl/lib/private.h
index 34785af4e64f..b38ee7d33a40 100644
--- a/cxl/lib/private.h
+++ b/cxl/lib/private.h
@@ -37,6 +37,7 @@ enum cxl_fwl_loading {
 struct cxl_features {
 	int id, major, minor;
 	struct cxl_ctx *ctx;
+	struct cxl_endpoint *endpoint;
 	void *dev_buf;
 	size_t buf_len;
 	char *host_path;
@@ -122,6 +123,8 @@ struct cxl_bus {
 struct cxl_endpoint {
 	struct cxl_port port;
 	struct cxl_memdev *memdev;
+	struct cxl_features *features;
+	char *uport_host;
 };
 
 struct cxl_target {
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
index 5dcc60c8bf1a..610c13051b6d 100644
--- a/cxl/libcxl.h
+++ b/cxl/libcxl.h
@@ -499,6 +499,10 @@ struct cxl_features *cxl_features_get_first(struct cxl_ctx *ctx);
 struct cxl_features *cxl_features_get_next(struct cxl_features *features);
 int cxl_features_get_major(struct cxl_features *features);
 int cxl_features_get_minor(struct cxl_features *features);
+const char *cxl_features_get_devname(struct cxl_features *features);
+const char *cxl_features_get_hostname(struct cxl_features *features);
+struct cxl_bus *cxl_features_get_bus(struct cxl_features *features);
+struct cxl_ctx *cxl_features_get_ctx(struct cxl_features *features);
 
 #ifdef __cplusplus
 } /* extern "C" */
-- 
2.47.1


  parent reply	other threads:[~2025-01-23  0:23 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-23  0:21 [NDCTL PATCH 0/5] ndctl: Add support and test for CXL features driver Dave Jiang
2025-01-23  0:22 ` [NDCTL PATCH 1/5] cxl: Add cxl_bus_get_by_provider() Dave Jiang
2025-01-23  0:22 ` [NDCTL PATCH 2/5] cxl: Enumerate features 'devices' Dave Jiang
2025-01-23  0:22 ` [NDCTL PATCH 3/5] cxl: Add get major and minor for cxl features device Dave Jiang
2025-01-23  0:22 ` Dave Jiang [this message]
2025-01-23  0:22 ` [NDCTL PATCH 5/5] cxl/test: Add test " Dave Jiang

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=20250123002304.2758417-5-dave.jiang@intel.com \
    --to=dave.jiang@intel.com \
    --cc=alison.schofield@intel.com \
    --cc=linux-cxl@vger.kernel.org \
    /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