From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
To: Dave Jiang <dave.jiang@intel.com>
Cc: <linux-cxl@vger.kernel.org>, <dan.j.williams@intel.com>,
<dave@stgolabs.net>, <alison.schofield@intel.com>,
<ira.weiny@intel.com>, <rrichter@amd.com>, <ming.li@zohomail.com>
Subject: Re: [PATCH 1/4] cxl: Saperate out CXL dport->id vs actual dport hardware id
Date: Tue, 22 Apr 2025 17:54:46 +0100 [thread overview]
Message-ID: <20250422175446.00002ac5@huawei.com> (raw)
In-Reply-To: <20250404230049.3578835-2-dave.jiang@intel.com>
On Fri, 4 Apr 2025 15:57:33 -0700
Dave Jiang <dave.jiang@intel.com> wrote:
Typo in patch title. Separate
> In preparation to allow dport to be allocated without being active, make
> dport->id to be Linux id that enumerates the dport objects per port.
> Keep the hardware id under dport->port_id to maintain compatibility and
> introduce a dport->id as the enumeration id.
>
> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
I'm getting my head around this still but just based on refactor in here
we have a bit where lifetimes weren't quite what I expected to see.
> ---
> drivers/cxl/core/port.c | 40 +++++++++++++++++++++++++++++-----------
> drivers/cxl/cxl.h | 4 ++++
> 2 files changed, 33 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
> index 0fd6646c1a2e..e90e55bc11ac 100644
> --- a/drivers/cxl/core/port.c
> +++ b/drivers/cxl/core/port.c
> @@ -159,7 +159,7 @@ static ssize_t emit_target_list(struct cxl_switch_decoder *cxlsd, char *buf)
>
> if (i + 1 < cxld->interleave_ways)
> next = cxlsd->target[i + 1];
> - rc = sysfs_emit_at(buf, offset, "%d%s", dport->port_id,
> + rc = sysfs_emit_at(buf, offset, "%d%s", dport->id,
> next ? "," : "");
> if (rc < 0)
> return rc;
> @@ -739,6 +739,7 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev,
> dev->parent = uport_dev;
>
> ida_init(&port->decoder_ida);
> + ida_init(&port->dport_ida);
> port->hdm_end = -1;
> port->commit_end = -1;
> xa_init(&port->dports);
> @@ -1044,14 +1045,14 @@ void put_cxl_root(struct cxl_root *cxl_root)
> }
> EXPORT_SYMBOL_NS_GPL(put_cxl_root, "CXL");
>
> -static struct cxl_dport *find_dport(struct cxl_port *port, int id)
> +static struct cxl_dport *find_dport(struct cxl_port *port, int port_id)
> {
> struct cxl_dport *dport;
> unsigned long index;
>
> device_lock_assert(&port->dev);
> xa_for_each(&port->dports, index, dport)
> - if (dport->port_id == id)
> + if (dport->port_id == port_id)
> return dport;
> return NULL;
> }
> @@ -1105,6 +1106,7 @@ static void cxl_dport_remove(void *data)
> struct cxl_port *port = dport->port;
>
> xa_erase(&port->dports, (unsigned long) dport->dport_dev);
> + ida_free(&port->dport_ida, dport->id);
Hmm. This ordering is effectively different to that in __devm_cxl_add_dport(reversed).
If we were to match that we'd free the ida after the
put_device(dport->dport_dev) which I think is unwinding the reference from
get_device(dport_dev)
This makes me suspicious of the ownership of dport->id.
Maybe just spin another devm_add_action_or_reset() to free the id?
If we need this ordering add a comment here on why.
> put_device(dport->dport_dev);
> }
>
> @@ -1114,7 +1116,7 @@ static void cxl_dport_unlink(void *data)
> struct cxl_port *port = dport->port;
> char link_name[CXL_TARGET_STRLEN];
>
> - sprintf(link_name, "dport%d", dport->port_id);
> + sprintf(link_name, "dport%d", dport->id);
> sysfs_remove_link(&port->dev.kobj, link_name);
> }
>
> @@ -1126,7 +1128,7 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
> char link_name[CXL_TARGET_STRLEN];
> struct cxl_dport *dport;
> struct device *host;
> - int rc;
> + int id, rc;
>
> if (is_cxl_root(port))
> host = port->uport_dev;
> @@ -1139,29 +1141,41 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
> return ERR_PTR(-ENXIO);
> }
>
> - if (snprintf(link_name, CXL_TARGET_STRLEN, "dport%d", port_id) >=
> - CXL_TARGET_STRLEN)
> + id = ida_alloc(&port->dport_ida, GFP_KERNEL);
> + if (id < 0)
> + return ERR_PTR(id);
> +
> + if (snprintf(link_name, CXL_TARGET_STRLEN, "dport%d", id) >=
> + CXL_TARGET_STRLEN) {
> + ida_free(&port->dport_ida, id);
I'm not that keen on the number of places we have to call ida_free() manually
in error paths. I think that's because we should have another devm
handler...
> return ERR_PTR(-EINVAL);
> + }
>
> dport = devm_kzalloc(host, sizeof(*dport), GFP_KERNEL);
> - if (!dport)
> + if (!dport) {
> + ida_free(&port->dport_ida, id);
> return ERR_PTR(-ENOMEM);
> + }
>
> dport->dport_dev = dport_dev;
> dport->port_id = port_id;
> dport->port = port;
> + dport->id = id;
>
> if (rcrb == CXL_RESOURCE_NONE) {
> rc = cxl_dport_setup_regs(&port->dev, dport,
> component_reg_phys);
> - if (rc)
> + if (rc) {
> + ida_free(&port->dport_ida, id);
> return ERR_PTR(rc);
> + }
> } else {
> dport->rcrb.base = rcrb;
> component_reg_phys = __rcrb_to_component(dport_dev, &dport->rcrb,
> CXL_RCRB_DOWNSTREAM);
> if (component_reg_phys == CXL_RESOURCE_NONE) {
> dev_warn(dport_dev, "Invalid Component Registers in RCRB");
> + ida_free(&port->dport_ida, id);
> return ERR_PTR(-ENXIO);
> }
>
> @@ -1170,8 +1184,10 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
> * memdev
> */
> rc = cxl_dport_setup_regs(NULL, dport, component_reg_phys);
> - if (rc)
> + if (rc) {
> + ida_free(&port->dport_ida, id);
> return ERR_PTR(rc);
> + }
>
> dport->rch = true;
> }
> @@ -1183,8 +1199,10 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
> cond_cxl_root_lock(port);
> rc = add_dport(port, dport);
> cond_cxl_root_unlock(port);
> - if (rc)
> + if (rc) {
> + ida_free(&port->dport_ida, id);
> return ERR_PTR(rc);
> + }
>
> get_device(dport_dev);
> rc = devm_add_action_or_reset(host, cxl_dport_remove, dport);
next prev parent reply other threads:[~2025-04-22 16:54 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-04 22:57 [PATCH 0/4] cxl: Delay HB port and switch dport probing until endpoint dev probe Dave Jiang
2025-04-04 22:57 ` [PATCH 1/4] cxl: Saperate out CXL dport->id vs actual dport hardware id Dave Jiang
2025-04-22 16:54 ` Jonathan Cameron [this message]
2025-04-25 22:26 ` Dave Jiang
2025-04-22 19:37 ` Dan Williams
2025-04-25 22:27 ` Dave Jiang
2025-04-04 22:57 ` [PATCH 2/4] cxl: Defer hardware dport->port_id assignment and registers probing Dave Jiang
2025-04-11 2:20 ` Li Ming
2025-04-14 21:45 ` Dave Jiang
2025-04-22 17:05 ` Jonathan Cameron
2025-04-25 22:49 ` Dave Jiang
2025-04-22 20:12 ` Dan Williams
2025-04-29 18:41 ` Dave Jiang
2025-04-04 22:57 ` [PATCH 3/4] cxl: Add late host bridge uport mapping update Dave Jiang
2025-04-11 2:32 ` Li Ming
2025-04-14 22:06 ` Dave Jiang
2025-04-22 17:15 ` Jonathan Cameron
2025-04-23 6:10 ` Dan Williams
2025-04-23 15:49 ` Dave Jiang
2025-04-04 22:57 ` [PATCH 4/4] cxl/test: Add workaround for cxl_test for cxl_core calling mocked functions Dave Jiang
2025-04-22 16:31 ` Jonathan Cameron
2025-04-29 19:52 ` Dan Williams
2025-04-11 3:05 ` [PATCH 0/4] cxl: Delay HB port and switch dport probing until endpoint dev probe Li Ming
2025-04-14 15:34 ` 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=20250422175446.00002ac5@huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=alison.schofield@intel.com \
--cc=dan.j.williams@intel.com \
--cc=dave.jiang@intel.com \
--cc=dave@stgolabs.net \
--cc=ira.weiny@intel.com \
--cc=linux-cxl@vger.kernel.org \
--cc=ming.li@zohomail.com \
--cc=rrichter@amd.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.