]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
dax/kmem: account for partial discontiguous resource upon removal
authorDavidlohr Bueso <dave@stgolabs.net>
Mon, 23 Feb 2026 20:15:16 +0000 (12:15 -0800)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 29 May 2026 04:04:53 +0000 (21:04 -0700)
When dev_dax_kmem_probe() partially succeeds (at least one range is
mapped) but a subsequent range fails request_mem_region() or
add_memory_driver_managed(), the probe silently continues, ultimately
returning success, but with the corresponding range resource NULL'ed out.

dev_dax_kmem_remove() iterates over all dax_device ranges regardless of if
the underlying resource exists.  When remove_memory() is called later, it
returns 0 because the memory was never added which causes
dev_dax_kmem_remove() to incorrectly assume the (nonexistent) resource can
be removed and attempts cleanup on a NULL pointer.

Fix this by skipping these ranges altogether, noting that these cases are
considered success, such that the cleanup is still reached when all
actually-added ranges are successfully removed.

Link: https://lore.kernel.org/20260223201516.1517657-1-dave@stgolabs.net
Fixes: 60e93dc097f7 ("device-dax: add dis-contiguous resource support")
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Reviewed-by: Ben Cheatham <benjamin.cheatham@amd.com>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
drivers/dax/kmem.c

index 2cc8749bc8711bbd5ec4b100c6f40342b56f9466..a18e2b968e4daef85a9a91777dc77a0dda9e375b 100644 (file)
@@ -227,6 +227,12 @@ static void dev_dax_kmem_remove(struct dev_dax *dev_dax)
                if (rc)
                        continue;
 
+               /* range was never added during probe */
+               if (!data->res[i]) {
+                       success++;
+                       continue;
+               }
+
                rc = remove_memory(range.start, range_len(&range));
                if (rc == 0) {
                        remove_resource(data->res[i]);