From: sashiko-bot@kernel.org
To: "Anisa Su" <anisa.su887@gmail.com>
Cc: linux-cxl@vger.kernel.org, nvdimm@lists.linux.dev
Subject: Re: [PATCH v11 14/31] cxl/extent: Handle DC Add Capacity events
Date: Thu, 25 Jun 2026 18:16:35 +0000 [thread overview]
Message-ID: <20260625181636.208D41F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260625112638.550691-15-anisa.su@samsung.com>
Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:
- [High] Use-after-free in `cxlr_dax_classify_extent` due to lockless XArray iteration.
- [High] Fully duplicate Add-Capacity groups are erroneously dropped without sending an Add-DC-Response.
- [High] Failed extents unconditionally send Release DC commands on error paths, violating the skip_device_release protocol.
- [High] Manual `xa_erase()` before `put_device()` creates a race condition that clobbers re-allocated IDs.
- [High] Concurrent teardown causes a data race on `group->nr_extents`, leading to a permanent resource leak.
- [High] Recovered extents are permanently leaked to the device if their individual tracking allocation fails.
- [High] Tag groups spanning multiple DAX regions are silently grouped under the first region, corrupting HPA ranges.
--
commit c1287602ad57e47bb90d02808a1f908fcb287a89
Author: Ira Weiny <iweiny@kernel.org>
Subject: cxl/extent: Handle DC Add Capacity events
Replace the empty-response stub in handle_add_event() with the real
add pipeline. This commit fills in the logic for processing the pending list
and adds basic validation for extents before they are added to the
device model as a child of the cxlr_dax region.
> diff --git a/drivers/cxl/core/extent.c b/drivers/cxl/core/extent.c
> new file mode 100644
> index 0000000000000..6e67e787d14de
> --- /dev/null
> +++ b/drivers/cxl/core/extent.c
> @@ -0,0 +1,411 @@
[ ... ]
> +static void dc_extent_release(struct device *dev)
> +{
> + struct dc_extent *dc_extent = to_dc_extent(dev);
> + struct cxl_dc_tag_group *group;
> +
> + if (!dc_extent)
> + return;
> +
> + group = dc_extent->group;
> + cxled_release_extent(dc_extent->cxled, dc_extent);
> + xa_erase(&group->cxlr_dax->dc_extents, dc_extent->dev.id);
> + xa_erase(&group->dc_extents, dc_extent->seq_num);
> + group->nr_extents--;
> + if (!group->nr_extents)
> + free_tag_group(group);
[Severity: High]
Is it safe to decrement group->nr_extents without a lock? Since multiple
extents in the same group can be released concurrently, couldn't this
non-atomic decrement cause a data race, leading to a permanent memory leak
of the cxl_dc_tag_group and its pinned cxlr_dax->dev reference?
> + kfree(dc_extent);
> +}
[ ... ]
> +static enum cxl_extent_class
> +cxlr_dax_classify_extent(struct cxl_dax_region *cxlr_dax,
> + struct cxl_endpoint_decoder *cxled,
> + const struct range *ext_range)
> +{
> + struct dc_extent *entry;
> + unsigned long i;
> +
> + xa_for_each(&cxlr_dax->dc_extents, i, entry) {
> + if (entry->cxled != cxled)
[Severity: High]
Is this iteration safe against concurrent teardown? xa_for_each drops the
internal RCU read lock between iterations, leaving the returned entry
unprotected. If online_tag_group fails concurrently or there is a
parallel release, couldn't accessing entry->cxled trigger a use-after-free?
> + continue;
> + if (range_contains(&entry->dpa_range, ext_range))
> + return CXL_EXT_DUPLICATE;
[ ... ]
> +static int cxlr_add_extent(struct cxl_memdev_state *mds,
> + struct cxl_dax_region *cxlr_dax,
> + struct dc_extent *dc_extent)
> +{
> + struct cxl_dc_tag_group **group = &mds->add_ctx.group;
> + int rc;
> +
> + if (*group && !uuid_equal(&(*group)->uuid, &dc_extent->uuid)) {
> + kfree(dc_extent);
> + return -EINVAL;
> + }
> +
> + if (!*group) {
> + dev_dbg(&cxlr_dax->dev, "Alloc new tag group\n");
> + *group = alloc_tag_group(cxlr_dax, &dc_extent->uuid);
> + if (IS_ERR(*group)) {
> + rc = PTR_ERR(*group);
> + *group = NULL;
> + kfree(dc_extent);
> + return rc;
> + }
> + } else {
> + dev_dbg(&cxlr_dax->dev, "Append dc_extent to tag group\n");
> + }
> +
> + dc_extent->group = *group;
[Severity: High]
What happens if extents in the same tag group (sharing a UUID) map to
different endpoint decoders and thus different DAX regions? This logic
appears to allocate the tag group using the cxlr_dax of the first extent
and blindly links subsequent extents to it. Could this cause cross-region
extents to be parented to the wrong region and corrupt their HPA mapping
offsets?
> +
> + /*
[ ... ]
> +int online_tag_group(struct cxl_dc_tag_group *group, bool skip_release)
> +{
[ ... ]
> + rc = dev_set_name(dev, "extent%d.%d", cxlr_dax->cxlr->id,
> + dev->id);
> + if (rc) {
> + xa_erase(&cxlr_dax->dc_extents, dev->id);
> + put_device(dev);
> + break;
> + }
> +
> + rc = device_add(dev);
> + if (rc) {
> + xa_erase(&cxlr_dax->dc_extents, dev->id);
> + put_device(dev);
> + break;
> + }
[Severity: High]
Does the manual xa_erase() before put_device() create a double-erase race
condition?
put_device(dev) synchronously calls dc_extent_release(), which performs a
second xa_erase() for the same ID. If a concurrent thread allocates an ID
between the first and second erase, wouldn't the second erase silently
clobber the new valid allocation?
[Severity: High]
Additionally, does this error path violate the skip_device_release protocol?
At this point, group->skip_device_release has not been set yet. Because it
is false, won't dc_extent_release() unconditionally send a Release DC command
to the hardware for capacity the host never formally accepted?
> +
> + dev_dbg(dev, "dc_extent HPA %pra (%pU)\n",
[ ... ]
> diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
> index 4e887b5cdc3ed..08f51b8807c06 100644
> --- a/drivers/cxl/core/mbox.c
> +++ b/drivers/cxl/core/mbox.c
[ ... ]
> +static int cxl_realize_group(struct cxl_memdev_state *mds, const uuid_t *tag,
> + struct list_head *group, bool existing)
> +{
> + struct device *dev = mds->cxlds.dev;
> + struct cxl_extent_list_node *pos, *tmp;
> + struct cxl_dc_tag_group *tag_group;
> + int group_cnt = 0;
> + int rc;
> +
> + list_for_each_entry_safe(pos, tmp, group, list) {
> + /*
> + * Pass the device-stamped 0-based shared_extn_seq through
> + * unchanged as the dax-side @seq_num (0..n-1).
> + */
> + u16 seq = le16_to_cpu(pos->extent->shared_extn_seq);
> +
> + if (cxl_add_extent(mds, pos->extent, seq) < 0) {
> + dev_dbg(dev,
> + "Tag %pUb: failed to add extent DPA:%#llx LEN:%#llx\n",
> + tag,
> + le64_to_cpu(pos->extent->start_dpa),
> + le64_to_cpu(pos->extent->length));
> + delete_extent_node(pos);
> + continue;
> + }
[Severity: High]
If cxl_add_extent() fails during initialization of existing extents
(e.g., under memory pressure), we simply delete the node and continue.
Because the extent is never added to a tag group, the teardown error path
cannot see it. Does this permanently strand the capacity on the device since
no Release DC command is sent?
> + group_cnt++;
> + }
> +
> + tag_group = mds->add_ctx.group;
> + mds->add_ctx.group = NULL;
> + if (!tag_group)
> + return -ENXIO;
[Severity: High]
If an Add Capacity event contains only extents that the host has already
accepted (duplicates), cxl_add_extent() succeeds but returns 0, and
mds->add_ctx.group is never allocated. Does this erroneously fail the
entire group with -ENXIO, causing cxl_add_pending() to drop it without
sending an Add-DC-Response, thereby stalling the device?
> +
> + rc = online_tag_group(tag_group, !existing);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260625112638.550691-1-anisa.su@samsung.com?part=14
next prev parent reply other threads:[~2026-06-25 18:16 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-25 11:04 DCD: Add support for Dynamic Capacity Devices (DCD) Anisa Su
2026-06-25 11:04 ` [PATCH v11 01/31] cxl/mbox: Flag " Anisa Su
2026-06-26 21:43 ` Dave Jiang
2026-06-25 11:04 ` [PATCH v11 02/31] cxl/mem: Read dynamic capacity configuration from the device Anisa Su
2026-06-25 18:16 ` sashiko-bot
2026-06-26 22:26 ` Dave Jiang
2026-06-25 11:04 ` [PATCH v11 04/31] cxl/core: Enforce partition order/simplify partition calls Anisa Su
2026-06-26 22:37 ` Dave Jiang
2026-06-25 11:04 ` [PATCH v11 05/31] cxl/mem: Expose dynamic ram 1 partition in sysfs Anisa Su
2026-06-25 18:12 ` sashiko-bot
2026-06-26 23:08 ` Dave Jiang
2026-06-25 11:04 ` [PATCH v11 06/31] cxl/port: Add 'dynamic_ram_1' to endpoint decoder mode Anisa Su
2026-06-25 11:04 ` [PATCH v11 07/31] cxl/region: Add DC DAX region support Anisa Su
2026-06-25 18:16 ` sashiko-bot
2026-06-26 23:18 ` Dave Jiang
2026-06-25 11:04 ` [PATCH v11 08/31] cxl/events: Split event msgnum configuration from irq setup Anisa Su
2026-06-25 11:04 ` [PATCH v11 09/31] cxl/pci: Factor out interrupt policy check Anisa Su
2026-06-25 11:04 ` [PATCH v11 10/31] cxl/mem: Configure dynamic capacity interrupts Anisa Su
2026-06-25 18:14 ` sashiko-bot
2026-06-25 11:04 ` [PATCH v11 11/31] cxl/core: Return endpoint decoder information from region search Anisa Su
2026-06-25 11:04 ` [PATCH v11 12/31] cxl/mem: Set up framework for handling DC Events Anisa Su
2026-06-25 18:12 ` sashiko-bot
2026-06-26 21:54 ` Dave Jiang
2026-06-25 11:04 ` [PATCH v11 13/31] cxl/mem: Add 20 second timeout for stalled DC_ADD_CAPACITY chains Anisa Su
2026-06-25 18:15 ` sashiko-bot
2026-06-25 11:04 ` [PATCH v11 14/31] cxl/extent: Handle DC Add Capacity events Anisa Su
2026-06-25 18:16 ` sashiko-bot [this message]
2026-06-25 11:04 ` [PATCH v11 15/31] cxl/mem: Drop misaligned DCD extent groups Anisa Su
2026-06-25 18:19 ` sashiko-bot
2026-06-25 11:04 ` [PATCH v11 16/31] cxl/extent: Validate DC extent partition Anisa Su
2026-06-25 18:20 ` sashiko-bot
2026-06-25 11:04 ` [PATCH v11 17/31] cxl/mem: Enforce tag-group semantics Anisa Su
2026-06-25 18:24 ` sashiko-bot
2026-06-25 11:04 ` [PATCH v11 18/31] cxl/extent: Handle DC Release Capacity events Anisa Su
2026-06-25 18:23 ` sashiko-bot
2026-06-25 11:04 ` [PATCH v11 19/31] cxl/extent: Enforce cross-region tag uniqueness Anisa Su
2026-06-25 18:23 ` sashiko-bot
2026-06-25 11:04 ` [PATCH v11 20/31] cxl/region/extent: Expose dc_extent information in sysfs Anisa Su
2026-06-25 18:33 ` sashiko-bot
2026-06-25 11:04 ` [PATCH v11 21/31] cxl + dax: Surface dax_resources on DCD Add Capacity events Anisa Su
2026-06-25 18:29 ` sashiko-bot
2026-06-25 11:04 ` [PATCH v11 22/31] cxl + dax: Release dax_resources on DCD Release " Anisa Su
2026-06-25 18:36 ` sashiko-bot
2026-06-25 11:05 ` [PATCH v11 23/31] dax/bus: Factor out dev dax resize logic Anisa Su
2026-06-25 18:27 ` sashiko-bot
2026-06-25 11:05 ` [PATCH v11 24/31] dax/bus: Add uuid sysfs attribute to dax devices Anisa Su
2026-06-25 11:05 ` [PATCH v11 25/31] dax/bus: Reject resize on DC dax devices and enforce 0-size creation Anisa Su
2026-06-25 11:05 ` [PATCH v11 26/31] dax/bus: Tag-aware uuid claim and show on DC dax devices Anisa Su
2026-06-25 18:26 ` sashiko-bot
2026-06-25 11:05 ` [PATCH v11 27/31] cxl/region: Read existing extents on region creation Anisa Su
2026-06-25 18:32 ` sashiko-bot
2026-06-25 11:05 ` [PATCH v11 28/31] cxl/mem: Trace Dynamic capacity Event Record Anisa Su
2026-06-25 18:29 ` sashiko-bot
2026-06-25 11:05 ` [PATCH v11 29/31] tools/testing/cxl: Make event logs dynamic Anisa Su
2026-06-25 18:31 ` sashiko-bot
2026-06-25 11:05 ` [PATCH v11 30/31] tools/testing/cxl: Add DC Regions to mock mem data Anisa Su
2026-06-25 18:34 ` sashiko-bot
2026-06-25 11:05 ` [PATCH v11 31/31] Documentation/cxl: Document DCD extent handling and DC-backed DAX regions Anisa Su
2026-06-25 18:24 ` sashiko-bot
2026-06-25 18:00 ` [PATCH v11 03/31] cxl/cdat: Gather DSMAS data for DCD partitions Anisa Su
2026-06-26 22:30 ` 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=20260625181636.208D41F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=anisa.su887@gmail.com \
--cc=linux-cxl@vger.kernel.org \
--cc=nvdimm@lists.linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
/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