Resolves: RHEL-223933, Use 30 secs timeout for each LMB removal kernel interface

This commit is contained in:
Than Ngo 2026-08-06 12:14:45 +02:00
parent 6568e180fc
commit b666915bc4
2 changed files with 85 additions and 37 deletions

View File

@ -1,19 +1,23 @@
The drmgr selects the removal LMB based on NUMA node ratio and
calls the kernel interface to remove the each selected LMB. Then
the kernel interface removes the LMB only after all pages are
isolated. But this page isolation can take longer which may affect
the memory removal process. The kernel interface returns to the
user space if sny signals are pending.
commit 4e9a9d74cbf7728e59858dccabc17e8cd24ff778
Author: Haren Myneni <haren@linux.ibm.com>
Date: Mon Aug 3 14:23:55 2026 -0700
So do not allow the kernel interface execute more then 30 secs for
each LMB removal. Setup 30 secs timer and generate SIGUSR1 signal
for each kernel interface.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
---
src/drmgr/common.c | 1 +
src/drmgr/drslot_chrp_mem.c | 68 +++++++++++++++++++++++++++++++++----
2 files changed, 63 insertions(+), 6 deletions(-)
drmgr: Use 30 secs timeout for each LMB removal kernel interface
The drmgr selects the removal LMB based on NUMA node ratio and
calls the kernel interface for each selected LMB. Then the
kernel interface removes the LMB only after all pages are isolated.
But this page isolation can take longer which may affect the
memory removal process. The kernel interface returns to the user
space if any signals are pending.
So do not allow the kernel interface to execute more than 30 secs
for each LMB removal. Setup 30 secs timer to generate SIGUSR1
signal for each kernel interface call.
Signed-off-by: Haren Myneni <haren@linux.ibm.com>
[tyreld: zero .tv_nsec as well at disarm]
Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
diff --git a/src/drmgr/common.c b/src/drmgr/common.c
index 68041a9..70f5d3b 100644
@ -28,10 +32,10 @@ index 68041a9..70f5d3b 100644
/* Now block all remaining signals */
rc = sigprocmask(SIG_SETMASK, &sigset, NULL);
diff --git a/src/drmgr/drslot_chrp_mem.c b/src/drmgr/drslot_chrp_mem.c
index 4a3fe3a..ea8e8ce 100644
index 4a3fe3a..c37c2dc 100644
--- a/src/drmgr/drslot_chrp_mem.c
+++ b/src/drmgr/drslot_chrp_mem.c
@@ -39,6 +39,10 @@
@@ -39,6 +39,16 @@
uint64_t block_sz_bytes = 0;
static char *state_strs[] = {"offline", "online"};
sig_atomic_t numa_mem_timeout = 0;
@ -39,10 +43,16 @@ index 4a3fe3a..ea8e8ce 100644
+struct itimerspec lmb_tval;
+struct sigevent lmb_sevent;
+timer_t lmb_timer;
+
+/*
+ * Timer to generate SIGUSR1 signal for each LMB removal
+ * kernel request
+ */
+#define LMB_REMOVAL_TIMER_SECS 30
static char *usagestr = "-c mem {-a | -r} {-q <quantity> -p {variable_weight | ent_capacity} | {-q <quantity> | -s [<drc_name> | <drc_index>]}}";
@@ -62,6 +66,15 @@ void mem_timeout_handler(int sig)
@@ -62,6 +72,16 @@ void mem_timeout_handler(int sig)
numa_mem_timeout = 1;
}
@ -52,13 +62,14 @@ index 4a3fe3a..ea8e8ce 100644
+ */
+void lmb_rm_timeout_handler(int sig)
+{
+ if (sig == SIGUSR1) lmb_rm_timeout = 1;
+ if (sig == SIGUSR1)
+ lmb_rm_timeout = 1;
+}
+
/**
* report_resource_count
* @brief Report the number of LMBs that were added or removed.
@@ -1461,12 +1474,36 @@ int valid_mem_options(void)
@@ -1461,12 +1481,46 @@ int valid_mem_options(void)
static int remove_lmb_by_index(uint32_t drc_index)
{
char cmdbuf[128];
@ -79,26 +90,57 @@ index 4a3fe3a..ea8e8ce 100644
+ * the kernel request takes longer than 30 secs.
+ */
+ lmb_rm_timeout = 0;
+ lmb_tval.it_value.tv_sec = 30;
+ timer_settime(lmb_timer, 0, &lmb_tval, NULL);
+ lmb_tval.it_value.tv_sec = LMB_REMOVAL_TIMER_SECS;
+ if (timer_settime(lmb_timer, 0, &lmb_tval, NULL)) {
+ say(ERROR, "Set LMB removal timer failed %s\n",
+ strerror(errno));
+ return -errno;
+ }
+
+ rc = do_kernel_dlpar_common(cmdbuf, offset,
+ 1 /* Don't report error */);
+
+ if (!lmb_rm_timeout) {
+ /*
+ * Disable the timer if the kernel request returned before
+ * 30 secs interval.
+ */
+ lmb_tval.it_value.tv_sec = 0;
+ timer_settime(lmb_timer, 0, &lmb_tval, NULL);
+ }
+ /*
+ * Disable the timer in case if the kernel request returned
+ * before 30 secs interval.
+ */
+ lmb_tval.it_value.tv_sec = 0;
+ lmb_tval.it_value.tv_nsec = 0;
+ /*
+ * The caller of this function expects the return value 0 for
+ * LMB remove success and failure for other values. The success
+ * return is considered to increment the number of LMBs removed
+ * which is used to report the total removed LMBs to HMC.
+ * So do not consider the failure of disable timer.
+ */
+ timer_settime(lmb_timer, 0, &lmb_tval, NULL);
+
+ return rc;
}
static int remove_lmb_from_node(struct ppcnuma_node *node, uint32_t count)
@@ -1707,12 +1744,30 @@ static void clear_numa_lmb_links(void)
@@ -1483,10 +1537,16 @@ static int remove_lmb_from_node(struct ppcnuma_node *node, uint32_t count)
unlinked++;
err = remove_lmb_by_index(lmb->drc_index);
- if (err)
- say(WARN, "Can't remove LMB node:%d index:0x%x: %s\n",
- node->node_id, lmb->drc_index, strerror(-err));
- else
+ if (err) {
+ if (lmb_rm_timeout)
+ say(WARN, "LMB remove timeout. node:%d index:0x%x: %s\n",
+ node->node_id, lmb->drc_index,
+ strerror(-err));
+ else
+ say(WARN, "Can't remove LMB node:%d index:0x%x: %s\n",
+ node->node_id, lmb->drc_index,
+ strerror(-err));
+ } else
done++;
}
@@ -1707,12 +1767,33 @@ static void clear_numa_lmb_links(void)
* (with -w option). In the case of LMB removal, the kernel
* interface can run longer until all pages in LMB are isolated
* and can return to the user space if any pending signals.
@ -108,7 +150,7 @@ index 4a3fe3a..ea8e8ce 100644
+ * make progress further. So setup SIGUSR1 30 secs timer for each
+ * LMB kernel removal request.
+ *
+ * This SIGALRM signal is used to exit drmgr in case if the complete
+ * This SIGUSR1 signal is used to exit drmgr in case if the complete
+ * memory removal process takes longer than the timeout value.
*/
static int drmem_timer_setup(void)
@ -119,20 +161,23 @@ index 4a3fe3a..ea8e8ce 100644
+ lmb_sigact.sa_handler = lmb_rm_timeout_handler;
+ sigemptyset(&lmb_sigact.sa_mask);
+ lmb_sigact.sa_flags = 0;
+ sigaction(SIGUSR1, &lmb_sigact, NULL);
+ if (sigaction(SIGUSR1, &lmb_sigact, NULL))
+ return -1;
+
+ lmb_sevent.sigev_notify = SIGEV_SIGNAL;
+ lmb_sevent.sigev_signo = SIGUSR1;
+ lmb_sevent.sigev_value.sival_ptr = &lmb_timer;
+ timer_create(CLOCK_MONOTONIC, &lmb_sevent, &lmb_timer);
+ lmb_tval.it_value.tv_sec = 30;
+ if (timer_create(CLOCK_MONOTONIC, &lmb_sevent, &lmb_timer))
+ return -1;
+
+ lmb_tval.it_value.tv_sec = LMB_REMOVAL_TIMER_SECS;
+ lmb_tval.it_value.tv_nsec = 0;
+ lmb_tval.it_interval.tv_sec = 0;
+ lmb_tval.it_interval.tv_nsec = 0;
if (!usr_timeout)
return 0;
@@ -1770,6 +1825,7 @@ static int numa_based_remove(uint32_t count)
@@ -1770,6 +1851,7 @@ static int numa_based_remove(uint32_t count)
out_free:
free_lmbs(lmb_list);
out_clear:

View File

@ -1,6 +1,6 @@
Name: powerpc-utils
Version: 1.3.13
Release: 5%{?dist}
Release: 6%{?dist}
Summary: PERL-based scripts for maintaining and servicing PowerPC systems
License: GPL-2.0-only
@ -233,6 +233,9 @@ systemctl enable hcn-init.service >/dev/null 2>&1 || :
%changelog
* Thu Aug 06 2026 Than Ngo <than@redhat.com> - 1.3.13-6
- Resolves: RHEL-223933, Use 30 secs timeout for each LMB removal kernel interface
* Thu Jul 16 2026 Than Ngo <than@redhat.com> - 1.3.13-5
- Resolves: RHEL-138523, Add ability to display Resource group
- Resolves: RHEL-184808, Dynamically removing cores from an LPAR is not taking care of NUMA topology