FAILED: patch "[PATCH] ACPI: HMAT: Fix initiator registration for single-initiator" failed to apply to 5.15-stable tree
Subsystems (2)
[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]>.
Possible dependencies:
48d4180939e1 ("ACPI: HMAT: Fix initiator registration for single-initiator systems") 14f16d47561b ("ACPI: HMAT: remove unnecessary variable initialization")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 48d4180939e12c4bd2846f984436d895bb9699ed Mon Sep 17 00:00:00 2001
From: Vishal Verma <[email protected]>
Date: Wed, 16 Nov 2022 16:37:37 -0700
Subject: [PATCH] ACPI: HMAT: Fix initiator registration for single-initiator
systems
In a system with a single initiator node, and one or more memory-only 'target' nodes, the memory-only node(s) would fail to register their initiator node correctly. i.e. in sysfs:
# ls /sys/devices/system/node/node0/access0/targets/ node0
Where as the correct behavior should be:
# ls /sys/devices/system/node/node0/access0/targets/ node0 node1
This happened because hmat_register_target_initiators() uses list_sort() to sort the initiator list, but the sort comparision function (initiator_cmp()) is overloaded to also set the node mask's bits.
In a system with a single initiator, the list is singular, and list_sort elides the comparision helper call. Thus the node mask never gets set, and the subsequent search for the best initiator comes up empty.
Add a new helper to consume the sorted initiator list, and generate the nodemask, decoupling it from the overloaded initiator_cmp() comparision callback. This prevents the singular list corner case naturally, and makes the code easier to follow as well.
drivers/acpi/numa/hmat.c +20 -6
@@ -562,17 +562,26 @@ static int initiator_cmp(void *priv, const struct list_head *a, {struct memory_initiator *ia;struct memory_initiator *ib; -unsigned long *p_nodes = priv; ia = list_entry(a, struct memory_initiator, node); ib = list_entry(b, struct memory_initiator, node); -set_bit (ia->processor_pxm, p_nodes); -set_bit (ib->processor_pxm, p_nodes); -return ia->processor_pxm - ib->processor_pxm; } +static int initiators_to_nodemask (unsigned long *p_nodes) +{ +struct memory_initiator *initiator; + +if (list_empty (&initiators)) +return -ENXIO ; + +list_for_each_entry (initiator, &initiators, node) +set_bit (initiator->processor_pxm, p_nodes); + +return 0 ; +} +static void hmat_register_target_initiators (struct memory_target *target) { static DECLARE_BITMAP(p_nodes, MAX_NUMNODES);
@@ -609,7 +618,10 @@ static void hmat_register_target_initiators(struct memory_target *target)* initiators. */ bitmap_zero (p_nodes,MAX_NUMNODES ); -list_sort (p_nodes, &initiators, initiator_cmp); +list_sort (NULL , &initiators, initiator_cmp); +if (initiators_to_nodemask (p_nodes) <0 ) +return ; +if (!access0done) {for (i =WRITE_LATENCY ; i <=READ_BANDWIDTH ; i++) { loc = localities_types[i];
@@ -643,7 +655,9 @@ static void hmat_register_target_initiators(struct memory_target *target)/* Access 1 ignores Generic Initiators */ bitmap_zero (p_nodes,MAX_NUMNODES ); -list_sort (p_nodes, &initiators, initiator_cmp); +if (initiators_to_nodemask (p_nodes) <0 ) +return ; +for (i =WRITE_LATENCY ; i <=READ_BANDWIDTH ; i++) { loc = localities_types[i];if (!loc)