Skip to content

Commit 0b4f78e

Browse files
davejianggregkh
authored andcommitted
acpi/hmat: Fix lockdep warning for hmem_register_resource()
[ Upstream commit 214291c ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent cbdbfc7 commit 0b4f78e

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
@@ -864,10 +864,32 @@ static void hmat_register_target_devices(struct memory_target *target)
864864
}
865865
}
866866

867-
static void hmat_register_target(struct memory_target *target)
867+
static void hmat_hotplug_target(struct memory_target *target)
868868
{
869869
int nid = pxm_to_node(target->memory_pxm);
870870

871+
/*
872+
* Skip offline nodes. This can happen when memory marked EFI_MEMORY_SP,
873+
* "specific purpose", is applied to all the memory in a proximity
874+
* domain leading to * the node being marked offline / unplugged, or if
875+
* memory-only "hotplug" node is offline.
876+
*/
877+
if (nid == NUMA_NO_NODE || !node_online(nid))
878+
return;
879+
880+
guard(mutex)(&target_lock);
881+
if (target->registered)
882+
return;
883+
884+
hmat_register_target_initiators(target);
885+
hmat_register_target_cache(target);
886+
hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL);
887+
hmat_register_target_perf(target, ACCESS_COORDINATE_CPU);
888+
target->registered = true;
889+
}
890+
891+
static void hmat_register_target(struct memory_target *target)
892+
{
871893
/*
872894
* Devices may belong to either an offline or online
873895
* node, so unconditionally add them.
@@ -885,25 +907,7 @@ static void hmat_register_target(struct memory_target *target)
885907
}
886908
mutex_unlock(&target_lock);
887909

888-
/*
889-
* Skip offline nodes. This can happen when memory
890-
* marked EFI_MEMORY_SP, "specific purpose", is applied
891-
* to all the memory in a proximity domain leading to
892-
* the node being marked offline / unplugged, or if
893-
* memory-only "hotplug" node is offline.
894-
*/
895-
if (nid == NUMA_NO_NODE || !node_online(nid))
896-
return;
897-
898-
mutex_lock(&target_lock);
899-
if (!target->registered) {
900-
hmat_register_target_initiators(target);
901-
hmat_register_target_cache(target);
902-
hmat_register_target_perf(target, ACCESS_COORDINATE_LOCAL);
903-
hmat_register_target_perf(target, ACCESS_COORDINATE_CPU);
904-
target->registered = true;
905-
}
906-
mutex_unlock(&target_lock);
910+
hmat_hotplug_target(target);
907911
}
908912

909913
static void hmat_register_targets(void)
@@ -929,7 +933,7 @@ static int hmat_callback(struct notifier_block *self,
929933
if (!target)
930934
return NOTIFY_OK;
931935

932-
hmat_register_target(target);
936+
hmat_hotplug_target(target);
933937
return NOTIFY_OK;
934938
}
935939

0 commit comments

Comments
 (0)