69 lines
2.2 KiB
Diff
69 lines
2.2 KiB
Diff
commit 8e0a9410baba62f16e9b9ac1a7096dc6c704ffa1
|
|
Author: Haren Myneni <haren@linux.ibm.com>
|
|
Date: Mon Feb 9 22:18:59 2026 -0800
|
|
|
|
drmgr: Remove only available LMBs from CPU less NUMA node
|
|
|
|
The current logic in remove_cpuless_lmbs() may remove more LMB
|
|
than requested.
|
|
|
|
todo = (count * node->ratio) / 100; --> can be 0
|
|
todo = min(todo, node->n_lmbs);
|
|
if (!todo && node->n_lmbs)
|
|
todo = (count - this_loop); -> todo may be > node->n_lmbs
|
|
|
|
Removing more lmbs than requested caused a decrement of count
|
|
(unsigned int) integer overflow, eventually leading to the drmgr
|
|
removing all available memory in the system. Existing testing
|
|
exposed the out of memory issue triggered by this counter
|
|
overflow.
|
|
|
|
This patch fixed this logic by adjusting todo per node dynamically
|
|
based on the count value and then determine todo value based on
|
|
number of available LMBs in the node.
|
|
|
|
Signed-off-by: Ryan Whittaker <ryancwmd@linux.ibm.com>
|
|
Reviewed-by: Mingming Cao <mmc@linux.ibm.com>
|
|
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
|
|
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
|
|
|
|
diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c
|
|
index 179fb17..4a36c73 100644
|
|
--- a/src/drmgr/drslot_chrp_mem.c
|
|
+++ b/src/drmgr/drslot_chrp_mem.c
|
|
@@ -1565,11 +1565,16 @@ static int remove_cpuless_lmbs(uint32_t count)
|
|
continue;
|
|
|
|
todo = (count * node->ratio) / 100;
|
|
- todo = min(todo, node->n_lmbs);
|
|
- /* Fix rounded value to 0 */
|
|
- if (!todo && node->n_lmbs)
|
|
+ /*
|
|
+ * Fix rounded value to 0 and fix if a 0 ratio has
|
|
+ * been processed
|
|
+ */
|
|
+ if ((!todo && node->n_lmbs) || (count - this_loop < todo))
|
|
todo = (count - this_loop);
|
|
|
|
+ /* Donot request more than available */
|
|
+ todo = min(todo, node->n_lmbs);
|
|
+
|
|
if (todo)
|
|
todo = remove_lmb_from_node(node, todo);
|
|
|
|
@@ -1583,7 +1588,13 @@ static int remove_cpuless_lmbs(uint32_t count)
|
|
if (!this_loop)
|
|
break;
|
|
|
|
- count -= this_loop;
|
|
+ /*
|
|
+ * Should not happen, but in case prevent integer overflow
|
|
+ */
|
|
+ if (this_loop < count)
|
|
+ count -= this_loop;
|
|
+ else
|
|
+ count = 0;
|
|
}
|
|
|
|
say(DEBUG, "%d / %d LMBs removed from the CPU less nodes\n",
|