FAILED: patch "[PATCH] cxl/pmem: Fix nvdimm registration races" failed to apply to 5.15-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x f57aec443c24d2e8e1f3b5b4856aea12ddda4254
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '[email protected]' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
f57aec443c24 ("cxl/pmem: Fix nvdimm registration races")4a0079bc7aae ("nvdimm: Replace lockdep_mutex with local lock classes") 3b6c6c039707 ("nvdimm/region: Delete nd_blk_region infrastructure") 84bd3690bf54 ("nvdimm/namespace: Delete nd_namespace_blk")fadc38a6672a ("nvdimm/namespace: Delete blk namespace consideration in shared paths") d9d290d7e659 ("nvdimm/region: Fix default alignment for small regions") 60b8f17215de ("cxl/pmem: Translate NVDIMM label commands to CXL label commands") 12f3856ad42d ("cxl/mbox: Add exclusive kernel command support")ff56ab9e164d ("cxl/mbox: Convert 'enabled_cmds' to DECLARE_BITMAP") 4faf31b43468 ("cxl/mbox: Move mailbox and other non-PCI specific infrastructure to the core") 4cb35f1ca05a ("cxl/pci: Drop idr.h")b64955a92929 ("cxl/mbox: Introduce the mbox_send operation")13e7749d06b3 ("cxl/pci: Clean up cxl_mem_get_partition_info()")99e222a5f1b6 ("cxl/pci: Make 'struct cxl_mem' device type generic") 5af96835e4da ("libnvdimm/labels: Introduce CXL labels")540ccaa2e4dd ("libnvdimm/label: Define CXL region labels")42e192aa9891 ("libnvdimm/labels: Introduce the concept of multi-range namespace labels") 8172db92527c ("libnvdimm/label: Add a helper for nlabel validation") d1c6e08e7503 ("libnvdimm/labels: Add uuid helpers")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f57aec443c24d2e8e1f3b5b4856aea12ddda4254 Mon Sep 17 00:00:00 2001
From: Dan Williams <[email protected]>
Date: Mon, 13 Feb 2023 17:01:05 -0800
Subject: [PATCH] cxl/pmem: Fix nvdimm registration races
A loop of the form:
while true; do modprobe cxl_pci; modprobe -r cxl_pci; done
...fails with the following crash signature:
BUG: kernel NULL pointer dereference, address: 0000000000000040
[..]
RIP: 0010:cxl_internal_send_cmd+0x5/0xb0 [cxl_core]
[..]
Call Trace:
<TASK>
cxl_pmem_ctl+0x121/0x240 [cxl_pmem]
nvdimm_get_config_data+0xd6/0x1a0 [libnvdimm]
nd_label_data_init+0x135/0x7e0 [libnvdimm]
nvdimm_probe+0xd6/0x1c0 [libnvdimm]
nvdimm_bus_probe+0x7a/0x1e0 [libnvdimm]
really_probe+0xde/0x380
__driver_probe_device+0x78/0x170
driver_probe_device+0x1f/0x90
__device_attach_driver+0x85/0x110
bus_for_each_drv+0x7d/0xc0
__device_attach+0xb4/0x1e0
bus_probe_device+0x9f/0xc0
device_add+0x445/0x9c0
nd_async_device_register+0xe/0x40 [libnvdimm]
async_run_entry_fn+0x30/0x130...namely that the bottom half of async nvdimm device registration runs after the CXL has already torn down the context that cxl_pmem_ctl() needs. Unlike the ACPI NFIT case that benefits from launching multiple nvdimm device registrations in parallel from those listed in the table, CXL is already marked PROBE_PREFER_ASYNCHRONOUS. So provide for a synchronous registration path to preclude this scenario.
drivers/cxl/pmem.c +1 -0
@@ -76,6 +76,7 @@ static int cxl_nvdimm_probe(struct device *dev)return rc;set_bit (NDD_LABELING , &flags); +set_bit (NDD_REGISTER_SYNC , &flags);set_bit (ND_CMD_GET_CONFIG_SIZE , &cmd_mask);set_bit (ND_CMD_GET_CONFIG_DATA , &cmd_mask);set_bit (ND_CMD_SET_CONFIG_DATA , &cmd_mask);
drivers/nvdimm/bus.c +16 -3
@@ -508,7 +508,7 @@ static void nd_async_device_unregister(void *d, async_cookie_t cookie)put_device (dev); } -void nd_device_register (struct device *dev) +static void __nd_device_register (struct device *dev,bool sync) {if (!dev)return ;
@@ -531,11 +531,24 @@ void nd_device_register(struct device *dev) }get_device (dev); -async_schedule_dev_domain (nd_async_device_register, dev, - &nd_async_domain); +if (sync) +nd_async_device_register (dev,0 ); +else +async_schedule_dev_domain (nd_async_device_register, dev, + &nd_async_domain); +} + +void nd_device_register (struct device *dev) +{ +__nd_device_register (dev, false); }EXPORT_SYMBOL (nd_device_register); +void nd_device_register_sync (struct device *dev) +{ +__nd_device_register (dev, true); +} +void nd_device_unregister (struct device *dev,enum nd_async_mode mode) {bool killed;
drivers/nvdimm/dimm_devs.c +4 -1
@@ -624,7 +624,10 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus, nvdimm->sec.ext_flags =nvdimm_security_flags (nvdimm,NVDIMM_MASTER );device_initialize (dev);lockdep_set_class (&dev->mutex, &nvdimm_key); -nd_device_register (dev); +if (test_bit (NDD_REGISTER_SYNC , &flags)) +nd_device_register_sync (dev); +else +nd_device_register (dev);return nvdimm; }
drivers/nvdimm/nd-core.h +1 -0
@@ -107,6 +107,7 @@ int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus);void nvdimm_bus_destroy_ndctl (struct nvdimm_bus *nvdimm_bus);void nd_synchronize (void );void nd_device_register (struct device *dev); +void nd_device_register_sync (struct device *dev);struct nd_label_id ;char *nd_label_gen_id (struct nd_label_id *label_id,const uuid_t *uuid,u32 flags);
include/linux/libnvdimm.h +3 -0
@@ -41,6 +41,9 @@ enum {*/ NDD_INCOHERENT =7 , +/* dimm provider wants synchronous registration by __nvdimm_create() */ +NDD_REGISTER_SYNC =8 , +/* need to set a limit somewhere, but yes, this is likely overkill */ ND_IOCTL_MAX_BUFLEN =SZ_4M , ND_CMD_MAX_ELEM = 5,