From d53e3bd7f05de8a2cb22080a9ff702705e852862 Mon Sep 17 00:00:00 2001 From: Pingfan Liu Date: Thu, 2 Jan 2025 08:49:11 +0800 Subject: [PATCH] Release 2.4-5 Resolves: https://issues.redhat.com/browse/RHEL-16710 Fix ncurse race issue Signed-off-by: Pingfan Liu --- ...ll-curses-calls-into-display-threads.patch | 260 ++++++++++++++++++ ...-race-on-submitting-display-commands.patch | 32 +++ numatop.spec | 7 +- 3 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 0033-Move-all-curses-calls-into-display-threads.patch create mode 100644 0034-Avoid-race-on-submitting-display-commands.patch diff --git a/0033-Move-all-curses-calls-into-display-threads.patch b/0033-Move-all-curses-calls-into-display-threads.patch new file mode 100644 index 0000000..c2375e0 --- /dev/null +++ b/0033-Move-all-curses-calls-into-display-threads.patch @@ -0,0 +1,260 @@ +From eb42e7eb07892e91939e3875a124d5f485697ae9 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Mon, 18 Nov 2024 08:04:04 -0800 +Subject: [PATCH] Move all curses calls into display threads + +Curses is not thread safe, but currently both the cons and the disp +thread can issue curses calls concurrently. + +Move all curses handling into the display thread. The cons thread +just does the select and pipe handling now. + +Fixes #91 +--- + common/disp.c | 138 +++++++++++++++++++++--------------------- + common/include/disp.h | 4 +- + 2 files changed, 73 insertions(+), 69 deletions(-) + +diff --git a/common/disp.c b/common/disp.c +index ea865c3..78bf9e9 100644 +--- a/common/disp.c ++++ b/common/disp.c +@@ -58,6 +58,7 @@ static cons_ctl_t s_cons_ctl; + static int disp_start(void); + static void* disp_handler(void *); + static void* cons_handler(void *); ++static disp_flag_t handle_getch(cmd_t *cmdp); + + static int mutex_cond_init(pthread_mutex_t *mutex, pthread_cond_t *cond) + { +@@ -465,6 +466,12 @@ disp_handler(void *arg __attribute__((unused))) + uint64_t start_ms; + int64_t diff_ms; + ++ if (!reg_curses_init(B_TRUE)) { ++ goto L_EXIT; ++ } ++ ++ win_fix_init(); ++ + /* + * Wait cons thread to complete initialization. + */ +@@ -509,6 +516,7 @@ disp_handler(void *arg __attribute__((unused))) + s_disp_ctl.flag = DISP_FLAG_NONE; + (void) pthread_mutex_unlock(&s_disp_ctl.mutex); + ++ + diff_ms = current_ms(&g_tvbase) - start_ms; + if (g_run_secs <= diff_ms / MS_SEC) { + g_run_secs = TIME_NSEC_MAX; +@@ -532,6 +540,7 @@ disp_handler(void *arg __attribute__((unused))) + continue; + } + ++ handle_cmd: + switch (flag) { + case DISP_FLAG_QUIT: + debug_print(NULL, 2, +@@ -601,6 +610,12 @@ disp_handler(void *arg __attribute__((unused))) + } + break; + ++ case DISP_FLAG_GETCH: ++ flag = handle_getch(&cmd); ++ if (flag == DISP_FLAG_ERR) ++ goto L_EXIT; ++ goto handle_cmd; ++ + default: + break; + } +@@ -610,7 +625,7 @@ L_EXIT: + if (pagelist_inited) { + page_list_fini(); + } +- ++ reg_curses_fini(); + /* + * Let the perf thread exit first. + */ +@@ -620,6 +635,53 @@ L_EXIT: + return (NULL); + } + ++static disp_flag_t ++handle_getch(cmd_t *cmd_id_p) ++{ ++ int c, cmd_id; ++ unsigned char ch; ++ ++ if ((c = getch()) == ERR) { ++ /* ++ * It's possile if the associated ++ * terminal is lost. ++ */ ++ debug_print(NULL, 2, "cons: " ++ "getch() failed.\n"); ++ return DISP_FLAG_ERR; ++ } ++ ++ ch = tolower((unsigned char)c); ++ dump_write("\n<-- User hit the key '%c' " ++ "(ascii = %d) -->\n", ch, (int)ch); ++ ++ /* These will send the command to itself. */ ++ ++ cmd_id = cmd_id_get(ch); ++ if (cmd_id != CMD_INVALID_ID) { ++ CMD_ID_SET(cmd_id_p, cmd_id); ++ return DISP_FLAG_CMD; ++ } else { ++ /* ++ * Hit the keys 'UP'/'DOWN'/'ENTER' ++ */ ++ switch (ch) { ++ case 2: /* KEY DOWN */ ++ return DISP_FLAG_SCROLLDOWN; ++ ++ case 3: /* KEY UP */ ++ return DISP_FLAG_SCROLLUP; ++ ++ case 13: /* enter. */ ++ return DISP_FLAG_SCROLLENTER; ++ ++ default: ++ break; ++ } ++ } ++ return DISP_FLAG_NONE; ++} ++ + /* + * The handler of 'cons thread' + */ +@@ -627,17 +689,10 @@ L_EXIT: + static void * + cons_handler(void *arg __attribute__((unused))) + { +- int c, cmd_id; + unsigned char ch; + +- if (!reg_curses_init(B_TRUE)) { +- goto L_EXIT; +- } +- +- win_fix_init(); +- + /* +- * Excute "home" command. It shows the NumaTop default page. ++ * Execute "home" command. It shows the NumaTop default page. + */ + disp_go_home(); + +@@ -676,75 +731,22 @@ cons_handler(void *arg __attribute__((unused))) + + CMD_ID_SET(&s_disp_ctl.cmd, + CMD_RESIZE_ID); +- dispthr_flagset_nolock(DISP_FLAG_CMD); ++ dispthr_flagset_nolock(DISP_FLAG_CMD); + +- (void) pthread_mutex_unlock( +- &s_disp_ctl.mutex); ++ (void) pthread_mutex_unlock( ++ &s_disp_ctl.mutex); + } + } + } else { + /* +- * Character is from STDIN. ++ * Character is from STDIN. Tell disp handler to process. + */ +- if ((c = getch()) == ERR) { +- /* +- * It's possile if the associated +- * terminal is lost. +- */ +- debug_print(NULL, 2, "cons: " +- "getch() failed.\n"); +- break; +- } +- +- ch = tolower((unsigned char)c); +- dump_write("\n<-- User hit the key '%c' " +- "(ascii = %d) -->\n", ch, (int)ch); +- +- cmd_id = cmd_id_get(ch); +- if (cmd_id != CMD_INVALID_ID) { +- /* +- * The character is a command. Send +- * the command to 'disp thread'. +- */ +- (void) pthread_mutex_lock( +- &s_disp_ctl.mutex); +- +- CMD_ID_SET(&s_disp_ctl.cmd, cmd_id); +- dispthr_flagset_nolock(DISP_FLAG_CMD); +- +- (void) pthread_mutex_unlock( +- &s_disp_ctl.mutex); +- } else { +- /* +- * Hit the keys 'UP'/'DOWN'/'ENTER' +- */ +- switch (ch) { +- case 2: /* KEY DOWN */ +- dispthr_flagset_lock( +- DISP_FLAG_SCROLLDOWN); +- break; +- +- case 3: /* KEY UP */ +- dispthr_flagset_lock( +- DISP_FLAG_SCROLLUP); +- break; +- +- case 13: /* enter. */ +- dispthr_flagset_lock( +- DISP_FLAG_SCROLLENTER); +- break; +- +- default: +- break; +- } +- } ++ dispthr_flagset_lock(DISP_FLAG_GETCH); + } ++ + } + } + +- reg_curses_fini(); +- +-L_EXIT: + debug_print(NULL, 2, "cons thread is exiting\n"); + return (NULL); + } +diff --git a/common/include/disp.h b/common/include/disp.h +index f9d28de..f934406 100644 +--- a/common/include/disp.h ++++ b/common/include/disp.h +@@ -47,6 +47,7 @@ extern "C" { + + typedef enum { + DISP_FLAG_NONE = 0, ++ DISP_FLAG_ERR, + DISP_FLAG_QUIT, + DISP_FLAG_PROFILING_DATA_READY, + DISP_FLAG_PROFILING_DATA_FAIL, +@@ -59,7 +60,8 @@ typedef enum { + DISP_FLAG_CMD, + DISP_FLAG_SCROLLUP, + DISP_FLAG_SCROLLDOWN, +- DISP_FLAG_SCROLLENTER ++ DISP_FLAG_SCROLLENTER, ++ DISP_FLAG_GETCH + } disp_flag_t; + + typedef struct _disp_ctl { +-- +2.41.0 + diff --git a/0034-Avoid-race-on-submitting-display-commands.patch b/0034-Avoid-race-on-submitting-display-commands.patch new file mode 100644 index 0000000..92e52bf --- /dev/null +++ b/0034-Avoid-race-on-submitting-display-commands.patch @@ -0,0 +1,32 @@ +From 8dfa30ea03111981ce5cbc793960688d93f17b68 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Tue, 19 Nov 2024 11:02:35 -0800 +Subject: [PATCH] Avoid race on submitting display commands + +Doesn't work for quitting, but we can ignore it here. +--- + common/disp.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/common/disp.c b/common/disp.c +index 78bf9e9..c542b77 100644 +--- a/common/disp.c ++++ b/common/disp.c +@@ -193,6 +193,14 @@ disp_consthr_quit(void) + static void + dispthr_flagset_nolock(disp_flag_t flag) + { ++ if (flag != DISP_FLAG_QUIT) { ++ /* Wait in case we the disp thread hasn't processed the flag yet. */ ++ while (*(volatile disp_flag_t *)&s_disp_ctl.flag != DISP_FLAG_NONE) { ++ (void) pthread_mutex_unlock(&s_disp_ctl.mutex); ++ usleep(1); ++ (void) pthread_mutex_lock(&s_disp_ctl.mutex); ++ } ++ } + s_disp_ctl.flag = flag; + (void) pthread_cond_signal(&s_disp_ctl.cond); + } +-- +2.41.0 + diff --git a/numatop.spec b/numatop.spec index 2ba17ad..6bbad52 100644 --- a/numatop.spec +++ b/numatop.spec @@ -3,7 +3,7 @@ Name: numatop Version: 2.4 -Release: 4%{?dist} +Release: 5%{?dist} Summary: Memory access locality characterization and analysis License: BSD @@ -42,6 +42,8 @@ Patch29: 0029-common-use-mount-umount-system-calls-rather-than-usi.patch Patch30: 0030-common-remove-executing-commands-for-directory-and-f.patch Patch31: 0031-powerpc-util-fix-build-warning-cast-LHS-of-expressio.patch Patch32: 0032-common-os-map-Fix-overflow-warning.patch +Patch33: 0033-Move-all-curses-calls-into-display-threads.patch +Patch34: 0034-Avoid-race-on-submitting-display-commands.patch BuildRequires: autoconf @@ -95,6 +97,9 @@ autoreconf --force --install --symlink %changelog +* Thu Jan 2 2025 Pingfan Liu - 2.4.5 +- Fix ncures race issue + * Thu Feb 1 2024 Pingfan Liu - 2.4.1 - Add initial support for EMR