import CS numatop-2.4-9.el9

This commit is contained in:
AlmaLinux RelEng Bot 2026-03-30 10:48:26 -04:00
parent 9d4f49b08b
commit be456b6ec5
12 changed files with 1055 additions and 9 deletions

View File

@ -1,7 +1,7 @@
From eb42e7eb07892e91939e3875a124d5f485697ae9 Mon Sep 17 00:00:00 2001
From: Andi Kleen <ak@linux.intel.com>
Date: Mon, 18 Nov 2024 08:04:04 -0800
Subject: [PATCH] Move all curses calls into display threads
Subject: [PATCH 1/5] 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.
@ -256,5 +256,5 @@ index f9d28de..f934406 100644
typedef struct _disp_ctl {
--
2.41.0
2.49.0

View File

@ -1,7 +1,7 @@
From 8dfa30ea03111981ce5cbc793960688d93f17b68 Mon Sep 17 00:00:00 2001
From: Andi Kleen <ak@linux.intel.com>
Date: Tue, 19 Nov 2024 11:02:35 -0800
Subject: [PATCH] Avoid race on submitting display commands
Subject: [PATCH 3/5] Avoid race on submitting display commands
Doesn't work for quitting, but we can ignore it here.
---
@ -28,5 +28,5 @@ index 78bf9e9..c542b77 100644
(void) pthread_cond_signal(&s_disp_ctl.cond);
}
--
2.41.0
2.49.0

View File

