Skip to content

Commit 214291c

Browse files
committed
acpi/hmat: Fix lockdep warning for hmem_register_resource()
The following lockdep splat was observed while kernel auto-online a CXL memory region: ====================================================== WARNING: possible circular locking dependency detected 6.17.0djtest+ #53 Tainted: G W ------------------------------------------------------ systemd-udevd/3334 is trying to acquire lock: ffffffff90346188 (hmem_resource_lock){+.+.}-{4:4}, at: hmem_register_resource+0x31/0x50 but task is already holding lock: ffffffff90338890 ((node_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x2e/0x70 which lock already depends on the new lock. [..] Chain exists of: hmem_resource_lock --> mem_hotplug_lock --> (node_chain).rwsem Possible unsafe locking scenario: CPU0 CPU1 ---- ---- rlock((node_chain).rwsem); lock(mem_hotplug_lock); lock((node_chain).rwsem); lock(hmem_resource_lock); The lock ordering can cause potential deadlock. There are instances where hmem_resource_lock is taken after (node_chain).rwsem, and vice versa. Split out the target update section of hmat_register_target() so that hmat_callback() only envokes that section instead of attempt to register hmem devices that it does not need to. [ dj: Fix up comment to be closer to 80cols. (Jonathan) ] Fixes: cf8741a ("ACPI: NUMA: HMAT: Register "soft reserved" memory as an "hmem" device") Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Tested-by: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com> Reviewed-by: Smita Koralahalli <Smita.KoralahalliChannabasappa@amd.com> Reviewed-by: Dan Williams <dan.j.williams@intel.com> Link: https://patch.msgid.link/20251105235115.85062-3-dave.jiang@intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent b6cfddd commit 214291c

File tree

1 file changed

+25
-21
lines changed

1 file changed

+25
-21
lines changed

drivers/acpi/numa/hmat.c

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -874,10 +874,32 @@ static void hmat_register_target_devices(struct memory_target *target)
874874
}
875875
}
876876

877-
static void hmat_register_target(struct memory_target *target)
877+
static void hmat_hotplug_target(struct memory_target *target)
878878
{
879879
int nid = pxm_to_node(target->memory_pxm);
880880

881+
/*
882+
* Skip offline nodes. This can happen when memory marked EFI_MEMORY_SP,
883+
* "specific purpose", is applied to all the memory in a proximity
884+
* domain leading to * the node being marked offline / unplugged, or if
885+
* memory-only "hotplug" node is offline.
886+
*/
887+
if (nid == NUMA_NO_NODE || !node_online(nid))
888+
return;
889+
890+
guard(mutex)(&target_lock);
891+
if (target->registered)
892+
return;
893+
894+
hmat_register_target_initiators(target);
895+
hmat_register_target_cache(target);
896+
hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL);
897+
hmat_register_target_perf(target, ACCESS_COORDINATE_CPU);
898+
target->registered = true;
899+
}
900+
901+
static void hmat_register_target(struct memory_target *target)
902+
{
881903
/*
882904
* Devices may belong to either an offline or online
883905
* node, so unconditionally add them.
@@ -895,25 +917,7 @@ static void hmat_register_target(struct memory_target *target)
895917
}
896918
mutex_unlock(&target_lock);
897919

898-
/*
899-
* Skip offline nodes. This can happen when memory
900-
* marked EFI_MEMORY_SP, "specific purpose", is applied
901-
* to all the memory in a proximity domain leading to
902-
* the node being marked offline / unplugged, or if
903-
* memory-only "hotplug" node is offline.
904-
*/
905-
if (nid == NUMA_NO_NODE || !node_online(nid))
906-
return;
907-
908-
mutex_lock(&target_lock);
909-
if (!target->registered) {
910-
hmat_register_target_initiators(target);
911-
hmat_register_target_cache(target);
912-
hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL);
913-
hmat_register_target_perf(target, ACCESS_COORDINATE_CPU);
914-
target->registered = true;
915-
}
916-
mutex_unlock(&target_lock);
920+
hmat_hotplug_target(target);
917921
}
918922

919923
static void hmat_register_targets(void)
@@ -939,7 +943,7 @@ static int hmat_callback(struct notifier_block *self,
939943
if (!target)
940944
return NOTIFY_OK;
941945

942-
hmat_register_target(target);
946+
hmat_hotplug_target(target);
943947
return NOTIFY_OK;
944948
}
945949

0 commit comments

Comments
 (0)