Skip to content

Commit

Permalink
cxl/port: Fix cxl_bus_rescan() vs bus_rescan_devices()
Browse files Browse the repository at this point in the history
[ Upstream commit 3d6ebf1 ]

It turns out since its original introduction, pre-2.6.12,
bus_rescan_devices() has skipped devices that might be in the process of
attaching or detaching from their driver. For CXL this behavior is
unwanted and expects that cxl_bus_rescan() is a probe barrier.

That behavior is simple enough to achieve with bus_for_each_dev() paired
with call to device_attach(), and it is unclear why bus_rescan_devices()
took the position of lockless consumption of dev->driver which is racy.

The "Fixes:" but no "Cc: stable" on this patch reflects that the issue
is merely by inspection since the bug that triggered the discovery of
this potential problem [1] is fixed by other means.  However, a stable
backport should do no harm.

Fixes: 8dd2bc0 ("cxl/mem: Add the cxl_mem driver")
Link: http://lore.kernel.org/20241004212504.1246-1-gourry@gourry.net [1]
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Tested-by: Gregory Price <gourry@gourry.net>
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Ira Weiny <ira.weiny@intel.com>
Link: https://patch.msgid.link/172964781104.81806.4277549800082443769.stgit@dwillia2-xfh.jf.intel.com
Signed-off-by: Ira Weiny <ira.weiny@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
djbw authored and gregkh committed Nov 8, 2024
1 parent d210bc8 commit a9ed67f
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions drivers/cxl/core/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -1969,11 +1969,18 @@ static void cxl_bus_remove(struct device *dev)

static struct workqueue_struct *cxl_bus_wq;

static void cxl_bus_rescan_queue(struct work_struct *w)
static int cxl_rescan_attach(struct device *dev, void *data)
{
int rc = bus_rescan_devices(&cxl_bus_type);
int rc = device_attach(dev);

dev_vdbg(dev, "rescan: %s\n", rc ? "attach" : "detached");

pr_debug("CXL bus rescan result: %d\n", rc);
return 0;
}

static void cxl_bus_rescan_queue(struct work_struct *w)
{
bus_for_each_dev(&cxl_bus_type, NULL, NULL, cxl_rescan_attach);
}

void cxl_bus_rescan(void)
Expand Down

0 comments on commit a9ed67f

Please sign in to comment.