@ -0,0 +1,210 @@
From 5f303ce5c19c5d2f17970797ab467aa32dc93cdc Mon Sep 17 00:00:00 2001
From: Andi Kleen <ak@linux.intel.com>
Date: Tue, 19 Nov 2024 10:29:44 -0800
Subject: [PATCH 4/5] Increase PID column width
Newer Linux distributions enable a >16bit pid_t, so need more digits to
display.
Fixes #94
---
common/win.c | 44 ++++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/common/win.c b/common/win.c
index c3e8492..03d096d 100644
--- a/common/win.c
+++ b/common/win.c
@@ -68,7 +68,7 @@ topnproc_caption_build(char *buf, int size)
case SORT_KEY_CPU:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_CPU);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RPI,
CAPTION_LPI, CAPTION_RL, CAPTION_CPI, tmp);
break;
@@ -76,7 +76,7 @@ topnproc_caption_build(char *buf, int size)
case SORT_KEY_CPI:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_CPI);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RPI,
CAPTION_LPI, CAPTION_RL, tmp, CAPTION_CPU);
break;
@@ -84,7 +84,7 @@ topnproc_caption_build(char *buf, int size)
case SORT_KEY_RPI:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_RPI);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, tmp,
CAPTION_LPI, CAPTION_RL, CAPTION_CPI, CAPTION_CPU);
break;
@@ -92,7 +92,7 @@ topnproc_caption_build(char *buf, int size)
case SORT_KEY_LPI:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_LPI);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RPI,
tmp, CAPTION_RL, CAPTION_CPI, CAPTION_CPU);
break;
@@ -100,14 +100,14 @@ topnproc_caption_build(char *buf, int size)
case SORT_KEY_RL:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_RL);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RPI,
CAPTION_LPI, tmp, CAPTION_CPI, CAPTION_CPU);
break;
default:
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RPI,
CAPTION_LPI, CAPTION_RL, CAPTION_CPI, CAPTION_CPU);
break;
@@ -120,7 +120,7 @@ topnproc_data_build(char *buf, int size, topnproc_line_t *line)
win_countvalue_t *value = &line->value;
(void) snprintf(buf, size,
- "%6d%15s%11.1f%11.1f%11.1f%11.2f%10.1f",
+ "%10d%15s%11.1f%11.1f%11.1f%11.2f%10.1f",
line->pid, line->proc_name, value->rpi, value->lpi,
value->rl, value->cpi, value->cpu * 100);
}
@@ -164,7 +164,7 @@ rawnum_caption_build(char *buf, int size)
case SORT_KEY_CPU:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_CPU);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RMA,
CAPTION_LMA, CAPTION_RL, CAPTION_CPI, tmp);
break;
@@ -172,7 +172,7 @@ rawnum_caption_build(char *buf, int size)
case SORT_KEY_CPI:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_CPI);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RMA,
CAPTION_LMA, CAPTION_RL, tmp, CAPTION_CPU);
break;
@@ -180,7 +180,7 @@ rawnum_caption_build(char *buf, int size)
case SORT_KEY_RMA:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_RMA);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, tmp,
CAPTION_LMA, CAPTION_RL, CAPTION_CPI, CAPTION_CPU);
break;
@@ -188,7 +188,7 @@ rawnum_caption_build(char *buf, int size)
case SORT_KEY_LMA:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_LMA);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RMA,
tmp, CAPTION_RL, CAPTION_CPI, CAPTION_CPU);
break;
@@ -196,14 +196,14 @@ rawnum_caption_build(char *buf, int size)
case SORT_KEY_RL:
(void) snprintf(tmp, sizeof (tmp), "*%s", CAPTION_RL);
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RMA,
CAPTION_LMA, tmp, CAPTION_CPI, CAPTION_CPU);
break;
default:
(void) snprintf(buf, size,
- "%6s%15s%11s%11s%11s%11s%11s",
+ "%10s%15s%11s%11s%11s%11s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RMA,
CAPTION_LMA, CAPTION_RL, CAPTION_CPI, CAPTION_CPU);
break;
@@ -216,7 +216,7 @@ rawnum_data_build(char *buf, int size, topnproc_line_t *line)
win_countvalue_t *value = &line->value;
(void) snprintf(buf, size,
- "%6d%15s%11.1f%11.1f%11.1f%11.2f%10.1f",
+ "%10d%15s%11.1f%11.1f%11.1f%11.2f%10.1f",
line->pid, line->proc_name, value->rma, value->lma,
value->rl, value->cpi, value->cpu * 100);
}
@@ -1154,7 +1154,7 @@ static void
topnlwp_caption_build(char *buf, int size)
{
(void) snprintf(buf, size,
- "%6s%10s%10s%11s%11s%10s%10s%10s",
+ "%10s%10s%10s%11s%11s%10s%10s%10s",
CAPTION_LWP, CAPTION_RPI, CAPTION_LPI,
CAPTION_RMA, CAPTION_LMA, CAPTION_RL,
CAPTION_CPI, CAPTION_CPU);
@@ -1169,7 +1169,7 @@ topnlwp_data_build(char *buf, int size, topnlwp_line_t *line)
(void) snprintf(tmp, sizeof (tmp), "%d", line->lwpid);
(void) snprintf(buf, size,
- "%6s%10.1f%10.1f%11.1f%11.1f%10.1f%10.2f%9.1f",
+ "%10s%10.1f%10.1f%11.1f%11.1f%10.1f%10.2f%9.1f",
tmp, value->rpi, value->lpi, value->rma,
value->lma, value->rl, value->cpi, value->cpu * 100);
}
@@ -2859,7 +2859,7 @@ pqos_cmt_proc_data_build(char *buf, int size,
snprintf(tmp, sizeof(tmp), "*%s", id);
snprintf(buf, size,
- "%6s%15s%11.1f%11.1f%21.1f%10.1f",
+ "%10s%15s%11.1f%11.1f%21.1f%10.1f",
tmp, line->proc_name,
value->rma, value->lma,
ratio(line->llc_occupancy,
@@ -2970,12 +2970,12 @@ pqos_cmt_caption_build(int lwpid, char *buf, int size)
{
if (lwpid == 0)
snprintf(buf, size,
- "%6s%15s%11s%11s%21s%11s",
+ "%10s%15s%11s%11s%21s%11s",
CAPTION_PID, CAPTION_PROC, CAPTION_RMA, CAPTION_LMA,
CAPTION_LLC_OCCUPANCY, CAPTION_CPU);
else
snprintf(buf, size,
- "%6s%15s%11s%11s%21s%11s",
+ "%10s%15s%11s%11s%21s%11s",
CAPTION_LWP, CAPTION_PROC, CAPTION_RMA, CAPTION_LMA,
CAPTION_LLC_OCCUPANCY, CAPTION_CPU);
}
@@ -3183,7 +3183,7 @@ pqos_mbm_proc_data_build(char *buf, int size,
ratio(line->localbw_scaled, 1048576));
snprintf(buf, size,
- "%6s%15s%10.1f%10.1f%14s%14s%9.1f",
+ "%10s%15s%10.1f%10.1f%14s%14s%9.1f",
id, line->proc_name,
value->rma, value->lma,
total_bw, local_bw,
@@ -3295,12 +3295,12 @@ pqos_mbm_caption_build(int lwpid, char *buf, int size)
{
if (lwpid == 0)
snprintf(buf, size,
- "%6s%15s%10s%10s%14s%14s%10s",
+ "%10s%15s%10s%10s%14s%14s%10s",
CAPTION_PID, CAPTION_PROC, CAPTION_RMA, CAPTION_LMA,
CAPTION_TOTAL_BW, CAPTION_LOCAL_BW, CAPTION_CPU);
else
snprintf(buf, size,
- "%6s%15s%10s%10s%14s%14s%10s",
+ "%10s%15s%10s%10s%14s%14s%10s",
CAPTION_LWP, CAPTION_PROC, CAPTION_RMA, CAPTION_LMA,
CAPTION_TOTAL_BW, CAPTION_LOCAL_BW, CAPTION_CPU);
}
--
2.49.0

View File

@ -0,0 +1,37 @@
From 636bf0ee924034d51e63a20325353f2e9384b3de Mon Sep 17 00:00:00 2001
From: Sandipan Das <sandipan.das@amd.com>
Date: Thu, 10 Jul 2025 11:57:03 +0530
Subject: [PATCH 5/5] common: Ignore samples for exiting tasks
After the inclusion of Linux commit 1d953111b648 ("perf/core: Don't
report zero PIDs for exiting tasks"), perf samples will report PID as
-1 for exiting tasks.
Such samples lead to segmentation faults during process lookup when
proc_find_nolock() is called with -1 as the PID. Process data at the
the hash table index returned by PROC_HASHTBL_INDEX() is invalid and
any dereference of the corresponding track_proc_t pointer results in
a bad access. Hence, ignore samples for exiting tasks.
Fixes: 972a9d0 ("Reconstruct code for better OS-independent.")
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
---
common/os/pfwrapper.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/os/pfwrapper.c b/common/os/pfwrapper.c
index 10042d9..780458e 100644
--- a/common/os/pfwrapper.c
+++ b/common/os/pfwrapper.c
@@ -497,7 +497,7 @@ ll_sample_read(struct perf_event_mmap_page *mhdr, int size,
* { u64 data_src; }
* };
*/
- if (mmap_buffer_read(mhdr, &id, sizeof (id)) == -1) {
+ if (mmap_buffer_read(mhdr, &id, sizeof (id)) == -1 || id.pid == -1U) {
debug_print(NULL, 2, "ll_sample_read: read pid/tid failed.\n");
goto L_EXIT;
}
--
2.49.0

View File

@ -0,0 +1,31 @@
From 69333ce658e1895241f91f187e12e4996147e196 Mon Sep 17 00:00:00 2001
From: Sandipan Das <sandipan.das@amd.com>
Date: Mon, 30 Jun 2025 12:08:28 +0530
Subject: [PATCH 1/6] common: Fix upper bound for nodes
os_sysfs_node_enum() sets num to the number of NUMA nodes discovered.
The upper bound for num is NNODES_MAX so fail only for cases where
num is strictly greater than the upper bound.
Fixes: 972a9d0 ("Reconstruct code for better OS-independent.")
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
---
common/os/node.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/os/node.c b/common/os/node.c
index f384e3b..10db693 100644
--- a/common/os/node.c
+++ b/common/os/node.c
@@ -228,7 +228,7 @@ node_group_refresh(boolean_t init)
if (!os_sysfs_node_enum(node_arr, NNODES_MAX, &num)) {
goto L_EXIT;
}
- if (num < 0 || num >= NNODES_MAX) {
+ if (num < 0 || num > NNODES_MAX) {
goto L_EXIT;
}
--
2.49.0

View File

@ -0,0 +1,31 @@
From 700351ff9e11840caa42b7b9f56c2400116dc30b Mon Sep 17 00:00:00 2001
From: Sandipan Das <sandipan.das@amd.com>
Date: Mon, 30 Jun 2025 11:16:49 +0530
Subject: [PATCH 2/6] common: Fix upper bound for CPUs per node
os_sysfs_cpu_enum() sets num to the number of online CPUs discovered.
The upper bound for num is NCPUS_NODE_MAX so fail only for cases where
num is strictly greater than NCPUS_NODE_MAX.
Fixes: 972a9d0 ("Reconstruct code for better OS-independent.")
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
---
common/os/node.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/os/node.c b/common/os/node.c
index 10db693..ab0c90d 100644
--- a/common/os/node.c
+++ b/common/os/node.c
@@ -167,7 +167,7 @@ cpu_refresh(boolean_t init)
if (!os_sysfs_cpu_enum(node->nid, cpu_arr, NCPUS_NODE_MAX, &num)) {
return (-1);
}
- if (num < 0 || num >= NCPUS_NODE_MAX) {
+ if (num < 0 || num > NCPUS_NODE_MAX) {
return (-1);
}
--
2.49.0

View File

@ -0,0 +1,345 @@
From 4740ef47cf753420244111df4878cd7128380f17 Mon Sep 17 00:00:00 2001
From: Sandipan Das <sandipan.das@amd.com>
Date: Fri, 27 Jun 2025 15:24:42 +0530
Subject: [PATCH 3/6] common: Resolve max count of nodes at runtime
Replace statically defined NNODES_MAX with a variable which is set at
runtime. Use libnuma helpers to determine the OS-defined limits for the
maximum possible number of NUMA nodes in the the system.
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
---
common/include/os/node.h | 2 +-
common/include/types.h | 5 ++--
common/numatop.c | 2 +-
common/os/node.c | 52 +++++++++++++++++++++++++++-------------
common/os/os_perf.c | 4 ++--
common/os/os_util.c | 2 +-
common/win.c | 15 ++++++++----
7 files changed, 54 insertions(+), 28 deletions(-)
diff --git a/common/include/os/node.h b/common/include/os/node.h
index da1ba7c..2c21556 100644
--- a/common/include/os/node.h
+++ b/common/include/os/node.h
@@ -101,7 +101,7 @@ typedef struct _node {
typedef struct _node_group {
pthread_mutex_t mutex;
- node_t nodes[NNODES_MAX];
+ node_t *nodes;
int nnodes;
int cpuid_max;
int intval_ms;
diff --git a/common/include/types.h b/common/include/types.h
index 05b411a..e688225 100644
--- a/common/include/types.h
+++ b/common/include/types.h
@@ -115,13 +115,14 @@ typedef enum {
#define UI_COUNT_NUM 5
-#define NNODES_MAX 64
#define NCPUS_NODE_MAX 256
-#define NCPUS_MAX (NNODES_MAX * NCPUS_NODE_MAX)
+#define NCPUS_MAX (nnodes_max * NCPUS_NODE_MAX)
#define NPROCS_NAX 4096
#define LL_THRESH 128
#define LL_PERIOD 1000
+extern int nnodes_max;
+
typedef struct _count_value {
uint64_t counts[PERF_COUNT_NUM];
} count_value_t;
diff --git a/common/numatop.c b/common/numatop.c
index 122c187..c5c0580 100644
--- a/common/numatop.c
+++ b/common/numatop.c
@@ -236,7 +236,7 @@ main(int argc, char *argv[])
if (node_group_init() != 0) {
stderr_print("The node/cpu number is out of range, \n"
"numatop supports up to %d nodes and %d CPUs\n",
- NNODES_MAX, NCPUS_MAX);
+ nnodes_max, NCPUS_MAX);
goto L_EXIT5;
}
diff --git a/common/os/node.c b/common/os/node.c
index ab0c90d..c2ca7a7 100644
--- a/common/os/node.c
+++ b/common/os/node.c
@@ -36,6 +36,7 @@
#include <pthread.h>
#include <string.h>
#include <assert.h>
+#include <numa.h>
#include "../include/types.h"
#include "../include/util.h"
#include "../include/ui_perf_map.h"
@@ -46,6 +47,8 @@
static node_group_t s_node_group;
int g_ncpus;
+int nnodes_max;
+
static void
node_init(node_t *node, int nid, boolean_t hotadd)
{
@@ -79,13 +82,22 @@ node_group_init(void)
int i;
node_t *node;
+ if (numa_available() < 0)
+ return (-1);
+
+ nnodes_max = numa_num_possible_nodes();
+
(void) memset(&s_node_group, 0, sizeof (node_group_t));
if (pthread_mutex_init(&s_node_group.mutex, NULL) != 0) {
return (-1);
}
+ if ((s_node_group.nodes = zalloc(nnodes_max * sizeof(node_t))) == NULL) {
+ return (-1);
+ }
+
s_node_group.inited = B_TRUE;
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
node_init(node, INVALID_NID, B_FALSE);
}
@@ -102,12 +114,13 @@ node_group_reset(void)
node_t *node;
int i;
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
node_fini(node);
}
s_node_group.nnodes = 0;
+ free(s_node_group.nodes);
}
/*
@@ -161,7 +174,7 @@ cpu_refresh(boolean_t init)
int cpu_arr[NCPUS_NODE_MAX];
node_t *node;
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (NODE_VALID(node)) {
if (!os_sysfs_cpu_enum(node->nid, cpu_arr, NCPUS_NODE_MAX, &num)) {
@@ -199,7 +212,7 @@ meminfo_refresh(void)
int i;
node_t *node;
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (NODE_VALID(node)) {
if (!os_sysfs_meminfo(node->nid, &node->meminfo)) {
@@ -220,19 +233,23 @@ meminfo_refresh(void)
int
node_group_refresh(boolean_t init)
{
- int node_arr[NNODES_MAX];
- int num, i, j, ret = -1;
+ int *node_arr, num, i, j, ret = -1;
node_t *node;
node_group_lock();
- if (!os_sysfs_node_enum(node_arr, NNODES_MAX, &num)) {
+
+ if ((node_arr = zalloc(nnodes_max * sizeof(int))) == NULL) {
+ goto L_EXIT;
+ }
+
+ if (!os_sysfs_node_enum(node_arr, nnodes_max, &num)) {
goto L_EXIT;
}
- if (num < 0 || num > NNODES_MAX) {
+ if (num < 0 || num > nnodes_max) {
goto L_EXIT;
}
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (NODE_VALID(node)) {
if ((j = nid_find(node->nid, node_arr, num)) == -1) {
@@ -244,7 +261,7 @@ node_group_refresh(boolean_t init)
}
}
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (!NODE_VALID(node)) {
if ((j = nid_find(i, node_arr, num)) >= 0) {
@@ -272,6 +289,7 @@ node_group_refresh(boolean_t init)
ret = 0;
L_EXIT:
+ free(node_arr);
node_group_unlock();
return (ret);
}
@@ -313,7 +331,7 @@ node_by_cpu(int cpuid)
return (NULL);
}
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (!NODE_VALID(node)) {
continue;
@@ -386,7 +404,7 @@ node_cpu_traverse(pfn_perf_cpu_op_t func, void *arg, boolean_t err_ret,
perf_cpu_t *cpu;
int i, j, ret;
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (!NODE_VALID(node)) {
continue;
@@ -461,7 +479,7 @@ node_countval_sum(count_value_t *countval_arr, int nid,
return (countval_sum(countval_arr, nid, ui_count_id));
}
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
value += countval_sum(countval_arr, i, ui_count_id);
}
@@ -486,7 +504,7 @@ node_profiling_clear(void)
node_t *node;
int i;
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
(void) memset(&node->countval, 0, sizeof (count_value_t));
}
@@ -498,7 +516,7 @@ node_valid_get(int node_idx)
int i, nvalid = 0;
node_t *node;
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (NODE_VALID(node)) {
if (node_idx == nvalid) {
@@ -537,7 +555,7 @@ node_qpi_init(void)
node_group_lock();
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (NODE_VALID(node) && (qpi_num > 0)) {
memcpy(node->qpi.qpi_info, qpi_tmp,
@@ -566,7 +584,7 @@ node_imc_init(void)
node_group_lock();
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (NODE_VALID(node) && (imc_num > 0)) {
memcpy(node->imc.imc_info, imc_tmp,
diff --git a/common/os/os_perf.c b/common/os/os_perf.c
index d8d634f..9ea93ea 100644
--- a/common/os/os_perf.c
+++ b/common/os/os_perf.c
@@ -1025,7 +1025,7 @@ uncore_stop_all(void)
node_t *node;
int i;
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (NODE_VALID(node)) {
if (node->qpi.qpi_num > 0)
@@ -1455,7 +1455,7 @@ int os_uncore_stop(perf_ctl_t *ctl __attribute__((unused)),
pf_uncoreimc_free(node);
}
} else {
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (NODE_VALID(node)) {
if (node->qpi.qpi_num > 0)
diff --git a/common/os/os_util.c b/common/os/os_util.c
index 0b862c2..ec3f6e5 100644
--- a/common/os/os_util.c
+++ b/common/os/os_util.c
@@ -863,7 +863,7 @@ static uint64_t cmt_field_value(char *dir, const char *field, int nid)
int i;
if (nid == -1) {
- for (i = 0; i < NNODES_MAX; i++) {
+ for (i = 0; i < nnodes_max; i++) {
if (cmt_task_node_value(dir, i, field,
&tmp) == 0)
val += tmp;
diff --git a/common/win.c b/common/win.c
index 03d096d..dad13d1 100644
--- a/common/win.c
+++ b/common/win.c
@@ -2714,7 +2714,7 @@ accdst_data_show(track_proc_t *proc, dyn_accdst_t *dyn, boolean_t *note_out)
void **addr_arr = NULL;
int *lat_arr = NULL;
int addr_num, i, nnodes, naccess_total = 0;
- map_nodedst_t nodedst_arr[NNODES_MAX];
+ map_nodedst_t *nodedst_arr;
accdst_line_t *lines;
char content[WIN_LINECHAR_MAX], intval_buf[16];
boolean_t ret = B_FALSE;
@@ -2728,14 +2728,19 @@ accdst_data_show(track_proc_t *proc, dyn_accdst_t *dyn, boolean_t *note_out)
return (B_FALSE);
}
+ nodedst_arr = (map_nodedst_t *) malloc(sizeof (map_nodedst_t) * nnodes_max);
+ if (!nodedst_arr) {
+ goto L_EXIT;
+ }
+
if (llrec2addr(proc, lwp, &addr_arr, &lat_arr, &addr_num) != 0) {
goto L_EXIT;
}
- (void) memset(nodedst_arr, 0, sizeof (map_nodedst_t) * NNODES_MAX);
+ (void) memset(nodedst_arr, 0, sizeof (map_nodedst_t) * nnodes_max);
if (addr_num > 0) {
if (map_addr2nodedst(proc->pid, addr_arr, lat_arr, addr_num,
- nodedst_arr, NNODES_MAX, &naccess_total) != 0) {
+ nodedst_arr, nnodes_max, &naccess_total) != 0) {
goto L_EXIT;
}
}
@@ -2784,7 +2789,7 @@ accdst_data_show(track_proc_t *proc, dyn_accdst_t *dyn, boolean_t *note_out)
* Save the per-node data with metrics in scrolling buffer.
*/
for (i = 0; i < nnodes; i++) {
- accdst_data_save(nodedst_arr, NNODES_MAX, naccess_total, i,
+ accdst_data_save(nodedst_arr, nnodes_max, naccess_total, i,
&lines[i]);
}
@@ -2799,6 +2804,8 @@ accdst_data_show(track_proc_t *proc, dyn_accdst_t *dyn, boolean_t *note_out)
reg_refresh_nout(r);
L_EXIT:
+ free(nodedst_arr);
+
if (lwp != NULL) {
lwp_refcount_dec(lwp);
}
--
2.49.0

View File

@ -0,0 +1,105 @@
From ebe98ffcc2517fa7e0a251914c52274e8a378b1c Mon Sep 17 00:00:00 2001
From: Sandipan Das <sandipan.das@amd.com>
Date: Fri, 27 Jun 2025 15:47:59 +0530
Subject: [PATCH 4/6] common: Resolve max count of CPUs at runtime
Replace statically defined NCPUS_MAX with a variable which is set at
runtime. Use libnuma helpers to determine the OS-defined limits for the
maximum possible number of CPUs in the the system.
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
---
common/include/types.h | 2 +-
common/numatop.c | 2 +-
common/os/node.c | 2 ++
common/os/os_util.c | 16 ++++++++++------
4 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/common/include/types.h b/common/include/types.h
index e688225..eb64fb1 100644
--- a/common/include/types.h
+++ b/common/include/types.h
@@ -116,12 +116,12 @@ typedef enum {
#define UI_COUNT_NUM 5
#define NCPUS_NODE_MAX 256
-#define NCPUS_MAX (nnodes_max * NCPUS_NODE_MAX)
#define NPROCS_NAX 4096
#define LL_THRESH 128
#define LL_PERIOD 1000
extern int nnodes_max;
+extern int ncpus_max;
typedef struct _count_value {
uint64_t counts[PERF_COUNT_NUM];
diff --git a/common/numatop.c b/common/numatop.c
index c5c0580..2e95378 100644
--- a/common/numatop.c
+++ b/common/numatop.c
@@ -236,7 +236,7 @@ main(int argc, char *argv[])
if (node_group_init() != 0) {
stderr_print("The node/cpu number is out of range, \n"
"numatop supports up to %d nodes and %d CPUs\n",
- nnodes_max, NCPUS_MAX);
+ nnodes_max, ncpus_max);
goto L_EXIT5;
}
diff --git a/common/os/node.c b/common/os/node.c
index c2ca7a7..f79bcdf 100644
--- a/common/os/node.c
+++ b/common/os/node.c
@@ -48,6 +48,7 @@ static node_group_t s_node_group;
int g_ncpus;
int nnodes_max;
+int ncpus_max;
static void
node_init(node_t *node, int nid, boolean_t hotadd)
@@ -86,6 +87,7 @@ node_group_init(void)
return (-1);
nnodes_max = numa_num_possible_nodes();
+ ncpus_max = numa_num_possible_cpus();
(void) memset(&s_node_group, 0, sizeof (node_group_t));
if (pthread_mutex_init(&s_node_group.mutex, NULL) != 0) {
diff --git a/common/os/os_util.c b/common/os/os_util.c
index ec3f6e5..c836e89 100644
--- a/common/os/os_util.c
+++ b/common/os/os_util.c
@@ -470,19 +470,23 @@ os_sysfs_cpu_enum(int nid, int *cpu_arr, int arr_size, int *num)
int
os_sysfs_online_ncpus(void)
{
- int cpu_arr[NCPUS_MAX], num;
+ int *cpu_arr, num, ret = -1;
char path[PATH_MAX];
- if (sysconf(_SC_NPROCESSORS_CONF) > NCPUS_MAX) {
+ cpu_arr = (int *) malloc(ncpus_max * sizeof(int));
+ if (!cpu_arr)
return (-1);
- }
snprintf(path, PATH_MAX, "/sys/devices/system/cpu/online");
- if (!file_int_extract(path, cpu_arr, NCPUS_MAX, &num)) {
- return (-1);
+ if (!file_int_extract(path, cpu_arr, ncpus_max, &num)) {
+ goto L_EXIT;
}
- return (num);
+ ret = num;
+
+L_EXIT:
+ free(cpu_arr);
+ return (ret);
}
static boolean_t
--
2.49.0

View File

@ -0,0 +1,223 @@
From 00128bb30fb1b88bf2c7421b2a5a759dcffacb32 Mon Sep 17 00:00:00 2001
From: Sandipan Das <sandipan.das@amd.com>
Date: Mon, 30 Jun 2025 18:42:33 +0530
Subject: [PATCH 5/6] common: Resolve max count of CPUs per node at runtime
Replace statically defined NCPUS_NODE_MAX with the previously introduced
ncpus_max. Technically, ncpus_max denotes the maximum possible number of
CPUs in a system but it can also serve as the maximum possible number of
CPUs per NUMA node because of the following reasons.
* CPUs may not be uniformly distributed across NUMA nodes.
* Some NUMA nodes may not have any CPUs associated with them.
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
---
common/include/os/node.h | 2 +-
common/include/types.h | 1 -
common/os/node.c | 72 ++++++++++++++++++++++++++++------------
common/os/os_win.c | 2 +-
4 files changed, 53 insertions(+), 24 deletions(-)
diff --git a/common/include/os/node.h b/common/include/os/node.h
index 2c21556..0b3c362 100644
--- a/common/include/os/node.h
+++ b/common/include/os/node.h
@@ -90,7 +90,7 @@ typedef struct _node_imc {
typedef struct _node {
int nid;
int ncpus;
- perf_cpu_t cpus[NCPUS_NODE_MAX];
+ perf_cpu_t *cpus;
count_value_t countval;
node_meminfo_t meminfo;
node_qpi_t qpi;
diff --git a/common/include/types.h b/common/include/types.h
index eb64fb1..1d1545d 100644
--- a/common/include/types.h
+++ b/common/include/types.h
@@ -115,7 +115,6 @@ typedef enum {
#define UI_COUNT_NUM 5
-#define NCPUS_NODE_MAX 256
#define NPROCS_NAX 4096
#define LL_THRESH 128
#define LL_PERIOD 1000
diff --git a/common/os/node.c b/common/os/node.c
index f79bcdf..cb8c38a 100644
--- a/common/os/node.c
+++ b/common/os/node.c
@@ -50,20 +50,34 @@ int g_ncpus;
int nnodes_max;
int ncpus_max;
-static void
+static int
node_init(node_t *node, int nid, boolean_t hotadd)
{
memset(node, 0, sizeof (node_t));
- os_perf_cpuarr_init(node->cpus, NCPUS_NODE_MAX, hotadd);
node->nid = nid;
node->hotadd = hotadd;
+ if (!NODE_VALID(node)) {
+ return 0;
+ }
+
+ if ((node->cpus = zalloc(ncpus_max * sizeof(perf_cpu_t))) == NULL) {
+ return (-1);
+ }
+
+ os_perf_cpuarr_init(node->cpus, ncpus_max, hotadd);
+ return 0;
}
static void
node_fini(node_t *node)
{
- os_perf_cpuarr_fini(node->cpus, NCPUS_NODE_MAX, B_FALSE);
+ if (!NODE_VALID(node)) {
+ return;
+ }
+
+ os_perf_cpuarr_fini(node->cpus, ncpus_max, B_FALSE);
node->ncpus = 0;
+ free(node->cpus);
node->nid = INVALID_NID;
}
@@ -71,7 +85,7 @@ static void
node_hotremove(node_t *node)
{
node->hotremove = B_TRUE;
- os_perf_cpuarr_fini(node->cpus, NCPUS_NODE_MAX, B_TRUE);
+ os_perf_cpuarr_fini(node->cpus, ncpus_max, B_TRUE);
}
/*
@@ -101,10 +115,20 @@ node_group_init(void)
s_node_group.inited = B_TRUE;
for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
- node_init(node, INVALID_NID, B_FALSE);
+ if (node_init(node, INVALID_NID, B_FALSE)) {
+ goto L_EXIT;
+ }
}
return (node_group_refresh(B_TRUE));
+
+L_EXIT:
+ for (i = i - 1; i >= 0; i--) {
+ node = node_get(i);
+ node_fini(node);
+ }
+
+ return (-1);
}
/*
@@ -172,23 +196,27 @@ cpuid_max_get(int *cpu_arr, int num)
static int
cpu_refresh(boolean_t init)
{
- int i, j, num, cpuid_max = -1;
- int cpu_arr[NCPUS_NODE_MAX];
+ int i, j, num, cpuid_max = -1, ret = -1;
+ int *cpu_arr;
node_t *node;
+ if ((cpu_arr = zalloc(ncpus_max * sizeof(int))) == NULL) {
+ return (-1);
+ }
+
for (i = 0; i < nnodes_max; i++) {
node = node_get(i);
if (NODE_VALID(node)) {
- if (!os_sysfs_cpu_enum(node->nid, cpu_arr, NCPUS_NODE_MAX, &num)) {
- return (-1);
+ if (!os_sysfs_cpu_enum(node->nid, cpu_arr, ncpus_max, &num)) {
+ goto L_EXIT;
}
- if (num < 0 || num > NCPUS_NODE_MAX) {
- return (-1);
+ if (num < 0 || num > ncpus_max) {
+ goto L_EXIT;
}
- if (os_perf_cpuarr_refresh(node->cpus, NCPUS_NODE_MAX, cpu_arr,
+ if (os_perf_cpuarr_refresh(node->cpus, ncpus_max, cpu_arr,
num, init) != 0) {
- return (-1);
+ goto L_EXIT;
}
node->ncpus = num;
@@ -205,7 +233,11 @@ cpu_refresh(boolean_t init)
/* Refresh the number of online CPUs */
g_ncpus = os_sysfs_online_ncpus();
- return (0);
+ ret = 0;
+
+L_EXIT:
+ free(cpu_arr);
+ return (ret);
}
static int
@@ -268,10 +300,8 @@ node_group_refresh(boolean_t init)
if (!NODE_VALID(node)) {
if ((j = nid_find(i, node_arr, num)) >= 0) {
ASSERT(node_arr[j] == i);
- if (init) {
- node_init(node, i, B_FALSE);
- } else {
- node_init(node, i, B_TRUE);
+ if (node_init(node, i, init ? B_FALSE : B_TRUE)) {
+ goto L_EXIT;
}
s_node_group.nnodes++;
@@ -339,7 +369,7 @@ node_by_cpu(int cpuid)
continue;
}
- for (j = 0; j < NCPUS_NODE_MAX; j++) {
+ for (j = 0; j < ncpus_max; j++) {
if (cpuid == node->cpus[j].cpuid) {
return (node);
}
@@ -412,7 +442,7 @@ node_cpu_traverse(pfn_perf_cpu_op_t func, void *arg, boolean_t err_ret,
continue;
}
- for (j = 0; j < NCPUS_NODE_MAX; j++) {
+ for (j = 0; j < ncpus_max; j++) {
cpu = &node->cpus[j];
if (cpu->hotremove) {
pf_resource_free(cpu);
@@ -455,7 +485,7 @@ countval_sum(count_value_t *countval_arr, int nid,
return (0);
}
- for (i = 0; i < NCPUS_NODE_MAX; i++) {
+ for (i = 0; i < ncpus_max; i++) {
if (num >= node->ncpus) {
break;
}
diff --git a/common/os/os_win.c b/common/os/os_win.c
index 9aaefae..bd34388 100644
--- a/common/os/os_win.c
+++ b/common/os/os_win.c
@@ -152,7 +152,7 @@ node_cpu_string(node_t *node, char *s1, int size)
}
j = 0;
- for (i = 0; (i < NCPUS_NODE_MAX) && (j < ncpus); i++) {
+ for (i = 0; (i < ncpus_max) && (j < ncpus); i++) {
if ((cpus[i].cpuid != INVALID_CPUID) && (!cpus[i].hotremove)) {
cpuid_arr[j++] = cpus[i].cpuid;
}
--
2.49.0

View File

@ -0,0 +1,27 @@
From 50b24cd2c9bdd524b8a9d842831e46b176de3265 Mon Sep 17 00:00:00 2001
From: Sandipan Das <sandipan.das@amd.com>
Date: Mon, 30 Jun 2025 19:03:47 +0530
Subject: [PATCH 6/6] common: Remove unused NPROCS_NAX
Remove the definition of NPROCS_NAX as it is unused.
Signed-off-by: Sandipan Das <sandipan.das@amd.com>
---
common/include/types.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/common/include/types.h b/common/include/types.h
index 1d1545d..221b06d 100644
--- a/common/include/types.h
+++ b/common/include/types.h
@@ -115,7 +115,6 @@ typedef enum {
#define UI_COUNT_NUM 5
-#define NPROCS_NAX 4096
#define LL_THRESH 128
#define LL_PERIOD 1000
--
2.49.0

View File

@ -0,0 +1,29 @@
From 1550c9925f98754c7af99d01df460eb6dabb4b0e Mon Sep 17 00:00:00 2001
From: Andi Kleen <ak@linux.intel.com>
Date: Tue, 2 Dec 2025 22:06:32 -0800
Subject: [PATCH] Avoid deadlock on quitting
by resetting the display command mailbox when the display thread exits.
Originally introduced with 8dfa30ea0311
Fixes #98
---
common/disp.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/common/disp.c b/common/disp.c
index c542b77..75eda9d 100644
--- a/common/disp.c
+++ b/common/disp.c
@@ -640,6 +640,7 @@ L_EXIT:
perf_fini();
debug_print(NULL, 2, "disp thread is exiting\n");
+ s_disp_ctl.flag = DISP_FLAG_NONE;
return (NULL);
}
--
2.49.0

View File

@ -3,10 +3,10 @@
Name: numatop
Version: 2.4
Release: 6%{?dist}
Release: 9%{?dist}
Summary: Memory access locality characterization and analysis
License: BSD
License: BSD-3-Clause
URL: https://01.org/numatop
Source: https://github.com/intel/numatop/archive/refs/tags/v%{version}.tar.gz
# Patch0: format.patch
@ -42,12 +42,20 @@ 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
Patch35: 0035-Remove-EMR-specific-events-configuration.patch
Patch36: 0036-Support-Intel-Granite-Rapids-platform.patch
Patch37: 0037-Support-Intel-Sierra-Forest-platform.patch
Patch38: 0038-Move-all-curses-calls-into-display-threads.patch
Patch39: 0039-Avoid-race-on-submitting-display-commands.patch
Patch40: 0040-Increase-PID-column-width.patch
Patch41: 0041-common-Ignore-samples-for-exiting-tasks.patch
Patch42: 0042-common-Fix-upper-bound-for-nodes.patch
Patch43: 0043-common-Fix-upper-bound-for-CPUs-per-node.patch
Patch44: 0044-common-Resolve-max-count-of-nodes-at-runtime.patch
Patch45: 0045-common-Resolve-max-count-of-CPUs-at-runtime.patch
Patch46: 0046-common-Resolve-max-count-of-CPUs-per-node-at-runtime.patch
Patch47: 0047-common-Remove-unused-NPROCS_NAX.patch
Patch48: 0048-Avoid-deadlock-on-quitting.patch
BuildRequires: autoconf