Linux-CXL Archive mirror
 help / color / mirror / Atom feed
From: Dongsheng Yang <dongsheng.yang@easystack.cn>
To: dave@stgolabs.net, jonathan.cameron@huawei.com,
	ave.jiang@intel.com, alison.schofield@intel.com,
	vishal.l.verma@intel.com, ira.weiny@intel.com,
	dan.j.williams@intel.com
Cc: linux-cxl@vger.kernel.org, Dongsheng Yang <dongsheng.yang@easystack.cn>
Subject: [RFC PATCH 3/4] cxl/port: introduce cxl_disable_port() function
Date: Thu, 28 Dec 2023 06:05:09 +0000	[thread overview]
Message-ID: <20231228060510.1178981-4-dongsheng.yang@easystack.cn> (raw)
In-Reply-To: <20231228060510.1178981-1-dongsheng.yang@easystack.cn>

when we want to delete an port (e.g in cxlv), we want to
make sure there is no region attached to this port or
any child port. And more, we need to prevent region to
attach in port deleting.

cxl_disable_port() will return -EBUSY if there is any
region attached to this port or child port, otherwise it
will set any child endpoint decoder to CXL_DECODER_DEAD,
that means this port are going to be deleted, dont attach region
to it.

Signed-off-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
---
 drivers/cxl/core/port.c | 80 +++++++++++++++++++++++++++++++++++++++++
 drivers/cxl/cxl.h       |  1 +
 2 files changed, 81 insertions(+)

diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 8d2d54da45e5..59ab8fe2cff2 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1508,6 +1508,86 @@ static void reap_dports(struct cxl_port *port)
 	}
 }
 
+/*
+ * Disable an endpoint decoder to prevent any more region attach.
+ */
+static int disable_decoder(struct device *device, void *data)
+{
+	struct cxl_endpoint_decoder *cxled;
+
+	if (!is_endpoint_decoder(device))
+		return 0;
+
+	cxled = to_cxl_endpoint_decoder(device);
+	cxled->mode = CXL_DECODER_DEAD;
+
+	return 0;
+}
+
+/*
+ * Disable a port, if it is an endpoint port, it will disable
+ * the related endpoint decoder, otherwise, disable all child ports.
+ */
+static int disable_port(struct device *device, void *data)
+{
+	struct cxl_port *port;
+	int ret;
+
+	if (!is_cxl_port(device))
+		return 0;
+
+	port = to_cxl_port(device);
+	if (is_cxl_endpoint(port)) {
+		ret = device_for_each_child(&port->dev, NULL, disable_decoder);
+	} else {
+		ret = device_for_each_child(&port->dev, NULL, disable_port);
+	}
+
+	return ret;
+}
+
+/*
+ * If there is any region attached to this port or child port, return -EBUSY.
+ */
+static int port_busy(struct device *device, void *data)
+{
+	struct cxl_port *port;
+
+	if (!is_cxl_port(device))
+		return 0;
+
+	port = to_cxl_port(device);
+	if (!xa_empty(&port->regions)) {
+		return -EBUSY;
+	}
+
+	return device_for_each_child(&port->dev, NULL, port_busy);
+}
+
+/*
+ * Disable any child endpoint decoder to prevent region attach,
+ * then we can delete this port safely.
+ *
+ * Returns -EBUSY if there is still region attached to this port
+ * or child port.
+ */
+int cxl_disable_port(struct cxl_port *port)
+{
+	int ret;
+
+	down_write(&cxl_region_rwsem);
+	if (port_busy(&port->dev, NULL)) {
+		ret = -EBUSY;
+		goto unlock;
+	}
+
+	ret = disable_port(&port->dev, NULL);
+unlock:
+	up_write(&cxl_region_rwsem);
+	return ret;
+}
+EXPORT_SYMBOL_NS_GPL(cxl_disable_port, CXL);
+
 struct detach_ctx {
 	struct cxl_memdev *cxlmd;
 	int depth;
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index 1397f66d943b..a1343449f35c 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -716,6 +716,7 @@ struct cxl_dport *devm_cxl_add_dport(struct cxl_port *port,
 struct cxl_dport *devm_cxl_add_rch_dport(struct cxl_port *port,
 					 struct device *dport_dev, int port_id,
 					 resource_size_t rcrb);
+int cxl_disable_port(struct cxl_port *port);
 
 #ifdef CONFIG_PCIEAER_CXL
 void cxl_setup_parent_dport(struct device *host, struct cxl_dport *dport);
-- 
2.34.1


  parent reply	other threads:[~2023-12-28  6:23 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-28  6:05 [RFC PATCH 0/4] cxl: introduce CXL Virtualization module Dongsheng Yang
2023-12-28  6:05 ` [RFC PATCH 1/4] cxl: move some function from acpi module to core module Dongsheng Yang
2023-12-28  6:43   ` Dongsheng Yang
2023-12-28  6:05 ` Dongsheng Yang [this message]
2023-12-28  6:05 ` [RFC PATCH 4/4] cxl: introduce CXL Virtualization module Dongsheng Yang
2024-01-03 17:22 ` [RFC PATCH 0/4] " Ira Weiny
2024-01-08 12:28   ` Jonathan Cameron
2024-01-10  2:07   ` Dongsheng Yang
2024-01-03 20:48 ` Dan Williams
     [not found]   ` <a32d859f-054f-11ca-e8a3-dff7a5234d0a@easystack.cn>
2024-01-25  3:49     ` Dan Williams
2024-01-25  6:49       ` Dongsheng Yang
2024-01-25  7:46         ` Dan Williams
2024-05-03  5:12 ` Hyeongtak Ji

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=20231228060510.1178981-4-dongsheng.yang@easystack.cn \
    --to=dongsheng.yang@easystack.cn \
    --cc=alison.schofield@intel.com \
    --cc=ave.jiang@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave@stgolabs.net \
    --cc=ira.weiny@intel.com \
    --cc=jonathan.cameron@huawei.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 read-only IMAP folder(s) and NNTP newsgroup(s).