From 0017647c654ab5a3073c785811133bde407a4381 Mon Sep 17 00:00:00 2001 From: Pingfan Liu Date: Thu, 19 Sep 2024 11:23:10 +0800 Subject: [PATCH] back port Resolves: https://issues.redhat.com/browse/RHEL-24552 Signed-off-by: Pingfan Liu --- ...mon-reg.c-use-explicit-format-string.patch | 34 + ...-numatop-powerpc-Add-Power11-support.patch | 44 + ...URITY.md-file-for-OSSF-Scorecard-com.patch | 41 + ...-x86-zen-Add-Zen-5-and-later-support.patch | 31 + 0005-readme-Add-note-on-AMD-support.patch | 30 + ...Fix-several-printf-format-specifiers.patch | 86 ++ 0007-Clean-up-32-bit-build-warnings.patch | 114 ++ ...win.c-Fix-incorrect-usage-of-strncat.patch | 79 ++ ...l.c-Fix-off-by-one-on-string-length-.patch | 39 + ...ragmas-to-silence-false-positive-war.patch | 44 + ...6-Fix-missing-fields-for-EMR-support.patch | 38 + ...ype_t-in-elf64_binary_read-signature.patch | 26 + ...ommon-Remove-unnecessary-temp-buffer.patch | 32 + ...memcpy-to-the-process-name-to-a-line.patch | 51 + ...mon-Increase-node-string-buffer-size.patch | 29 + 0016-Fix-remaining-clang-warnings.patch | 50 + ...g-Add-pragmas-to-silence-false-posit.patch | 44 + ...n-Replace-malloc-strncpy-with-strdup.patch | 31 + ...-Build-node-string-with-bound-checks.patch | 114 ++ 0020-Add-missing-hunks-from-last-change.patch | 42 + ...tra-d-from-debug_print-and-fix-gramm.patch | 32 + ...tialized-string-content-in-dyn-pid-0.patch | 32 + ...n-Add-missing-t-from-help-and-manual.patch | 1046 +++++++++++++++++ ...anity-check-on-num-to-avoid-array-bo.patch | 43 + ...e-dump-and-log-files-are-not-opened-.patch | 46 + ...erence-of-data_head-and-data_tail-to.patch | 39 + ...nique-Fix-uninitialised-return-of-po.patch | 32 + ...fix-timeout-option-break-out-of-loop.patch | 32 + ...-umount-system-calls-rather-than-usi.patch | 76 ++ ...ecuting-commands-for-directory-and-f.patch | 152 +++ ...-build-warning-cast-LHS-of-expressio.patch | 34 + 0032-common-os-map-Fix-overflow-warning.patch | 36 + numatop.spec | 35 +- 33 files changed, 2633 insertions(+), 1 deletion(-) create mode 100644 0001-common-reg.c-use-explicit-format-string.patch create mode 100644 0002-numatop-powerpc-Add-Power11-support.patch create mode 100644 0003-add-required-SECURITY.md-file-for-OSSF-Scorecard-com.patch create mode 100644 0004-x86-zen-Add-Zen-5-and-later-support.patch create mode 100644 0005-readme-Add-note-on-AMD-support.patch create mode 100644 0006-Fix-several-printf-format-specifiers.patch create mode 100644 0007-Clean-up-32-bit-build-warnings.patch create mode 100644 0008-common-os-os_win.c-Fix-incorrect-usage-of-strncat.patch create mode 100644 0009-common-os-os_util.c-Fix-off-by-one-on-string-length-.patch create mode 100644 0010-common-reg-Add-pragmas-to-silence-false-positive-war.patch create mode 100644 0011-x86-Fix-missing-fields-for-EMR-support.patch create mode 100644 0012-common-Use-sym_type_t-in-elf64_binary_read-signature.patch create mode 100644 0013-common-Remove-unnecessary-temp-buffer.patch create mode 100644 0014-common-Use-memcpy-to-the-process-name-to-a-line.patch create mode 100644 0015-common-Increase-node-string-buffer-size.patch create mode 100644 0016-Fix-remaining-clang-warnings.patch create mode 100644 0017-Revert-common-reg-Add-pragmas-to-silence-false-posit.patch create mode 100644 0018-common-Replace-malloc-strncpy-with-strdup.patch create mode 100644 0019-common-Build-node-string-with-bound-checks.patch create mode 100644 0020-Add-missing-hunks-from-last-change.patch create mode 100644 0021-common-remove-extra-d-from-debug_print-and-fix-gramm.patch create mode 100644 0022-common-fix-uninitialized-string-content-in-dyn-pid-0.patch create mode 100644 0023-common-Add-missing-t-from-help-and-manual.patch create mode 100644 0024-common-perform-sanity-check-on-num-to-avoid-array-bo.patch create mode 100644 0025-common-ensure-the-dump-and-log-files-are-not-opened-.patch create mode 100644 0026-common-cast-difference-of-data_head-and-data_tail-to.patch create mode 100644 0027-common-resolve_unique-Fix-uninitialised-return-of-po.patch create mode 100644 0028-common-fix-timeout-option-break-out-of-loop.patch create mode 100644 0029-common-use-mount-umount-system-calls-rather-than-usi.patch create mode 100644 0030-common-remove-executing-commands-for-directory-and-f.patch create mode 100644 0031-powerpc-util-fix-build-warning-cast-LHS-of-expressio.patch create mode 100644 0032-common-os-map-Fix-overflow-warning.patch diff --git a/0001-common-reg.c-use-explicit-format-string.patch b/0001-common-reg.c-use-explicit-format-string.patch new file mode 100644 index 0000000..e1e5f14 --- /dev/null +++ b/0001-common-reg.c-use-explicit-format-string.patch @@ -0,0 +1,34 @@ +From 635e2ce2ccb1ac793cc276a7fcb8a92b1ffefa5d Mon Sep 17 00:00:00 2001 +From: Will Dietz +Date: Mon, 31 Jan 2022 12:43:19 -0600 +Subject: [PATCH 01/32] common/reg.c: use explicit format string + +--- + common/reg.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/common/reg.c b/common/reg.c +index 1a87161..ad37274 100644 +--- a/common/reg.c ++++ b/common/reg.c +@@ -240,7 +240,7 @@ reg_line_write(win_reg_t *r, int line, reg_align_t align, char *content) + } + + if (len > 0) { +- (void) mvwprintw(r->hdl, line, pos_x, content); ++ (void) mvwprintw(r->hdl, line, pos_x, "%s", content); + } + + if (r->mode != 0) { +@@ -267,7 +267,7 @@ reg_highlight_write(win_reg_t *r, int line, int align, char *content) + } + + if (len > 0) { +- (void) mvwprintw(r->hdl, line, pos_x, content); ++ (void) mvwprintw(r->hdl, line, pos_x, "%s", content); + } + + (void) wattroff(r->hdl, A_REVERSE | A_BOLD); +-- +2.41.0 + diff --git a/0002-numatop-powerpc-Add-Power11-support.patch b/0002-numatop-powerpc-Add-Power11-support.patch new file mode 100644 index 0000000..5fbc63c --- /dev/null +++ b/0002-numatop-powerpc-Add-Power11-support.patch @@ -0,0 +1,44 @@ +From 50617b9a0e197a5261b3824d6e6309c034e99134 Mon Sep 17 00:00:00 2001 +From: Kajol Jain +Date: Fri, 12 Apr 2024 04:46:59 -0400 +Subject: [PATCH 02/32] numatop/powerpc: Add Power11 support + +Power11 is PowerISA v3.1 compliant processor and support Power10 events. +So using Power10 events to enable numatop in Power11 platform and to +count the per-process/per-thread memory accesses and CPU usage. + +Signed-off-by: Kajol Jain +--- + numatop.8 | 2 +- + powerpc/plat.c | 5 +++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/numatop.8 b/numatop.8 +index 7237093..b09862e 100644 +--- a/numatop.8 ++++ b/numatop.8 +@@ -500,4 +500,4 @@ in 3.9. The following steps show how to get and apply the patch set. + \fBnumatop\fP supports the Intel Xeon processors: 5500-series, 6500/7500-series, + 5600 series, E7-x8xx-series, and E5-16xx/24xx/26xx/46xx-series. + \fBNote\fP: CPU microcode version 0x618 or 0x70c or later is required on +-E5-16xx/24xx/26xx/46xx-series. It also supports IBM Power8, Power9 and Power10 processors. ++E5-16xx/24xx/26xx/46xx-series. It also supports IBM Power8, Power9, Power10 and Power11 processors. +diff --git a/powerpc/plat.c b/powerpc/plat.c +index bed27d5..0ea262b 100644 +--- a/powerpc/plat.c ++++ b/powerpc/plat.c +@@ -93,6 +93,11 @@ plat_detect(void) + s_cpu_type = CPU_POWER10; + ret = 0; + break; ++ ++ case 0x82: ++ s_cpu_type = CPU_POWER10; ++ ret = 0; ++ break; + } + + return ret; +-- +2.41.0 + diff --git a/0003-add-required-SECURITY.md-file-for-OSSF-Scorecard-com.patch b/0003-add-required-SECURITY.md-file-for-OSSF-Scorecard-com.patch new file mode 100644 index 0000000..ba73fc5 --- /dev/null +++ b/0003-add-required-SECURITY.md-file-for-OSSF-Scorecard-com.patch @@ -0,0 +1,41 @@ +From c7d38589c859744c30eeda6f0f775f9c423d4b3e Mon Sep 17 00:00:00 2001 +From: Robert Dower +Date: Fri, 3 May 2024 17:14:01 -0700 +Subject: [PATCH 03/32] add required SECURITY.md file for OSSF Scorecard + compliance + +--- + SECURITY.md | 20 ++------------------ + 1 file changed, 2 insertions(+), 18 deletions(-) + +diff --git a/SECURITY.md b/SECURITY.md +index 034e848..373608b 100644 +--- a/SECURITY.md ++++ b/SECURITY.md +@@ -1,21 +1,5 @@ + # Security Policy +- +-## Supported Versions +- +-Use this section to tell people about which versions of your project are +-currently being supported with security updates. +- +-| Version | Supported | +-| ------- | ------------------ | +-| 5.1.x | :white_check_mark: | +-| 5.0.x | :x: | +-| 4.0.x | :white_check_mark: | +-| < 4.0 | :x: | ++Intel is committed to rapidly addressing security vulnerabilities affecting our customers and providing clear guidance on the solution, impact, severity and mitigation. + + ## Reporting a Vulnerability +- +-Use this section to tell people how to report a vulnerability. +- +-Tell them where to go, how often they can expect to get an update on a +-reported vulnerability, what to expect if the vulnerability is accepted or +-declined, etc. ++Please report any security vulnerabilities in this project utilizing the guidelines [here](https://www.intel.com/content/www/us/en/security-center/vulnerability-handling-guidelines.html). +-- +2.41.0 + diff --git a/0004-x86-zen-Add-Zen-5-and-later-support.patch b/0004-x86-zen-Add-Zen-5-and-later-support.patch new file mode 100644 index 0000000..c74a098 --- /dev/null +++ b/0004-x86-zen-Add-Zen-5-and-later-support.patch @@ -0,0 +1,31 @@ +From 5a9c64daa4e146f5b03af5fc9201461a701d208a Mon Sep 17 00:00:00 2001 +From: Sandipan Das +Date: Mon, 3 Jun 2024 13:35:10 +0530 +Subject: [PATCH 04/32] x86/zen: Add Zen 5 and later support + +Processors based on Zen 5 and future microarchitectures are expected to +support events that are already available on Zen 4. Since these events +already provide base functionality, keep reusing the Zen 4 CPU model for +Family 1Ah and later processors until any changes are required. + +Signed-off-by: Sandipan Das +--- + x86/plat.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/x86/plat.c b/x86/plat.c +index b5dbda4..d0c7cba 100644 +--- a/x86/plat.c ++++ b/x86/plat.c +@@ -210,6 +210,8 @@ cpu_type_get(void) + } else { + type = CPU_ZEN4; + } ++ } else if (family >= 26) { /* Family 1Ah and later */ ++ type = CPU_ZEN4; + } + + return (type); +-- +2.41.0 + diff --git a/0005-readme-Add-note-on-AMD-support.patch b/0005-readme-Add-note-on-AMD-support.patch new file mode 100644 index 0000000..4d3bdef --- /dev/null +++ b/0005-readme-Add-note-on-AMD-support.patch @@ -0,0 +1,30 @@ +From e6e8c162d2e6a078a330c2b46b2ee9ddcd53b754 Mon Sep 17 00:00:00 2001 +From: Sandipan Das +Date: Mon, 3 Jun 2024 13:44:54 +0530 +Subject: [PATCH 05/32] readme: Add note on AMD support + +Call out support for AMD EPYC processors from the 7001, 7002, 7003, +4004, 8004 and 9004 series. + +Signed-off-by: Sandipan Das +--- + README.md | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/README.md b/README.md +index 9908e92..fc2db9e 100644 +--- a/README.md ++++ b/README.md +@@ -77,6 +77,9 @@ numatop is supported on Intel Xeon processors: 5500-series, 6500/7500-series, + E5-16xx/24xx/26xx/46xx-series had better be updated to latest CPU microcode + (microcode must be 0x618+ or 0x70c+). + ++AMD EPYC processors from the 7001, 7002, 7003, 4004, 8004 and 9004 series are ++also supported. ++ + To learn about NumaTOP, please visit http://01.org/numatop + + +-- +2.41.0 + diff --git a/0006-Fix-several-printf-format-specifiers.patch b/0006-Fix-several-printf-format-specifiers.patch new file mode 100644 index 0000000..01dd05b --- /dev/null +++ b/0006-Fix-several-printf-format-specifiers.patch @@ -0,0 +1,86 @@ +From ee151845bb4b3e735676bef9607a3774a7c0995d Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Mon, 13 Jan 2020 16:23:56 +0000 +Subject: [PATCH 06/32] Fix several printf format specifiers + +There are several format specifiers that are incorrect, use %zu for +size_t values and %lx for u64 values. + +Signed-off-by: Colin Ian King +--- + common/os/pfwrapper.c | 10 +++++----- + common/os/sym.c | 4 ++-- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/common/os/pfwrapper.c b/common/os/pfwrapper.c +index d6102be..943820e 100644 +--- a/common/os/pfwrapper.c ++++ b/common/os/pfwrapper.c +@@ -166,7 +166,7 @@ pf_profiling_setup(struct _perf_cpu *cpu, int idx, pf_conf_t *conf) + PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; + attr.size = sizeof(attr); + +- debug_print(NULL, 2, "pf_profiling_setup: attr.type = 0x%lx, " ++ debug_print(NULL, 2, "pf_profiling_setup: attr.type = 0x%x, " + "attr.config = 0x%lx, attr.config1 = 0x%lx\n", + attr.type, attr.config, attr.config1); + +@@ -773,14 +773,14 @@ pf_uncoreqpi_setup(struct _node *node) + if ((qpi->qpi_info[i].fd = pf_event_open(&attr, -1, + node->cpus[0].cpuid, -1, 0)) < 0) { + debug_print(NULL, 2, "pf_uncoreqpi_setup: pf_event_open is failed " +- "for node %d, qpi %d, cpu %d, type %d, config 0x%x\n", ++ "for node %d, qpi %d, cpu %d, type %d, config 0x%lx\n", + node->nid, i, node->cpus[0].cpuid, attr.type, attr.config); + qpi->qpi_info[i].fd = INVALID_FD; + return (-1); + } + + debug_print(NULL, 2, "pf_uncoreqpi_setup: pf_event_open is successful " +- "for node %d, qpi %d, cpu %d, type %d, config 0x%x, fd %d\n", ++ "for node %d, qpi %d, cpu %d, type %d, config 0x%lx, fd %d\n", + node->nid, i, node->cpus[0].cpuid, attr.type, attr.config, + qpi->qpi_info[i].fd); + } +@@ -897,14 +897,14 @@ pf_uncoreimc_setup(struct _node *node) + if ((imc->imc_info[i].fd = pf_event_open(&attr, -1, + node->cpus[0].cpuid, -1, 0)) < 0) { + debug_print(NULL, 2, "pf_uncoreimc_setup: pf_event_open is failed " +- "for node %d, imc %d, cpu %d, type %d, config 0x%x\n", ++ "for node %d, imc %d, cpu %d, type %d, config 0x%lx\n", + node->nid, i, node->cpus[0].cpuid, attr.type, attr.config); + imc->imc_info[i].fd = INVALID_FD; + return (-1); + } + + debug_print(NULL, 2, "pf_uncoreimc_setup: pf_event_open is successful " +- "for node %d, imc %d, cpu %d, type %d, config 0x%x, fd %d\n", ++ "for node %d, imc %d, cpu %d, type %d, config 0x%lx, fd %d\n", + node->nid, i, node->cpus[0].cpuid, attr.type, attr.config, + imc->imc_info[i].fd); + } +diff --git a/common/os/sym.c b/common/os/sym.c +index 9ead1fb..949ce7a 100644 +--- a/common/os/sym.c ++++ b/common/os/sym.c +@@ -384,7 +384,7 @@ elf32_binary_read(sym_binary_t *binary, sym_type_t sym_type) + } + + if (ehdr.e_shentsize != sizeof (Elf32_Shdr)) { +- debug_print(NULL, 2, "elf32_binary_read: ehdr.e_shentsize != %d\n", ++ debug_print(NULL, 2, "elf32_binary_read: ehdr.e_shentsize != %zu\n", + sizeof (Elf32_Shdr)); + return (-1); + } +@@ -481,7 +481,7 @@ elf64_binary_read(sym_binary_t *binary, unsigned int sym_type) + } + + if (ehdr.e_shentsize != sizeof (Elf64_Shdr)) { +- debug_print(NULL, 2, "elf64_binary_read: ehdr.e_shentsize != %d\n", ++ debug_print(NULL, 2, "elf64_binary_read: ehdr.e_shentsize != %zu\n", + sizeof (Elf64_Shdr)); + return (-1); + } +-- +2.41.0 + diff --git a/0007-Clean-up-32-bit-build-warnings.patch b/0007-Clean-up-32-bit-build-warnings.patch new file mode 100644 index 0000000..4583113 --- /dev/null +++ b/0007-Clean-up-32-bit-build-warnings.patch @@ -0,0 +1,114 @@ +From 3cf69e26e6ffa1a09148da8be0e211dcc699af3c Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Mon, 13 Jan 2020 17:07:04 +0000 +Subject: [PATCH 07/32] Clean up 32 bit build warnings + +The casting of uint64_t sized address values to void * pointers is +causing build warnings on 32 bit builds. A simple remedy is to +cast uint64_t values to uintptr_t types before casting them to void * +pointers. + +Signed-off-by: Colin Ian King +--- + common/os/map.c | 8 ++++---- + common/os/os_win.c | 6 +++--- + common/proc.c | 3 ++- + common/win.c | 2 +- + 4 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/common/os/map.c b/common/os/map.c +index 2650864..83fdb88 100644 +--- a/common/os/map.c ++++ b/common/os/map.c +@@ -322,7 +322,7 @@ numa_map_update(numa_map_t *numa_map, void **addr_arr, int *node_arr, + int i = 0, j; + + if ((entry = last_entry) == NULL) { +- if ((entry = numa_entry_add(numa_map, (uint64_t)(addr_arr[i]), ++ if ((entry = numa_entry_add(numa_map, (uint64_t)(uintptr_t)addr_arr[i], + node_arr[i])) == NULL) { + return (NULL); + } +@@ -332,10 +332,10 @@ numa_map_update(numa_map_t *numa_map, void **addr_arr, int *node_arr, + + for (j = i; j < addr_num; j++) { + if ((entry->nid == node_arr[j]) && +- (entry->end_addr == (uint64_t)(addr_arr[j]))) { ++ (entry->end_addr == (uint64_t)(uintptr_t)addr_arr[j])) { + entry->end_addr += g_pagesize; + } else { +- if ((entry = numa_entry_add(numa_map, (uint64_t)(addr_arr[j]), ++ if ((entry = numa_entry_add(numa_map, (uint64_t)(uintptr_t)addr_arr[j], + node_arr[j])) == NULL) { + return (NULL); + } +@@ -359,7 +359,7 @@ map_map2numa(track_proc_t *proc, map_entry_t *map_entry) + while (npages_moved < npages_total) { + npages_tomove = MIN(NUMA_MOVE_NPAGES, npages_total - npages_moved); + for (i = 0; i < npages_tomove; i++) { +- addr_arr[i] = (void *)(map_entry->start_addr + ++ addr_arr[i] = (void *)(uintptr_t)(map_entry->start_addr + + (i + npages_moved) * g_pagesize); + } + +diff --git a/common/os/os_win.c b/common/os/os_win.c +index de198ca..09d2ed0 100644 +--- a/common/os/os_win.c ++++ b/common/os/os_win.c +@@ -561,7 +561,7 @@ os_llcallchain_win_destroy(dyn_win_t *win) + static int + bufaddr_cmp(const void *p1, const void *p2) + { +- const uint64_t addr = (const uint64_t)p1; ++ const uint64_t addr = (const uint64_t)(uintptr_t)p1; + const bufaddr_t *bufaddr = (const bufaddr_t *)p2; + + if (addr < bufaddr->addr) { +@@ -621,7 +621,7 @@ llcallchain_bufinfo_show(dyn_llcallchain_t *dyn, track_proc_t *proc, + * Check if the linear address is located in a buffer in + * process address space. + */ +- if ((line = bsearch((void *)(dyn->addr), lat_buf, nlines, ++ if ((line = bsearch((void *)(uintptr_t)(dyn->addr), lat_buf, nlines, + sizeof (lat_line_t), bufaddr_cmp)) != NULL) { + win_lat_str_build(content, WIN_LINECHAR_MAX, 0, line); + reg_line_write(reg, 0, ALIGN_LEFT, content); +@@ -791,7 +791,7 @@ os_lat_buf_hit(lat_line_t *lat_buf, int nlines, os_perf_llrec_t *rec, + * Check if the linear address is located in a buffer in + * process address space. + */ +- if ((line = bsearch((void *)(rec->addr), lat_buf, nlines, ++ if ((line = bsearch((void *)(uintptr_t)(rec->addr), lat_buf, nlines, + sizeof (lat_line_t), bufaddr_cmp)) != NULL) { + /* + * If the linear address is located in, that means this +diff --git a/common/proc.c b/common/proc.c +index db450ed..9954eb6 100644 +--- a/common/proc.c ++++ b/common/proc.c +@@ -746,7 +746,8 @@ proc_group_refresh(pid_t *procs_new, int nproc_new) + proc_group_remove(proc); + proc_free(proc); + } else { +- j = ((uint64_t)p - (uint64_t)procs_new) / ++ j = ((uint64_t)(uintptr_t)p - ++ (uint64_t)(uintptr_t)procs_new) / + sizeof (pid_t); + exist_arr[j] = B_TRUE; + } +diff --git a/common/win.c b/common/win.c +index d0a8f3b..910d267 100644 +--- a/common/win.c ++++ b/common/win.c +@@ -2668,7 +2668,7 @@ llrec2addr(track_proc_t *proc, track_lwp_t *lwp, void ***addr_arr, + } + + for (i = 0; i < grp->nrec_cur; i++) { +- addr_buf[i] = (void *)(grp->rec_arr[i].addr); ++ addr_buf[i] = (void *)(uintptr_t)(grp->rec_arr[i].addr); + lat_buf[i] = grp->rec_arr[i].latency; + } + +-- +2.41.0 + diff --git a/0008-common-os-os_win.c-Fix-incorrect-usage-of-strncat.patch b/0008-common-os-os_win.c-Fix-incorrect-usage-of-strncat.patch new file mode 100644 index 0000000..caadfba --- /dev/null +++ b/0008-common-os-os_win.c-Fix-incorrect-usage-of-strncat.patch @@ -0,0 +1,79 @@ +From f2d5d8b575cefb54d641e15fb1b28a0d598fbc83 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Mon, 29 Nov 2021 18:28:09 +0000 +Subject: [PATCH 08/32] common/os/os_win.c: Fix incorrect usage of strncat + +The wrong buffer size is being used for strncat. Fix this by keeping +account of how much space is left and only appending strings if there +is enough headroom to avoid a buffer overflow. + +Signed-off-by: Colin Ian King +--- + common/os/os_win.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/common/os/os_win.c b/common/os/os_win.c +index 09d2ed0..69e24be 100644 +--- a/common/os/os_win.c ++++ b/common/os/os_win.c +@@ -117,6 +117,7 @@ node_cpu_string(node_t *node, char *s1, int size) + int i, j, k, l, cpuid_start; + int *cpuid_arr; + int ncpus; ++ int s1_len = size; + perf_cpu_t *cpus = node_cpus(node); + + s1[0] = 0; +@@ -140,8 +141,7 @@ node_cpu_string(node_t *node, char *s1, int size) + cpuid_start = cpuid_arr[0]; + + if (ncpus == 1) { +- (void) snprintf(s2, sizeof (s2), "%d", cpuid_start); +- (void) strncat(s1, s2, strlen(s2)); ++ (void) snprintf(s1, size, "%d", cpuid_start); + free(cpuid_arr); + return; + } +@@ -152,6 +152,8 @@ node_cpu_string(node_t *node, char *s1, int size) + for (j = 1; j < ncpus; j++) { + k++; + if (cpuid_arr[j] != cpuid_start + l) { ++ int s2_len = sizeof(s2); ++ + if (k < ncpus) { + if (l == 1) { + (void) snprintf(s2, sizeof (s2), "%d ", cpuid_start); +@@ -167,20 +169,27 @@ node_cpu_string(node_t *node, char *s1, int size) + (void) snprintf(s2, sizeof (s2), "%d-%d", + cpuid_start, cpuid_start + l - 1); + } ++ s2_len -= strlen(s2); + + (void) snprintf(s3, sizeof (s3), " %d", + cpuid_arr[j]); +- (void) strncat(s2, s3, strlen(s3)); ++ s2_len -= strlen(s3); ++ if (s2_len > 0) ++ (void) strncat(s2, s3, s2_len); + } + +- (void) strncat(s1, s2, strlen(s2)); ++ s1_len -= strlen(s2); ++ if (s1_len > 0) ++ (void) strncat(s1, s2, s1_len); + cpuid_start = cpuid_arr[j]; + l = 1; + } else { + if (k == ncpus) { + (void) snprintf(s2, sizeof (s2), "%d-%d", + cpuid_start, cpuid_start + l); +- (void) strncat(s1, s2, strlen(s2)); ++ s1_len -= strlen(s2); ++ if (s1_len > 0) ++ (void) strncat(s1, s2, s1_len); + } else { + l++; + } +-- +2.41.0 + diff --git a/0009-common-os-os_util.c-Fix-off-by-one-on-string-length-.patch b/0009-common-os-os_util.c-Fix-off-by-one-on-string-length-.patch new file mode 100644 index 0000000..1a97d54 --- /dev/null +++ b/0009-common-os-os_util.c-Fix-off-by-one-on-string-length-.patch @@ -0,0 +1,39 @@ +From 33c2cc629c248c2684069e077c9b9f10b22170d8 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Wed, 1 Dec 2021 13:58:10 +0000 +Subject: [PATCH 09/32] common/os/os_util.c: Fix off-by-one on string length in + strncpy call + +The strncpy will miss adding the terminating '\0' to the string because +of an off-by-one issue. Most of the time we are lucky this works because +the malloc'd data is zero, but we can't assume this. + +Signed-off-by: Colin Ian King +--- + common/os/os_util.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/common/os/os_util.c b/common/os/os_util.c +index f442729..53bf405 100644 +--- a/common/os/os_util.c ++++ b/common/os/os_util.c +@@ -391,7 +391,7 @@ str_int_extract(char *str, int *arr, int arr_size, int *num) + return (B_FALSE); + } + +- strncpy(scopy, str, len); ++ strncpy(scopy, str, len + 1); + scopy[len] = 0; + cur = scopy; + +@@ -447,7 +447,6 @@ file_int_extract(char *path, int *arr, int arr_size, int *num) + fclose(fp); + return (B_FALSE); + } +- + fclose(fp); + return (str_int_extract(buf, arr, arr_size, num)); + } +-- +2.41.0 + diff --git a/0010-common-reg-Add-pragmas-to-silence-false-positive-war.patch b/0010-common-reg-Add-pragmas-to-silence-false-positive-war.patch new file mode 100644 index 0000000..98cb6b6 --- /dev/null +++ b/0010-common-reg-Add-pragmas-to-silence-false-positive-war.patch @@ -0,0 +1,44 @@ +From 5509f2830b5376ff24690b7bed076053db25232c Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Fri, 3 Dec 2021 19:37:30 +0000 +Subject: [PATCH 10/32] common/reg: Add pragmas to silence false positive + warnings + +Signed-off-by: Colin Ian King +--- + common/reg.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/common/reg.c b/common/reg.c +index 1a87161..4a2875c 100644 +--- a/common/reg.c ++++ b/common/reg.c +@@ -239,9 +239,12 @@ reg_line_write(win_reg_t *r, int line, reg_align_t align, char *content) + pos_x = (r->ncols_scr - len) / 2; + } + ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wformat-security" + if (len > 0) { + (void) mvwprintw(r->hdl, line, pos_x, content); + } ++#pragma GCC diagnostic pop + + if (r->mode != 0) { + (void) wattroff(r->hdl, r->mode); +@@ -266,9 +269,12 @@ reg_highlight_write(win_reg_t *r, int line, int align, char *content) + pos_x = (r->ncols_scr - len) / 2; + } + ++#pragma GCC diagnostic push ++#pragma GCC diagnostic ignored "-Wformat-security" + if (len > 0) { + (void) mvwprintw(r->hdl, line, pos_x, content); + } ++#pragma GCC diagnostic pop + + (void) wattroff(r->hdl, A_REVERSE | A_BOLD); + } +-- +2.41.0 + diff --git a/0011-x86-Fix-missing-fields-for-EMR-support.patch b/0011-x86-Fix-missing-fields-for-EMR-support.patch new file mode 100644 index 0000000..2eb2ef2 --- /dev/null +++ b/0011-x86-Fix-missing-fields-for-EMR-support.patch @@ -0,0 +1,38 @@ +From 8badd8cfed744c254520808890d7351b88e1b9c4 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Wed, 31 Jul 2024 12:02:06 +0100 +Subject: [PATCH 11/32] x86: Fix missing fields for EMR support + +There are two missing fields in the s_emr_config array causing +build issues with modern versions of gcc. Fix this. + +Fixes: d3fcffc6a9cc ("x86: Add initial support for EMR") +Signed-off-by: Colin Ian King +--- + x86/skl.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/x86/skl.c b/x86/skl.c +index 17cfbcc..a80a868 100644 +--- a/x86/skl.c ++++ b/x86/skl.c +@@ -64,11 +64,11 @@ static plat_event_config_t s_spr_config[PERF_COUNT_NUM] = { + }; + + static plat_event_config_t s_emr_config[PERF_COUNT_NUM] = { +- { PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES, 0x53, 0, "cpu_clk_unhalted.core" }, +- { PERF_TYPE_RAW, 0x012A, 0x53, 0x730000001, "off_core_response_0" }, +- { PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES, 0x53, 0, "cpu_clk_unhalted.ref" }, +- { PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, 0x53, 0, "instr_retired.any" }, +- { PERF_TYPE_RAW, 0x012B, 0x53, 0x104000001, "off_core_response_1" } ++ { PERF_TYPE_HARDWARE, PERF_COUNT_HW_CPU_CYCLES, 0x53, 0, 0, 0, "cpu_clk_unhalted.core" }, ++ { PERF_TYPE_RAW, 0x012A, 0x53, 0x730000001, 0, 0, "off_core_response_0" }, ++ { PERF_TYPE_HARDWARE, PERF_COUNT_HW_REF_CPU_CYCLES, 0x53, 0, 0, 0, "cpu_clk_unhalted.ref" }, ++ { PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, 0x53, 0, 0, 0, "instr_retired.any" }, ++ { PERF_TYPE_RAW, 0x012B, 0x53, 0x104000001, 0, 0, "off_core_response_1" } + }; + + static plat_event_config_t s_skl_ll = { +-- +2.41.0 + diff --git a/0012-common-Use-sym_type_t-in-elf64_binary_read-signature.patch b/0012-common-Use-sym_type_t-in-elf64_binary_read-signature.patch new file mode 100644 index 0000000..13e781b --- /dev/null +++ b/0012-common-Use-sym_type_t-in-elf64_binary_read-signature.patch @@ -0,0 +1,26 @@ +From 3836f8be442d2557ee10216327949b9c85792eac Mon Sep 17 00:00:00 2001 +From: Dridi Boukelmoune +Date: Mon, 4 Mar 2024 22:57:13 +0100 +Subject: [PATCH 12/32] common: Use sym_type_t in elf64_binary_read() signature + +This silences the enum-int-mismatch warning. +--- + common/os/sym.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/common/os/sym.c b/common/os/sym.c +index 949ce7a..4626c8d 100644 +--- a/common/os/sym.c ++++ b/common/os/sym.c +@@ -463,7 +463,7 @@ L_EXIT: + } + + static int +-elf64_binary_read(sym_binary_t *binary, unsigned int sym_type) ++elf64_binary_read(sym_binary_t *binary, sym_type_t sym_type) + { + Elf64_Ehdr ehdr; + Elf64_Shdr shdr; +-- +2.41.0 + diff --git a/0013-common-Remove-unnecessary-temp-buffer.patch b/0013-common-Remove-unnecessary-temp-buffer.patch new file mode 100644 index 0000000..ffee4fc --- /dev/null +++ b/0013-common-Remove-unnecessary-temp-buffer.patch @@ -0,0 +1,32 @@ +From 3eb83bcb5ff91d3390e03acccad0fd8c89171a53 Mon Sep 17 00:00:00 2001 +From: Dridi Boukelmoune +Date: Mon, 4 Mar 2024 23:02:15 +0100 +Subject: [PATCH 13/32] common: Remove unnecessary temp buffer + +--- + common/win.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/common/win.c b/common/win.c +index 910d267..c06f42d 100644 +--- a/common/win.c ++++ b/common/win.c +@@ -484,14 +484,11 @@ topnproc_data_show(dyn_win_t *win) + static void + load_msg_show(void) + { +- char content[64]; + win_reg_t r; + +- (void) snprintf(content, sizeof (content), "Loading ..."); +- + (void) reg_init(&r, 0, 1, g_scr_width, g_scr_height - 1, A_BOLD); + reg_erase(&r); +- reg_line_write(&r, 1, ALIGN_LEFT, content); ++ reg_line_write(&r, 1, ALIGN_LEFT, "Loading ..."); + reg_refresh(&r); + reg_win_destroy(&r); + } +-- +2.41.0 + diff --git a/0014-common-Use-memcpy-to-the-process-name-to-a-line.patch b/0014-common-Use-memcpy-to-the-process-name-to-a-line.patch new file mode 100644 index 0000000..2d3eb93 --- /dev/null +++ b/0014-common-Use-memcpy-to-the-process-name-to-a-line.patch @@ -0,0 +1,51 @@ +From e5b69a496bfd9f68ff7a6adbc2062bd875071f0f Mon Sep 17 00:00:00 2001 +From: Dridi Boukelmoune +Date: Mon, 4 Mar 2024 23:03:02 +0100 +Subject: [PATCH 14/32] common: Use memcpy() to the process name to a line + +The copy will either collect the whole string, and potentially a little +more, but from a safe location, or a truncated string with a null char +guaranteed by the memset() call above. + +This silences the stringop-truncation warning. +--- + common/win.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/common/win.c b/common/win.c +index c06f42d..39909bc 100644 +--- a/common/win.c ++++ b/common/win.c +@@ -355,8 +355,7 @@ topnproc_data_save(track_proc_t *proc, int intval, topnproc_line_t *line) + /* + * Cut off the process name if it's too long. + */ +- (void) strncpy(line->proc_name, proc->name, sizeof (line->proc_name)); +- line->proc_name[WIN_PROCNAME_SIZE - 1] = 0; ++ memcpy(line->proc_name, proc->name, sizeof (line->proc_name) - 1); + line->pid = proc->pid; + line->nlwp = proc_nlwp(proc); + +@@ -2892,8 +2891,7 @@ pqos_cmt_proc_data_save(track_proc_t *proc, track_lwp_t *lwp, int intval, + { + (void) memset(line, 0, sizeof (pqos_cmt_proc_line_t)); + +- (void) strncpy(line->proc_name, proc->name, sizeof (line->proc_name)); +- line->proc_name[WIN_PROCNAME_SIZE - 1] = 0; ++ memcpy(line->proc_name, proc->name, sizeof (line->proc_name) - 1); + line->pid = proc->pid; + line->nlwp = proc_nlwp(proc); + +@@ -3216,8 +3214,7 @@ pqos_mbm_proc_data_save(track_proc_t *proc, track_lwp_t *lwp, int intval, + { + (void) memset(line, 0, sizeof (pqos_mbm_proc_line_t)); + +- (void) strncpy(line->proc_name, proc->name, sizeof (line->proc_name)); +- line->proc_name[WIN_PROCNAME_SIZE - 1] = 0; ++ memcpy(line->proc_name, proc->name, sizeof (line->proc_name) - 1); + line->pid = proc->pid; + line->nlwp = proc_nlwp(proc); + +-- +2.41.0 + diff --git a/0015-common-Increase-node-string-buffer-size.patch b/0015-common-Increase-node-string-buffer-size.patch new file mode 100644 index 0000000..fbb6f05 --- /dev/null +++ b/0015-common-Increase-node-string-buffer-size.patch @@ -0,0 +1,29 @@ +From 58546ce76063d7cc41a6601b44eca9d5502d9da1 Mon Sep 17 00:00:00 2001 +From: Dridi Boukelmoune +Date: Mon, 4 Mar 2024 23:16:27 +0100 +Subject: [PATCH 15/32] common: Increase node string buffer size + +Since the maximum number of CPUs was doubled, it might be reasonable to +double the size of the buffer for the string representation. + +Refs 6f6cc3b24d84c413556639b64a62aca6ad0b21cc +--- + common/os/os_win.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/common/os/os_win.c b/common/os/os_win.c +index 69e24be..bd6f5ce 100644 +--- a/common/os/os_win.c ++++ b/common/os/os_win.c +@@ -215,7 +215,7 @@ nodedetail_line_show(win_reg_t *reg, char *title, char *value, int line) + void + os_nodedetail_data(dyn_nodedetail_t *dyn, win_reg_t *seg) + { +- char s1[256], s2[32]; ++ char s1[512], s2[32]; + node_t *node; + win_countvalue_t value; + node_meminfo_t meminfo; +-- +2.41.0 + diff --git a/0016-Fix-remaining-clang-warnings.patch b/0016-Fix-remaining-clang-warnings.patch new file mode 100644 index 0000000..2cdfae2 --- /dev/null +++ b/0016-Fix-remaining-clang-warnings.patch @@ -0,0 +1,50 @@ +From 75e1f8a0cc7531f5d6e38f083d427114025b7c84 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Wed, 31 Jul 2024 08:52:46 -0700 +Subject: [PATCH 16/32] Fix remaining clang warnings + +Increase mapfile buffer size. +Avoid some warnings for pointer truncation. +--- + common/os/map.c | 2 +- + common/os/os_perf.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/common/os/map.c b/common/os/map.c +index 83fdb88..39251a8 100644 +--- a/common/os/map.c ++++ b/common/os/map.c +@@ -144,7 +144,7 @@ map_read(pid_t pid, map_proc_t *map) + char path[PATH_MAX]; + char line[MAPFILE_LINE_SIZE]; + char addr_str[128], attr_str[128], off_str[128]; +- char fd_str[128], inode_str[128], path_str[PATH_MAX]; ++ char fd_str[128], inode_str[128], path_str[PATH_MAX*2]; + char s1[64], s2[64]; + uint64_t start_addr, end_addr; + unsigned int attr; +diff --git a/common/os/os_perf.c b/common/os/os_perf.c +index 49fdaaa..5a992e4 100644 +--- a/common/os/os_perf.c ++++ b/common/os/os_perf.c +@@ -292,7 +292,7 @@ cpu_profiling_setupstart(perf_cpu_t *cpu, + static int + cpu_profiling_partpause(perf_cpu_t *cpu, void *arg) + { +- perf_count_id_t perf_count_id = (perf_count_id_t)arg; ++ perf_count_id_t perf_count_id = (perf_count_id_t)(uintptr_t)arg; + int i; + + if (perf_count_id == PERF_COUNT_INVALID || +@@ -345,7 +345,7 @@ cpu_profiling_multipause(perf_cpu_t *cpu, void *arg) + static int + cpu_profiling_restore(perf_cpu_t *cpu, void *arg) + { +- perf_count_id_t perf_count_id = (perf_count_id_t)arg; ++ perf_count_id_t perf_count_id = (perf_count_id_t)(uintptr_t)arg; + int i; + + if (perf_count_id == PERF_COUNT_INVALID || +-- +2.41.0 + diff --git a/0017-Revert-common-reg-Add-pragmas-to-silence-false-posit.patch b/0017-Revert-common-reg-Add-pragmas-to-silence-false-posit.patch new file mode 100644 index 0000000..f046c1a --- /dev/null +++ b/0017-Revert-common-reg-Add-pragmas-to-silence-false-posit.patch @@ -0,0 +1,44 @@ +From 2410088f0f22f5f76ac860c9c4bb48944c828940 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Wed, 31 Jul 2024 16:28:18 -0700 +Subject: [PATCH 17/32] Revert "common/reg: Add pragmas to silence false + positive warnings" + +This reverts commit 5509f2830b5376ff24690b7bed076053db25232c. +--- + common/reg.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/common/reg.c b/common/reg.c +index f969cbc..ad37274 100644 +--- a/common/reg.c ++++ b/common/reg.c +@@ -239,12 +239,9 @@ reg_line_write(win_reg_t *r, int line, reg_align_t align, char *content) + pos_x = (r->ncols_scr - len) / 2; + } + +-#pragma GCC diagnostic push +-#pragma GCC diagnostic ignored "-Wformat-security" + if (len > 0) { + (void) mvwprintw(r->hdl, line, pos_x, "%s", content); + } +-#pragma GCC diagnostic pop + + if (r->mode != 0) { + (void) wattroff(r->hdl, r->mode); +@@ -269,12 +266,9 @@ reg_highlight_write(win_reg_t *r, int line, int align, char *content) + pos_x = (r->ncols_scr - len) / 2; + } + +-#pragma GCC diagnostic push +-#pragma GCC diagnostic ignored "-Wformat-security" + if (len > 0) { + (void) mvwprintw(r->hdl, line, pos_x, "%s", content); + } +-#pragma GCC diagnostic pop + + (void) wattroff(r->hdl, A_REVERSE | A_BOLD); + } +-- +2.41.0 + diff --git a/0018-common-Replace-malloc-strncpy-with-strdup.patch b/0018-common-Replace-malloc-strncpy-with-strdup.patch new file mode 100644 index 0000000..3a5d4b4 --- /dev/null +++ b/0018-common-Replace-malloc-strncpy-with-strdup.patch @@ -0,0 +1,31 @@ +From fb42dae1e7c0c97b9a49a22e8f860882a26b3464 Mon Sep 17 00:00:00 2001 +From: Dridi Boukelmoune +Date: Mon, 4 Mar 2024 23:07:07 +0100 +Subject: [PATCH 18/32] common: Replace malloc()+strncpy() with strdup() + +This silences the stringop-truncation warning. +--- + common/os/os_util.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/common/os/os_util.c b/common/os/os_util.c +index 53bf405..3e4d5fc 100644 +--- a/common/os/os_util.c ++++ b/common/os/os_util.c +@@ -387,12 +387,10 @@ str_int_extract(char *str, int *arr, int arr_size, int *num) + int len = strlen(str); + boolean_t ret = B_FALSE; + +- if ((scopy = malloc(len + 1)) == NULL) { ++ if ((scopy = strdup(str)) == NULL) { + return (B_FALSE); + } + +- strncpy(scopy, str, len + 1); +- scopy[len] = 0; + cur = scopy; + + while (cur < (scopy + len)) { +-- +2.41.0 + diff --git a/0019-common-Build-node-string-with-bound-checks.patch b/0019-common-Build-node-string-with-bound-checks.patch new file mode 100644 index 0000000..99b3425 --- /dev/null +++ b/0019-common-Build-node-string-with-bound-checks.patch @@ -0,0 +1,114 @@ +From cf9ca3853a2c801fe04d9bf6d4e2698a00d6de79 Mon Sep 17 00:00:00 2001 +From: Dridi Boukelmoune +Date: Mon, 4 Mar 2024 23:11:13 +0100 +Subject: [PATCH 19/32] common: Build node string with bound checks + +A print_buf() function is added to keep track of progress inside the s1 +buffer and the remaining space. With s1 acting as a cursor and vsnprintf +taking care of formatting, the temp buffers s2 and s3 are no longer +needed. + +This silences the stringop-overflow warning. +--- + common/os/os_win.c | 47 ++++++++++++++++++++++++++++------------------ + 1 file changed, 29 insertions(+), 18 deletions(-) + +diff --git a/common/os/os_win.c b/common/os/os_win.c +index bd6f5ce..48052c6 100644 +--- a/common/os/os_win.c ++++ b/common/os/os_win.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -105,6 +106,28 @@ cpuid_cmp(const void *a, const void *b) + return (0); + } + ++static void ++print_buf(char **destp, int *sizep, const char *fmt, ...) ++{ ++ va_list ap; ++ int len; ++ ++ if (*sizep <= 0) ++ return; ++ ++ va_start(ap, fmt); ++ len = vsnprintf(*destp, *sizep, fmt, ap); ++ va_end(ap); ++ ++ if (len >= *sizep) { ++ *sizep = 0; ++ return; ++ } ++ ++ *destp += len; ++ *sizep -= len; ++} ++ + /* + * Build a readable string of CPU ID and try to reduce the string length. e.g. + * For cpu1, cpu2, cpu3, cpu4, the string is "CPU(1-4)", +@@ -113,7 +136,6 @@ cpuid_cmp(const void *a, const void *b) + static void + node_cpu_string(node_t *node, char *s1, int size) + { +- char s2[128], s3[128]; + int i, j, k, l, cpuid_start; + int *cpuid_arr; + int ncpus; +@@ -156,40 +178,29 @@ node_cpu_string(node_t *node, char *s1, int size) + + if (k < ncpus) { + if (l == 1) { +- (void) snprintf(s2, sizeof (s2), "%d ", cpuid_start); ++ print_buf(&s1, &size, "%d ", cpuid_start); + } else { +- (void) snprintf(s2, sizeof (s2), ++ print_buf(&s1, &size, + "%d-%d ", cpuid_start, cpuid_start + l - 1); + } + } else { + if (l == 1) { +- (void) snprintf(s2, sizeof (s2), "%d", +- cpuid_start); ++ print_buf(&s1, &size, "%d", cpuid_start); + } else { +- (void) snprintf(s2, sizeof (s2), "%d-%d", ++ print_buf(&s1, &size, "%d-%d", + cpuid_start, cpuid_start + l - 1); + } + s2_len -= strlen(s2); + +- (void) snprintf(s3, sizeof (s3), " %d", +- cpuid_arr[j]); +- s2_len -= strlen(s3); +- if (s2_len > 0) +- (void) strncat(s2, s3, s2_len); ++ print_buf(&s1, &size, " %d", cpuid_arr[j]); + } + +- s1_len -= strlen(s2); +- if (s1_len > 0) +- (void) strncat(s1, s2, s1_len); + cpuid_start = cpuid_arr[j]; + l = 1; + } else { + if (k == ncpus) { +- (void) snprintf(s2, sizeof (s2), "%d-%d", ++ print_buf(&s1, &size, "%d-%d", + cpuid_start, cpuid_start + l); +- s1_len -= strlen(s2); +- if (s1_len > 0) +- (void) strncat(s1, s2, s1_len); + } else { + l++; + } +-- +2.41.0 + diff --git a/0020-Add-missing-hunks-from-last-change.patch b/0020-Add-missing-hunks-from-last-change.patch new file mode 100644 index 0000000..095985e --- /dev/null +++ b/0020-Add-missing-hunks-from-last-change.patch @@ -0,0 +1,42 @@ +From e1bc987c482bd8f0eadae88a78d3fc91c1c27de3 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Thu, 1 Aug 2024 01:30:40 -0700 +Subject: [PATCH 20/32] Add missing hunks from last change + +--- + common/os/os_win.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/common/os/os_win.c b/common/os/os_win.c +index 48052c6..9aaefae 100644 +--- a/common/os/os_win.c ++++ b/common/os/os_win.c +@@ -139,7 +139,6 @@ node_cpu_string(node_t *node, char *s1, int size) + int i, j, k, l, cpuid_start; + int *cpuid_arr; + int ncpus; +- int s1_len = size; + perf_cpu_t *cpus = node_cpus(node); + + s1[0] = 0; +@@ -174,8 +173,6 @@ node_cpu_string(node_t *node, char *s1, int size) + for (j = 1; j < ncpus; j++) { + k++; + if (cpuid_arr[j] != cpuid_start + l) { +- int s2_len = sizeof(s2); +- + if (k < ncpus) { + if (l == 1) { + print_buf(&s1, &size, "%d ", cpuid_start); +@@ -190,8 +187,6 @@ node_cpu_string(node_t *node, char *s1, int size) + print_buf(&s1, &size, "%d-%d", + cpuid_start, cpuid_start + l - 1); + } +- s2_len -= strlen(s2); +- + print_buf(&s1, &size, " %d", cpuid_arr[j]); + } + +-- +2.41.0 + diff --git a/0021-common-remove-extra-d-from-debug_print-and-fix-gramm.patch b/0021-common-remove-extra-d-from-debug_print-and-fix-gramm.patch new file mode 100644 index 0000000..c5872bb --- /dev/null +++ b/0021-common-remove-extra-d-from-debug_print-and-fix-gramm.patch @@ -0,0 +1,32 @@ +From 41db077a4c36e6f28ea55c5df7d6f34c886d5a0a Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Thu, 1 Aug 2024 09:41:27 +0100 +Subject: [PATCH 21/32] common: remove extra %d from debug_print and fix + grammar + +The debug_print print formats two integers using %d/%d but only +one integer is being passed as an argument. Remove the send %d. +Also fix grammar in the debug message. + +Fixes: 8a4a6c57a74d ("Add a feature to show per-Node QPI bandwidth") +Signed-off-by: Colin Ian King +--- + common/os/os_perf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/common/os/os_perf.c b/common/os/os_perf.c +index 5a992e4..d8d634f 100644 +--- a/common/os/os_perf.c ++++ b/common/os/os_perf.c +@@ -1510,7 +1510,7 @@ os_uncore_start(perf_ctl_t *ctl, perf_task_t *task) + + if (uncore_start(ctl, t->nid) != 0) { + debug_print(NULL, 2, +- "os_uncore_start is failed for node %d/%d\n", ++ "os_uncore_start failed for node %d\n", + t->nid); + perf_status_set(PERF_STATUS_UNCORE_FAILED); + return (-1); +-- +2.41.0 + diff --git a/0022-common-fix-uninitialized-string-content-in-dyn-pid-0.patch b/0022-common-fix-uninitialized-string-content-in-dyn-pid-0.patch new file mode 100644 index 0000000..cd78292 --- /dev/null +++ b/0022-common-fix-uninitialized-string-content-in-dyn-pid-0.patch @@ -0,0 +1,32 @@ +From d52038ca7af3198dc8797841f2b25f2cd862f5df Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Thu, 1 Aug 2024 09:45:32 +0100 +Subject: [PATCH 22/32] common: fix uninitialized string content in dyn->pid == + 0 case + +In the case where dyn->pid is zero the string content is not initialized +and subsequent writing of this string will emit unintialized garbage and +potentially leaking data on the stack and/or buffer overflow. Fix this +by making it an empty string. + +Fixes: 232711080396 ("Add cache monitoring and memory bandwidth monitoring features") +Signed-off-by: Colin Ian King +--- + common/win.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/common/win.c b/common/win.c +index 39909bc..c3e8492 100644 +--- a/common/win.c ++++ b/common/win.c +@@ -3324,6 +3324,7 @@ pqos_mbm_data_show(dyn_win_t *win, boolean_t *note_out) + + if (dyn->pid == 0) { + /* TODO */ ++ *content = '\0'; + } else if (dyn->lwpid == 0) { + nprocs = 1; + data_reg->nlines_total = 1; +-- +2.41.0 + diff --git a/0023-common-Add-missing-t-from-help-and-manual.patch b/0023-common-Add-missing-t-from-help-and-manual.patch new file mode 100644 index 0000000..063b459 --- /dev/null +++ b/0023-common-Add-missing-t-from-help-and-manual.patch @@ -0,0 +1,1046 @@ +From 233df51fbccaf1b66571495a8da18e8cfb5153a2 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Fri, 2 Aug 2024 09:21:14 +0100 +Subject: [PATCH 23/32] common: Add missing -t from help and manual + +The help and manual don't describe the -t option, so add this. Also +convert the manual from DOS format to UNIX format carriage return ++ line feed. + +Closes: https://github.com/intel/numatop/issues/28 + +Signed-off-by: Colin Ian King +--- + common/numatop.c | 4 +- + numatop.8 | 1008 +++++++++++++++++++++++----------------------- + 2 files changed, 507 insertions(+), 505 deletions(-) + +diff --git a/common/numatop.c b/common/numatop.c +index 2cc5aea..d66e64b 100644 +--- a/common/numatop.c ++++ b/common/numatop.c +@@ -387,6 +387,6 @@ print_usage(const char *exec_name) + " normal: balance precision and overhead (default)\n" + " high : high sampling precision\n" + " (high overhead, not recommended option)\n" +- " low : low sampling precision, suitable for high" +- " load system\n"); ++ " low : low sampling precision, suitable for high load system\n" ++ " -t specify run time in seconds\n"); + } +diff --git a/numatop.8 b/numatop.8 +index b09862e..e2ead45 100644 +--- a/numatop.8 ++++ b/numatop.8 +@@ -1,503 +1,505 @@ +-.TH NUMATOP 8 "April 3, 2013" +-.\" Please adjust this date whenever revising the manpage. +-.\" +-.\" Some roff macros, for reference: +-.\" .nh disable hyphenation +-.\" .hy enable hyphenation +-.\" .ad l left justify +-.\" .ad b justify to both left and right margins +-.\" .nf disable filling +-.\" .fi enable filling +-.\" .br insert line break +-.\" .sp insert n+1 empty lines +-.\" for manpage-specific macros, see man(7) +-.SH NAME +-numatop \- a tool for memory access locality characterization and analysis. +-.SH SYNOPSIS +-.B numatop +-.RI [ -s ] " " [ -l ] " " [ -f ] " " [ -d ] +-.PP +-.B numatop +-.RI [ -h ] +-.SH DESCRIPTION +-This manual page briefly documents the +-.B numatop +-command. +-.PP +-Most modern systems use a Non-Uniform Memory Access (NUMA) design for +-multiprocessing. In NUMA systems, memory and processors are organized in such a +-way that some parts of memory are closer to a given processor, while other parts +-are farther from it. A processor can access memory that is closer to it much faster +-than the memory that is farther from it. Hence, the latency between the processors +-and different portions of the memory in a NUMA machine may be significantly different. +- +-\fBnumatop\fP is an observation tool for runtime memory locality characterization +-and analysis of processes and threads running on a NUMA system. It helps the user to +-characterize the NUMA behavior of processes and threads and to identify where the +-NUMA-related performance bottlenecks reside. The tool uses hardware performance counter +-sampling technologies and associates the performance data with Linux system runtime +-information to provide real-time analysis in production systems. The tool can be used to: +- +-\fBA)\fP Characterize the locality of all running processes and threads to identify +-those with the poorest locality in the system. +- +-\fBB)\fP Identify the "hot" memory areas, report average memory access latency, and +-provide the location where accessed memory is allocated. A "hot" memory area is where +-process/thread(s) accesses are most frequent. numatop has a metric called "ACCESS%" +-that specifies what percentage of memory accesses are attributable to each memory area. +- +-\fBNote: numatop records only the memory accesses which have latencies greater than a +-predefined threshold (128 CPU cycles).\fP +- +-\fBC)\fP Provide the call-chain(s) in the process/thread code that accesses a given hot +-memory area. +- +-\fBD)\fP Provide the call-chain(s) when the process/thread generates certain counter +-events (RMA/LMA/IR/CYCLE). The call-chain(s) helps to locate the source code that generates +-the events. +-.PP +-RMA: Remote Memory Access. +-.br +-LMA: Local Memory Access. +-.br +-IR: Instruction Retired. +-.br +-CYCLE: CPU cycles. +-.br +- +-\fBE)\fP Provide per-node statistics for memory and CPU utilization. A node is: a region +-of memory in which every byte has the same distance from each CPU. +- +-\fBF)\fP Show, using a user-friendly interface, the list of processes/threads sorted by +-some metrics (by default, sorted by CPU utilization), with the top process having the +-highest CPU utilization in the system and the bottom one having the lowest CPU utilization. +-Users can also use hotkeys to resort the output by these metrics: RMA, LMA, RMA/LMA, CPI, +-and CPU%. +- +-.br +-RMA/LMA: ratio of RMA/LMA. +-.br +-CPI: CPU cycle per instruction. +-.br +-CPU%: CPU utilization. +-.br +- +-\fBnumatop\fP is a GUI tool that periodically tracks and analyzes the NUMA activity of +-processes and threads and displays useful metrics. Users can scroll up/down by using the +-up or down key to navigate in the current window and can use several hot keys shown at the +-bottom of the window, to switch between windows or to change the running state of the tool. +-For example, hotkey 'R' refreshes the data in the current window. +- +-Below is a detailed description of the various display windows and the data items +-that they display: +- +-\fB[WIN1 - Monitoring processes and threads]:\fP +-.br +-Get the locality characterization of all processes. This is the first window upon startup, +-it's numatop's "Home" window. This window displays a list of processes. The top process has +-the highest system CPU utilization (CPU%), while the bottom process has the lowest CPU% in +-the system. Generally, the memory-intensive process is also CPU-intensive, so the processes +-shown in this window are sorted by CPU% by default. The user can press hotkeys '1', '2', '3', '4', or '5' to resort the output by "RMA", "LMA", "RMA/LMA", "CPI", or "CPU%". +-.PP +-\fB[KEY METRICS]:\fP +-.br +-RMA(K): number of Remote Memory Access (unit is 1000). +-.br +- RMA(K) = RMA / 1000; +-.br +-LMA(K): number of Local Memory Access (unit is 1000). +-.br +- LMA(K) = LMA / 1000; +-.br +-RMA/LMA: ratio of RMA/LMA. +-.br +-CPI: CPU cycles per instruction. +-.br +-CPU%: system CPU utilization (busy time across all CPUs). +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: WIN1 refresh. +-.br +-R: Refresh to show the latest data. +-.br +-I: Switch to WIN2 to show the normalized data. +-.br +-N: Switch to WIN11 to show the per-node statistics. +-.br +-1: Sort by RMA. +-.br +-2: Sort by LMA. +-.br +-3: Sort by RMA/LMA. +-.br +-4: Sort by CPI. +-.br +-5: Sort by CPU% +-.PP +-\fB[WIN2 - Monitoring processes and threads (normalized)]:\fP +-.br +-Get the normalized locality characterization of all processes. +-.PP +-\fB[KEY METRICS]:\fP +-.br +-RPI(K): RMA normalized by 1000 instructions. +-.br +- RPI(K) = RMA / (IR / 1000); +-.br +-LPI(K): LMA normalized by 1000 instructions. +-.br +- LPI(K) = LMA / (IR / 1000); +-.br +-Other metrics remain the same. +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to previous window. +-.br +-R: Refresh to show the latest data. +-.br +-N: Switch to WIN11 to show the per-node statistics. +-.br +-1: Sort by RPI. +-.br +-2: Sort by LPI. +-.br +-3: Sort by RMA/LMA. +-.br +-4: Sort by CPI. +-.br +-5: Sort by CPU% +-.PP +-\fB[WIN3 - Monitoring the process]:\fP +-.br +-Get the locality characterization with node affinity of a specified process. +-.PP +-\fB[KEY METRICS]:\fP +-.br +-NODE: the node ID. +-.br +-CPU%: per-node CPU utilization. +-.br +-Other metrics remain the same. +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to previous window. +-.br +-R: Refresh to show the latest data. +-.br +-N: Switch to WIN11 to show the per-node statistics. +-.br +-L: Show the latency information. +-.br +-C: Show the call-chain. +-.PP +-\fB[WIN4 - Monitoring all threads]:\fP +-.br +-Get the locality characterization of all threads in a specified process. +-.PP +-\fB[KEY METRICS]\fP: +-.br +-CPU%: per-CPU CPU utilization. +-.br +-Other metrics remain the same. +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to previous window. +-.br +-R: Refresh to show the latest data. +-.br +-N: Switch to WIN11 to show the per-node statistics. +-.PP +-\fB[WIN5 - Monitoring the thread]:\fP +-.br +-Get the locality characterization with node affinity of a specified thread. +-.PP +-\fB[KEY METRICS]:\fP +-.br +-CPU%: per-CPU CPU utilization. +-.br +-Other metrics remain the same. +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to previous window. +-.br +-R: Refresh to show the latest data. +-.br +-N: Switch to WIN11 to show the per-node statistics. +-.br +-L: Show the latency information. +-.br +-C: Show the call-chain. +-.PP +-\fB[WIN6 - Monitoring memory areas]:\fP +-.br +-Get the memory area use with the associated accessing latency of a +-specified process/thread. +-.PP +-\fB[KEY METRICS]:\fP +-.br +-ADDR: starting address of the memory area. +-.br +-SIZE: size of memory area (K/M/G bytes). +-.br +-ACCESS%: percentage of memory accesses are to this memory area. +-.br +-LAT(ns): the average latency (nanoseconds) of memory accesses. +-.br +-DESC: description of memory area (from /proc//maps). +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to previous window. +-.br +-R: Refresh to show the latest data. +-.br +-A: Show the memory access node distribution. +-.br +-C: Show the call-chain when process/thread accesses the memory area. +-.PP +-\fB[WIN7 - Memory access node distribution overview]:\fP +-.br +-Get the percentage of memory accesses originated from the process/thread to each node. +-.PP +-\fB[KEY METRICS]:\fP +-.br +-NODE: the node ID. +-.br +-ACCESS%: percentage of memory accesses are to this node. +-.br +-LAT(ns): the average latency (nanoseconds) of memory accesses to this node. +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to previous window. +-.br +-R: Refresh to show the latest data. +-.PP +-\fB[WIN8 - Break down the memory area into physical memory on node]:\fP +-.br +-Break down the memory area into the physical mapping on node with the +-associated accessing latency of a process/thread. +-.PP +-\fB[KEY METRICS]:\fP +-.br +-NODE: the node ID. +-.br +-Other metrics remain the same. +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to previous window. +-.br +-R: Refresh to show the latest data. +-.PP +-\fB[WIN9 - Call-chain when process/thread generates the event ("RMA"/"LMA"/"CYCLE"/"IR")]:\fP +-.br +-Determine the call-chains to the code that generates "RMA"/"LMA"/"CYCLE"/"IR". +-.PP +-\fB[KEY METRICS]:\fP +-.br +-Call-chain list: a list of call-chains. +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to the previous window. +-.br +-R: Refresh to show the latest data. +-.br +-1: Locate call-chain when process/thread generates "RMA" +-.br +-2: Locate call-chain when process/thread generates "LMA" +-.br +-3: Locate call-chain when process/thread generates "CYCLE" (CPU cycle) +-.br +-4: Locate call-chain when process/thread generates "IR" (Instruction Retired) +-.PP +-\fB[WIN10 - Call-chain when process/thread access the memory area]:\fP +-.br +-Determine the call-chains to the code that references this memory area. +-The latency must be greater than the predefined latency threshold +-(128 CPU cycles). +-.PP +-\fB[KEY METRICS]:\fP +-.br +-Call-chain list: a list of call-chains. +-.br +-Other metrics remain the same. +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to previous window. +-.br +-R: Refresh to show the latest data. +-.PP +-\fB[WIN11 - Node Overview]:\fP +-.br +-Show the basic per-node statistics for this system +-.PP +-\fB[KEY METRICS]:\fP +-.br +-MEM.ALL: total usable RAM (physical RAM minus a few reserved bits and the kernel binary code). +-.br +-MEM.FREE: sum of LowFree + HighFree (overall stat) . +-.br +-CPU%: per-node CPU utilization. +-.br +-Other metrics remain the same. +-.PP +-\fB[WIN12 - Information of Node N]:\fP +-.br +-Show the memory use and CPU utilization for the selected node. +-.PP +-\fB[KEY METRICS]:\fP +-.br +-CPU: array of logical CPUs which belong to this node. +-.br +-CPU%: per-node CPU utilization. +-.br +-MEM active: the amount of memory that has been used more recently and is not usually reclaimed unless absolute necessary. +-.br +-MEM inactive: the amount of memory that has not been used for a while and is eligible to be swapped to disk. +-.br +-Dirty: the amount of memory waiting to be written back to the disk. +-.br +-Writeback: the amount of memory actively being written back to the disk. +-.br +-Mapped: all pages mapped into a process. +-.PP +-\fB[HOTKEY]:\fP +-.br +-Q: Quit the application. +-.br +-H: Switch to WIN1. +-.br +-B: Back to previous window. +-.br +-R: Refresh to show the latest data. +-.PP +-.SH "OPTIONS" +-The following options are supported by numatop: +-.PP +--s sampling_precision +-.br +-normal: balance precision and overhead (default) +-.br +-high: high sampling precision (high overhead) +-.br +-low: low sampling precision, suitable for high load system +-.PP +--l log_level +-.br +-Specifies the level of logging in the log file. Valid values are: +-.br +-1: unknown (reserved for future use) +-.br +-2: all +-.PP +--f log_file +-.br +-Specifies the log file where output will be written. If the log file is +-not writable, the tool will prompt "Cannot open '' for writting.". +-.PP +--d dump_file +-.br +-Specifies the dump file where the screen data will be written. Generally the dump +-file is used for automated test. If the dump file is not writable, the tool will +-prompt "Cannot open for dump writing." +-.PP +--h +-.br +-Displays the command's usage. +-.PP +-.SH EXAMPLES +-Example 1: Launch numatop with high sampling precision +-.br +-numatop -s high +-.PP +-Example 2: Write all warning messages in /tmp/numatop.log +-.br +-numatop -l 2 -o /tmp/numatop.log +-.PP +-Example 3: Dump screen data in /tmp/dump.log +-.br +-numatop -d /tmp/dump.log +-.PP +-.SH EXIT STATUS +-.br +-0: successful operation. +-.br +-Other value: an error occurred. +-.PP +-.SH USAGE +-.br +-You must have root privileges to run numatop. +-.br +-Or set -1 in /proc/sys/kernel/perf_event_paranoid +-.PP +-\fBNote\fP: The perf_event_paranoid setting has security implications and a non-root +-user probably doesn't have authority to access /proc. It is highly recommended +-that the user runs \fBnumatop\fP as root. +-.PP +-.SH VERSION +-.br +- +-\fBnumatop\fP requires a patch set to support PEBS Load Latency functionality in the +-kernel. The patch set has not been integrated in 3.8. Probably it will be integrated +-in 3.9. The following steps show how to get and apply the patch set. +- +-.PP +-1. git clone git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git +-.br +-2. cd tip +-.br +-3. git checkout perf/x86 +-.br +-4. build kernel as usual +-.PP +- +-\fBnumatop\fP supports the Intel Xeon processors: 5500-series, 6500/7500-series, +-5600 series, E7-x8xx-series, and E5-16xx/24xx/26xx/46xx-series. +-\fBNote\fP: CPU microcode version 0x618 or 0x70c or later is required on +-E5-16xx/24xx/26xx/46xx-series. It also supports IBM Power8, Power9, Power10 and Power11 processors. ++.TH NUMATOP 8 "August 1, 2024" ++.\" Please adjust this date whenever revising the manpage. ++.\" ++.\" Some roff macros, for reference: ++.\" .nh disable hyphenation ++.\" .hy enable hyphenation ++.\" .ad l left justify ++.\" .ad b justify to both left and right margins ++.\" .nf disable filling ++.\" .fi enable filling ++.\" .br insert line break ++.\" .sp insert n+1 empty lines ++.\" for manpage-specific macros, see man(7) ++.SH NAME ++numatop \- a tool for memory access locality characterization and analysis. ++.SH SYNOPSIS ++.B numatop ++.RI [ -s ] " " [ -l ] " " [ -f ] " " [ -d ] ++.PP ++.B numatop ++.RI [ -h ] ++.SH DESCRIPTION ++This manual page briefly documents the ++.B numatop ++command. ++.PP ++Most modern systems use a Non-Uniform Memory Access (NUMA) design for ++multiprocessing. In NUMA systems, memory and processors are organized in such a ++way that some parts of memory are closer to a given processor, while other parts ++are farther from it. A processor can access memory that is closer to it much faster ++than the memory that is farther from it. Hence, the latency between the processors ++and different portions of the memory in a NUMA machine may be significantly different. ++ ++\fBnumatop\fP is an observation tool for runtime memory locality characterization ++and analysis of processes and threads running on a NUMA system. It helps the user to ++characterize the NUMA behavior of processes and threads and to identify where the ++NUMA-related performance bottlenecks reside. The tool uses hardware performance counter ++sampling technologies and associates the performance data with Linux system runtime ++information to provide real-time analysis in production systems. The tool can be used to: ++ ++\fBA)\fP Characterize the locality of all running processes and threads to identify ++those with the poorest locality in the system. ++ ++\fBB)\fP Identify the "hot" memory areas, report average memory access latency, and ++provide the location where accessed memory is allocated. A "hot" memory area is where ++process/thread(s) accesses are most frequent. numatop has a metric called "ACCESS%" ++that specifies what percentage of memory accesses are attributable to each memory area. ++ ++\fBNote: numatop records only the memory accesses which have latencies greater than a ++predefined threshold (128 CPU cycles).\fP ++ ++\fBC)\fP Provide the call-chain(s) in the process/thread code that accesses a given hot ++memory area. ++ ++\fBD)\fP Provide the call-chain(s) when the process/thread generates certain counter ++events (RMA/LMA/IR/CYCLE). The call-chain(s) helps to locate the source code that generates ++the events. ++.PP ++RMA: Remote Memory Access. ++.br ++LMA: Local Memory Access. ++.br ++IR: Instruction Retired. ++.br ++CYCLE: CPU cycles. ++.br ++ ++\fBE)\fP Provide per-node statistics for memory and CPU utilization. A node is: a region ++of memory in which every byte has the same distance from each CPU. ++ ++\fBF)\fP Show, using a user-friendly interface, the list of processes/threads sorted by ++some metrics (by default, sorted by CPU utilization), with the top process having the ++highest CPU utilization in the system and the bottom one having the lowest CPU utilization. ++Users can also use hotkeys to resort the output by these metrics: RMA, LMA, RMA/LMA, CPI, ++and CPU%. ++ ++.br ++RMA/LMA: ratio of RMA/LMA. ++.br ++CPI: CPU cycle per instruction. ++.br ++CPU%: CPU utilization. ++.br ++ ++\fBnumatop\fP is a GUI tool that periodically tracks and analyzes the NUMA activity of ++processes and threads and displays useful metrics. Users can scroll up/down by using the ++up or down key to navigate in the current window and can use several hot keys shown at the ++bottom of the window, to switch between windows or to change the running state of the tool. ++For example, hotkey 'R' refreshes the data in the current window. ++ ++Below is a detailed description of the various display windows and the data items ++that they display: ++ ++\fB[WIN1 - Monitoring processes and threads]:\fP ++.br ++Get the locality characterization of all processes. This is the first window upon startup, ++it's numatop's "Home" window. This window displays a list of processes. The top process has ++the highest system CPU utilization (CPU%), while the bottom process has the lowest CPU% in ++the system. Generally, the memory-intensive process is also CPU-intensive, so the processes ++shown in this window are sorted by CPU% by default. The user can press hotkeys '1', '2', '3', '4', or '5' to resort the output by "RMA", "LMA", "RMA/LMA", "CPI", or "CPU%". ++.PP ++\fB[KEY METRICS]:\fP ++.br ++RMA(K): number of Remote Memory Access (unit is 1000). ++.br ++ RMA(K) = RMA / 1000; ++.br ++LMA(K): number of Local Memory Access (unit is 1000). ++.br ++ LMA(K) = LMA / 1000; ++.br ++RMA/LMA: ratio of RMA/LMA. ++.br ++CPI: CPU cycles per instruction. ++.br ++CPU%: system CPU utilization (busy time across all CPUs). ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: WIN1 refresh. ++.br ++R: Refresh to show the latest data. ++.br ++I: Switch to WIN2 to show the normalized data. ++.br ++N: Switch to WIN11 to show the per-node statistics. ++.br ++1: Sort by RMA. ++.br ++2: Sort by LMA. ++.br ++3: Sort by RMA/LMA. ++.br ++4: Sort by CPI. ++.br ++5: Sort by CPU% ++.PP ++\fB[WIN2 - Monitoring processes and threads (normalized)]:\fP ++.br ++Get the normalized locality characterization of all processes. ++.PP ++\fB[KEY METRICS]:\fP ++.br ++RPI(K): RMA normalized by 1000 instructions. ++.br ++ RPI(K) = RMA / (IR / 1000); ++.br ++LPI(K): LMA normalized by 1000 instructions. ++.br ++ LPI(K) = LMA / (IR / 1000); ++.br ++Other metrics remain the same. ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to previous window. ++.br ++R: Refresh to show the latest data. ++.br ++N: Switch to WIN11 to show the per-node statistics. ++.br ++1: Sort by RPI. ++.br ++2: Sort by LPI. ++.br ++3: Sort by RMA/LMA. ++.br ++4: Sort by CPI. ++.br ++5: Sort by CPU% ++.PP ++\fB[WIN3 - Monitoring the process]:\fP ++.br ++Get the locality characterization with node affinity of a specified process. ++.PP ++\fB[KEY METRICS]:\fP ++.br ++NODE: the node ID. ++.br ++CPU%: per-node CPU utilization. ++.br ++Other metrics remain the same. ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to previous window. ++.br ++R: Refresh to show the latest data. ++.br ++N: Switch to WIN11 to show the per-node statistics. ++.br ++L: Show the latency information. ++.br ++C: Show the call-chain. ++.PP ++\fB[WIN4 - Monitoring all threads]:\fP ++.br ++Get the locality characterization of all threads in a specified process. ++.PP ++\fB[KEY METRICS]\fP: ++.br ++CPU%: per-CPU CPU utilization. ++.br ++Other metrics remain the same. ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to previous window. ++.br ++R: Refresh to show the latest data. ++.br ++N: Switch to WIN11 to show the per-node statistics. ++.PP ++\fB[WIN5 - Monitoring the thread]:\fP ++.br ++Get the locality characterization with node affinity of a specified thread. ++.PP ++\fB[KEY METRICS]:\fP ++.br ++CPU%: per-CPU CPU utilization. ++.br ++Other metrics remain the same. ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to previous window. ++.br ++R: Refresh to show the latest data. ++.br ++N: Switch to WIN11 to show the per-node statistics. ++.br ++L: Show the latency information. ++.br ++C: Show the call-chain. ++.PP ++\fB[WIN6 - Monitoring memory areas]:\fP ++.br ++Get the memory area use with the associated accessing latency of a ++specified process/thread. ++.PP ++\fB[KEY METRICS]:\fP ++.br ++ADDR: starting address of the memory area. ++.br ++SIZE: size of memory area (K/M/G bytes). ++.br ++ACCESS%: percentage of memory accesses are to this memory area. ++.br ++LAT(ns): the average latency (nanoseconds) of memory accesses. ++.br ++DESC: description of memory area (from /proc//maps). ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to previous window. ++.br ++R: Refresh to show the latest data. ++.br ++A: Show the memory access node distribution. ++.br ++C: Show the call-chain when process/thread accesses the memory area. ++.PP ++\fB[WIN7 - Memory access node distribution overview]:\fP ++.br ++Get the percentage of memory accesses originated from the process/thread to each node. ++.PP ++\fB[KEY METRICS]:\fP ++.br ++NODE: the node ID. ++.br ++ACCESS%: percentage of memory accesses are to this node. ++.br ++LAT(ns): the average latency (nanoseconds) of memory accesses to this node. ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to previous window. ++.br ++R: Refresh to show the latest data. ++.PP ++\fB[WIN8 - Break down the memory area into physical memory on node]:\fP ++.br ++Break down the memory area into the physical mapping on node with the ++associated accessing latency of a process/thread. ++.PP ++\fB[KEY METRICS]:\fP ++.br ++NODE: the node ID. ++.br ++Other metrics remain the same. ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to previous window. ++.br ++R: Refresh to show the latest data. ++.PP ++\fB[WIN9 - Call-chain when process/thread generates the event ("RMA"/"LMA"/"CYCLE"/"IR")]:\fP ++.br ++Determine the call-chains to the code that generates "RMA"/"LMA"/"CYCLE"/"IR". ++.PP ++\fB[KEY METRICS]:\fP ++.br ++Call-chain list: a list of call-chains. ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to the previous window. ++.br ++R: Refresh to show the latest data. ++.br ++1: Locate call-chain when process/thread generates "RMA" ++.br ++2: Locate call-chain when process/thread generates "LMA" ++.br ++3: Locate call-chain when process/thread generates "CYCLE" (CPU cycle) ++.br ++4: Locate call-chain when process/thread generates "IR" (Instruction Retired) ++.PP ++\fB[WIN10 - Call-chain when process/thread access the memory area]:\fP ++.br ++Determine the call-chains to the code that references this memory area. ++The latency must be greater than the predefined latency threshold ++(128 CPU cycles). ++.PP ++\fB[KEY METRICS]:\fP ++.br ++Call-chain list: a list of call-chains. ++.br ++Other metrics remain the same. ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to previous window. ++.br ++R: Refresh to show the latest data. ++.PP ++\fB[WIN11 - Node Overview]:\fP ++.br ++Show the basic per-node statistics for this system ++.PP ++\fB[KEY METRICS]:\fP ++.br ++MEM.ALL: total usable RAM (physical RAM minus a few reserved bits and the kernel binary code). ++.br ++MEM.FREE: sum of LowFree + HighFree (overall stat) . ++.br ++CPU%: per-node CPU utilization. ++.br ++Other metrics remain the same. ++.PP ++\fB[WIN12 - Information of Node N]:\fP ++.br ++Show the memory use and CPU utilization for the selected node. ++.PP ++\fB[KEY METRICS]:\fP ++.br ++CPU: array of logical CPUs which belong to this node. ++.br ++CPU%: per-node CPU utilization. ++.br ++MEM active: the amount of memory that has been used more recently and is not usually reclaimed unless absolute necessary. ++.br ++MEM inactive: the amount of memory that has not been used for a while and is eligible to be swapped to disk. ++.br ++Dirty: the amount of memory waiting to be written back to the disk. ++.br ++Writeback: the amount of memory actively being written back to the disk. ++.br ++Mapped: all pages mapped into a process. ++.PP ++\fB[HOTKEY]:\fP ++.br ++Q: Quit the application. ++.br ++H: Switch to WIN1. ++.br ++B: Back to previous window. ++.br ++R: Refresh to show the latest data. ++.PP ++.SH "OPTIONS" ++The following options are supported by numatop: ++.PP ++-s sampling_precision ++.br ++normal: balance precision and overhead (default) ++.br ++high: high sampling precision (high overhead) ++.br ++low: low sampling precision, suitable for high load system ++.PP ++-l log_level ++.br ++Specifies the level of logging in the log file. Valid values are: ++.br ++1: unknown (reserved for future use) ++.br ++2: all ++.PP ++-f log_file ++.br ++Specifies the log file where output will be written. If the log file is ++not writable, the tool will prompt "Cannot open '' for writting.". ++.PP ++-d dump_file ++.br ++Specifies the dump file where the screen data will be written. Generally the dump ++file is used for automated test. If the dump file is not writable, the tool will ++prompt "Cannot open for dump writing." ++.PP ++-h Displays the command's usage. ++.PP ++-t duration ++.br ++Specifies run time duration in seconds. ++.PP ++.SH EXAMPLES ++Example 1: Launch numatop with high sampling precision ++.br ++numatop -s high ++.PP ++Example 2: Write all warning messages in /tmp/numatop.log ++.br ++numatop -l 2 -o /tmp/numatop.log ++.PP ++Example 3: Dump screen data in /tmp/dump.log ++.br ++numatop -d /tmp/dump.log ++.PP ++.SH EXIT STATUS ++.br ++0: successful operation. ++.br ++Other value: an error occurred. ++.PP ++.SH USAGE ++.br ++You must have root privileges to run numatop. ++.br ++Or set -1 in /proc/sys/kernel/perf_event_paranoid ++.PP ++\fBNote\fP: The perf_event_paranoid setting has security implications and a non-root ++user probably doesn't have authority to access /proc. It is highly recommended ++that the user runs \fBnumatop\fP as root. ++.PP ++.SH VERSION ++.br ++ ++\fBnumatop\fP requires a patch set to support PEBS Load Latency functionality in the ++kernel. The patch set has not been integrated in 3.8. Probably it will be integrated ++in 3.9. The following steps show how to get and apply the patch set. ++ ++.PP ++1. git clone git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git ++.br ++2. cd tip ++.br ++3. git checkout perf/x86 ++.br ++4. build kernel as usual ++.PP ++ ++\fBnumatop\fP supports the Intel Xeon processors: 5500-series, 6500/7500-series, ++5600 series, E7-x8xx-series, and E5-16xx/24xx/26xx/46xx-series. ++\fBNote\fP: CPU microcode version 0x618 or 0x70c or later is required on ++E5-16xx/24xx/26xx/46xx-series. It also supports IBM Power8, Power9, Power10 and Power11 processors. +-- +2.41.0 + diff --git a/0024-common-perform-sanity-check-on-num-to-avoid-array-bo.patch b/0024-common-perform-sanity-check-on-num-to-avoid-array-bo.patch new file mode 100644 index 0000000..435e175 --- /dev/null +++ b/0024-common-perform-sanity-check-on-num-to-avoid-array-bo.patch @@ -0,0 +1,43 @@ +From 1057faab896911fb2d3b5cd98bec15cecbdcc00e Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Mon, 5 Aug 2024 17:33:36 +0100 +Subject: [PATCH 24/32] common: perform sanity check on num to avoid array + bounds underflow/overflow + +The integer num is being read from a file and potentially could have values +outside of the range of the arrays it is used to index into. To avoid any +potential array index underflow or overflow accesses perform some sanity +checking. + +Signed-off-by: Colin Ian King +--- + common/os/node.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/common/os/node.c b/common/os/node.c +index 5df1d89..f384e3b 100644 +--- a/common/os/node.c ++++ b/common/os/node.c +@@ -167,6 +167,9 @@ 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) { ++ return (-1); ++ } + + if (os_perf_cpuarr_refresh(node->cpus, NCPUS_NODE_MAX, cpu_arr, + num, init) != 0) { +@@ -225,6 +228,9 @@ 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) { ++ goto L_EXIT; ++ } + + for (i = 0; i < NNODES_MAX; i++) { + node = node_get(i); +-- +2.41.0 + diff --git a/0025-common-ensure-the-dump-and-log-files-are-not-opened-.patch b/0025-common-ensure-the-dump-and-log-files-are-not-opened-.patch new file mode 100644 index 0000000..d8910c8 --- /dev/null +++ b/0025-common-ensure-the-dump-and-log-files-are-not-opened-.patch @@ -0,0 +1,46 @@ +From 4cc28a70d711c5e543648c671faf7731af55ddbe Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Tue, 6 Aug 2024 11:26:03 +0100 +Subject: [PATCH 25/32] common: ensure the dump and log files are not opened + multiple times + +Currently one can pass the -d and -f options multiple times and this +leads to the dump and log files being opened more than once. Check +for these files being re-opened again to avoid this. + +Signed-off-by: Colin Ian King +--- + common/numatop.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/common/numatop.c b/common/numatop.c +index d66e64b..122c187 100644 +--- a/common/numatop.c ++++ b/common/numatop.c +@@ -103,6 +103,11 @@ main(int argc, char *argv[]) + goto L_EXIT0; + } + ++ if (log != NULL) { ++ stderr_print("Invalid multiple use of -f option.\n"); ++ goto L_EXIT0; ++ } ++ + if ((log = fopen(optarg, "w")) == NULL) { + stderr_print("Cannot open '%s' for writing.\n", + optarg); +@@ -142,6 +147,11 @@ main(int argc, char *argv[]) + goto L_EXIT0; + } + ++ if (dump != NULL) { ++ stderr_print("Invalid multiple use of -d option.\n"); ++ goto L_EXIT0; ++ } ++ + if ((dump = fopen(optarg, "w")) == NULL) { + stderr_print("Cannot open '%s' for dump.\n", + optarg); +-- +2.41.0 + diff --git a/0026-common-cast-difference-of-data_head-and-data_tail-to.patch b/0026-common-cast-difference-of-data_head-and-data_tail-to.patch new file mode 100644 index 0000000..36c6c3e --- /dev/null +++ b/0026-common-cast-difference-of-data_head-and-data_tail-to.patch @@ -0,0 +1,39 @@ +From 020fe25d0fa7446ebcd7925caeae914ba4481f3e Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Tue, 6 Aug 2024 11:35:23 +0100 +Subject: [PATCH 26/32] common: cast difference of data_head and data_tail to + int64_t rather than int + +Don't assume int is the same size as the uint64_t data_head and data_tail +sizes. Use int64_t and remove the redundant use of variable data_size. + +Signed-off-by: Colin Ian King +--- + common/os/pfwrapper.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/common/os/pfwrapper.c b/common/os/pfwrapper.c +index 943820e..10042d9 100644 +--- a/common/os/pfwrapper.c ++++ b/common/os/pfwrapper.c +@@ -58,7 +58,7 @@ mmap_buffer_read(struct perf_event_mmap_page *header, void *buf, size_t size) + { + void *data; + uint64_t data_head, data_tail; +- int data_size, ncopies; ++ int ncopies; + + /* + * The first page is a meta-data page (struct perf_event_mmap_page), +@@ -79,7 +79,7 @@ mmap_buffer_read(struct perf_event_mmap_page *header, void *buf, size_t size) + * The kernel function "perf_output_space()" guarantees no data_head can + * wrap over the data_tail. + */ +- if ((data_size = data_head - data_tail) < (int)size) { ++ if ((int64_t)(data_head - data_tail) < (int64_t)size) { + return (-1); + } + +-- +2.41.0 + diff --git a/0027-common-resolve_unique-Fix-uninitialised-return-of-po.patch b/0027-common-resolve_unique-Fix-uninitialised-return-of-po.patch new file mode 100644 index 0000000..bb6c36c --- /dev/null +++ b/0027-common-resolve_unique-Fix-uninitialised-return-of-po.patch @@ -0,0 +1,32 @@ +From 3095e829f785fefe8618bfd12652eb1ed173f29a Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Tue, 6 Aug 2024 14:39:39 +0100 +Subject: [PATCH 27/32] common: resolve_unique: Fix uninitialised return of + pointer item + +In the case where resolve_unique does not resolve a unique symbol +the uninitialzed pointer item is returned which is problematic because +the caller performs a NULL check on this. Fix this be initializing +item to NULL at the start. + +Signed-off-by: Colin Ian King +--- + common/os/sym.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/common/os/sym.c b/common/os/sym.c +index 4626c8d..ffd40fc 100644 +--- a/common/os/sym.c ++++ b/common/os/sym.c +@@ -842,7 +842,7 @@ sym_resolve(sym_t *sym, uint64_t addr, sym_item_t **item_arr, + static sym_item_t * + resolve_unique(sym_t *sym, uint64_t addr, sym_item_t **arr, uint64_t *base_addr) + { +- sym_item_t *item_arr, *item; ++ sym_item_t *item_arr, *item = NULL; + int num, i; + + if (sym_resolve(sym, addr, &item_arr, &num, base_addr) != 0) { +-- +2.41.0 + diff --git a/0028-common-fix-timeout-option-break-out-of-loop.patch b/0028-common-fix-timeout-option-break-out-of-loop.patch new file mode 100644 index 0000000..8166d2c --- /dev/null +++ b/0028-common-fix-timeout-option-break-out-of-loop.patch @@ -0,0 +1,32 @@ +From b2206e7780e7074e811ca1159753b0ccfa68cbc5 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Tue, 6 Aug 2024 16:37:54 +0100 +Subject: [PATCH 28/32] common: fix timeout option, break out of loop + +Currently the timeout -t option does not work, the code display +loop continues forever when the timeout occurs. Fix this by +replacing the continue statement with a break to exit the loop. + +Fixes: https://github.com/intel/numatop/issues/27 + +Signed-off-by: Colin Ian King +--- + common/disp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/common/disp.c b/common/disp.c +index bb0bba2..ea865c3 100644 +--- a/common/disp.c ++++ b/common/disp.c +@@ -514,7 +514,7 @@ disp_handler(void *arg __attribute__((unused))) + g_run_secs = TIME_NSEC_MAX; + debug_print(NULL, 2, + "disp: it's time to exit\n"); +- continue; ++ break; + } + + if ((status == ETIMEDOUT) && (flag == DISP_FLAG_NONE)) { +-- +2.41.0 + diff --git a/0029-common-use-mount-umount-system-calls-rather-than-usi.patch b/0029-common-use-mount-umount-system-calls-rather-than-usi.patch new file mode 100644 index 0000000..d6886d6 --- /dev/null +++ b/0029-common-use-mount-umount-system-calls-rather-than-usi.patch @@ -0,0 +1,76 @@ +From 0df5ed7dd09816495596c7b5224b4747713d3766 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Wed, 7 Aug 2024 08:55:50 +0100 +Subject: [PATCH 29/32] common: use mount/umount system calls rather than using + commands + +Using the mount and umount commands is slower and less safe than +directly using the mount and umount system calls. Fix this by replacing +the exec'ing of the commands with direct system calls. + +Fixes: https://github.com/intel/numatop/issues/60 + +Signed-off-by: Colin Ian King +--- + common/os/os_util.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/common/os/os_util.c b/common/os/os_util.c +index 3e4d5fc..a2212fb 100644 +--- a/common/os/os_util.c ++++ b/common/os/os_util.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + #include "../include/types.h" + #include "../include/util.h" + #include "../include/os/os_util.h" +@@ -731,33 +732,34 @@ static boolean_t resctrl_mounted(void) + + boolean_t os_cmt_init(void) + { +- char command[128]; ++ int ret; + + g_pqos_moni_id = 0; + + if (resctrl_mounted()) + return B_TRUE; + +- snprintf(command, sizeof(command), +- "mount -t resctrl resctrl /sys/fs/resctrl 2>/dev/null"); +- +- if (!execute_command(command, "r")) ++ ret = mount("resctrl", "/sys/fs/resctrl", "resctrl", 0, NULL); ++ if (ret < 0) { ++ debug_print(NULL, 2, "Mount of /sys/fs/resctrl failed (errno = %d)\n", errno); + return B_FALSE; ++ } + + return resctrl_mounted(); + } + + void os_cmt_fini(void) + { +- char command[128]; ++ int ret; + + if (!resctrl_mounted()) + return; + +- snprintf(command, sizeof(command), +- "umount -f /sys/fs/resctrl 2>/dev/null"); ++ ret = umount("/sys/fs/resctrl"); ++ if (ret < 0) { ++ debug_print(NULL, 2, "Unmount of /sys/fs/resctrl failed (errno = %d)\n", errno); ++ } + +- execute_command(command, "r"); + g_pqos_moni_id = 0; + } + +-- +2.41.0 + diff --git a/0030-common-remove-executing-commands-for-directory-and-f.patch b/0030-common-remove-executing-commands-for-directory-and-f.patch new file mode 100644 index 0000000..061f72c --- /dev/null +++ b/0030-common-remove-executing-commands-for-directory-and-f.patch @@ -0,0 +1,152 @@ +From ccece149e1b73a636474b67b641b578f5e7476f5 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Wed, 7 Aug 2024 10:18:08 +0100 +Subject: [PATCH 30/32] common: remove executing commands for directory and + file operations + +Calling commands using execute_command to remove files and directories, +create directories and writing data to a file is just wrong. Replace +these with direct system calls and remove the execute_command helper +function now that it's not required. + +Fixes: https://github.com/intel/numatop/issues/50 + +Signed-off-by: Colin Ian King +--- + common/os/os_util.c | 83 ++++++++++++++++++++++++++++++--------------- + 1 file changed, 55 insertions(+), 28 deletions(-) + +diff --git a/common/os/os_util.c b/common/os/os_util.c +index a2212fb..0b862c2 100644 +--- a/common/os/os_util.c ++++ b/common/os/os_util.c +@@ -27,6 +27,7 @@ + */ + + #define _GNU_SOURCE ++#define _XOPEN_SOURCE 500 + #include + #include + #include +@@ -41,6 +42,7 @@ + #include + #include + #include ++#include + #include + #include + #include "../include/types.h" +@@ -699,23 +701,6 @@ os_sysfs_uncore_imc_init(imc_info_t *imc, int num) + return imc_num; + } + +-static boolean_t execute_command(const char *command, const char *type) +-{ +- FILE *fp; +- +- fp = popen(command, type); +- if (fp == NULL) { +- debug_print(NULL, 2, "Execute '%s' failed (errno = %d)\n", +- command, errno); +- return B_FALSE; +- } +- +- pclose(fp); +- debug_print(NULL, 2, "Execute '%s' ok\n", command); +- +- return B_TRUE; +-} +- + static boolean_t resctrl_mounted(void) + { + char path[128]; +@@ -763,9 +748,41 @@ void os_cmt_fini(void) + g_pqos_moni_id = 0; + } + ++static int os_sysfs_nftw_unlink(const char *fpath, const struct stat *statbuf, ++ int tflag, struct FTW *ftwbuf) ++{ ++ int ret; ++ ++ (void)statbuf; ++ (void)ftwbuf; ++ ++ switch (tflag) { ++ case FTW_F: ++ case FTW_SL: ++ case FTW_SLN: ++ default: ++ errno = 0; ++ ret = unlink(fpath); ++ if (ret < 0) ++ debug_print(NULL, 2, "unlink %s (errno=%d)\n", fpath, errno); ++ break; ++ case FTW_D: ++ case FTW_DP: ++ case FTW_DNR: ++ errno = 0; ++ ret = rmdir(fpath); ++ if (ret < 0) ++ debug_print(NULL, 2, "rmdir %s (errno=%d)\n", fpath, errno); ++ break; ++ } ++ ++ return 0; ++} ++ + int os_sysfs_cmt_task_set(int pid, int lwpid, struct _perf_pqos *pqos) + { +- char command[160], path[128]; ++ char data[64], path[128]; ++ int ret, fd; + + if (lwpid) + pqos->task_id = lwpid; +@@ -777,23 +794,33 @@ int os_sysfs_cmt_task_set(int pid, int lwpid, struct _perf_pqos *pqos) + snprintf(path, sizeof(path), + "/sys/fs/resctrl/mon_groups/%d", pqos->task_id); + +- snprintf(command, sizeof(command), "rm -rf %s 2>/dev/null", path); +- if (!execute_command(command, "r")) ++ /* nftw will return -1 if the path does not exist, ignore this */ ++ (void)nftw(path, os_sysfs_nftw_unlink, 32, FTW_DEPTH | FTW_PHYS); ++ ++ ret = mkdir(path, 0777); ++ if (ret < 0) { ++ debug_print(NULL, 2, "mkdir %s failed, errno=%d\n", path, errno); + return -1; ++ } + +- snprintf(command, sizeof(command), "mkdir %s 2>/dev/null", path); +- if (!execute_command(command, "r")) ++ snprintf(path, sizeof(path), ++ "/sys/fs/resctrl/mon_groups/%d/tasks", pqos->task_id); ++ fd = open(path, O_RDWR); ++ if (fd < 0) { ++ debug_print(NULL, 2, "open %s failed, errno=%d\n", path, errno); + return -1; ++ } + + if (lwpid == 0) +- snprintf(command, sizeof(command), +- "echo %d > %s/tasks", pid, path); ++ snprintf(data, sizeof(data), "%d\n", pid); + else +- snprintf(command, sizeof(command), +- "echo %d > %s/tasks", lwpid, path); +- +- if (!execute_command(command, "r")) ++ snprintf(data, sizeof(data), "%d\n", lwpid); ++ if (write(fd, data, strlen(data)) < 0) { ++ debug_print(NULL, 2, "write to %s failed, errno=%d\n", path, errno); ++ (void)close(fd); + return -1; ++ } ++ (void)close(fd); + + return 0; + } +-- +2.41.0 + diff --git a/0031-powerpc-util-fix-build-warning-cast-LHS-of-expressio.patch b/0031-powerpc-util-fix-build-warning-cast-LHS-of-expressio.patch new file mode 100644 index 0000000..90cad6d --- /dev/null +++ b/0031-powerpc-util-fix-build-warning-cast-LHS-of-expressio.patch @@ -0,0 +1,34 @@ +From 9c4d14a9c553840022ecb2333b87643370b333d8 Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Tue, 13 Aug 2024 14:17:32 +0100 +Subject: [PATCH 31/32] powerpc/util: fix build warning, cast LHS of expression + to size_t + +The powerpc builds are throwing a warning, fix this with a cast. + +Fixes warning: +powerpc/util.c:91:34: warning: comparison of integer expressions of different +signedness: 'long int' and 'size_t' {aka 'long unsigned int'} [-Wsign-compare] + 91 | if (c - line + 2 < len && ... + +Signed-off-by: Colin Ian King +--- + powerpc/util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/powerpc/util.c b/powerpc/util.c +index f2ff159..6e1fe9d 100644 +--- a/powerpc/util.c ++++ b/powerpc/util.c +@@ -88,7 +88,7 @@ arch__cpuinfo_freq(double *freq, char *unit) + } + + c = strchr(line, ':'); +- if (c - line + 2 < len && ++ if ((size_t)(c - line + 2) < len && + !strncmp(c + 2, "pSeries", sizeof ("pSeries") - 1)) { + ret = 0; + break; +-- +2.41.0 + diff --git a/0032-common-os-map-Fix-overflow-warning.patch b/0032-common-os-map-Fix-overflow-warning.patch new file mode 100644 index 0000000..797fa82 --- /dev/null +++ b/0032-common-os-map-Fix-overflow-warning.patch @@ -0,0 +1,36 @@ +From 7dd67b56333bae4a40d825600c3b7cc7df08068d Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +Date: Mon, 17 Jun 2024 12:36:39 +0800 +Subject: [PATCH 32/32] common/os: map: Fix overflow warning + +As we have +common/include/types.h:79:#ifndef PATH_MAX +common/include/types.h:80:#define PATH_MAX 2048 + +The following code has potential issue with overflow: + if ((nargs = sscanf(line, "%127[^ ] %127[^ ] %127[^ ] %127[^ ] %127[^ ] %4095[^\n]", + addr_str, attr_str, off_str, fd_str, inode_str, path_str)) < 0) { + +Where the capacity of path_str is 2048 instead of 4096. + +Signed-off-by: Pingfan Liu +--- + common/os/map.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/common/os/map.c b/common/os/map.c +index 39251a8..29c5a78 100644 +--- a/common/os/map.c ++++ b/common/os/map.c +@@ -165,7 +165,7 @@ map_read(pid_t pid, map_proc_t *map) + /* + * e.g. 00400000-00405000 r-xp 00000000 fd:00 678793 /usr/bin/vmstat + */ +- if ((nargs = sscanf(line, "%127[^ ] %127[^ ] %127[^ ] %127[^ ] %127[^ ] %4095[^\n]", ++ if ((nargs = sscanf(line, "%127[^ ] %127[^ ] %127[^ ] %127[^ ] %127[^ ] %2047[^\n]", + addr_str, attr_str, off_str, fd_str, inode_str, path_str)) < 0) { + goto L_EXIT; + } +-- +2.41.0 + diff --git a/numatop.spec b/numatop.spec index e5d2c57..b7bc4e9 100644 --- a/numatop.spec +++ b/numatop.spec @@ -9,7 +9,40 @@ Summary: Memory access locality characterization and analysis 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 +# Patch0: format.patch +Patch01: 0001-common-reg.c-use-explicit-format-string.patch +Patch02: 0002-numatop-powerpc-Add-Power11-support.patch +Patch03: 0003-add-required-SECURITY.md-file-for-OSSF-Scorecard-com.patch +Patch04: 0004-x86-zen-Add-Zen-5-and-later-support.patch +Patch05: 0005-readme-Add-note-on-AMD-support.patch +Patch06: 0006-Fix-several-printf-format-specifiers.patch +Patch07: 0007-Clean-up-32-bit-build-warnings.patch +Patch08: 0008-common-os-os_win.c-Fix-incorrect-usage-of-strncat.patch +Patch09: 0009-common-os-os_util.c-Fix-off-by-one-on-string-length-.patch +#Patch10: 0010-common-reg-Add-pragmas-to-silence-false-positive-war.patch +Patch11: 0011-x86-Fix-missing-fields-for-EMR-support.patch +Patch12: 0012-common-Use-sym_type_t-in-elf64_binary_read-signature.patch +Patch13: 0013-common-Remove-unnecessary-temp-buffer.patch +Patch14: 0014-common-Use-memcpy-to-the-process-name-to-a-line.patch +Patch15: 0015-common-Increase-node-string-buffer-size.patch +Patch16: 0016-Fix-remaining-clang-warnings.patch +#Patch17: 0017-Revert-common-reg-Add-pragmas-to-silence-false-posit.patch +Patch18: 0018-common-Replace-malloc-strncpy-with-strdup.patch +Patch19: 0019-common-Build-node-string-with-bound-checks.patch +Patch20: 0020-Add-missing-hunks-from-last-change.patch +Patch21: 0021-common-remove-extra-d-from-debug_print-and-fix-gramm.patch +Patch22: 0022-common-fix-uninitialized-string-content-in-dyn-pid-0.patch +Patch23: 0023-common-Add-missing-t-from-help-and-manual.patch +Patch24: 0024-common-perform-sanity-check-on-num-to-avoid-array-bo.patch +Patch25: 0025-common-ensure-the-dump-and-log-files-are-not-opened-.patch +Patch26: 0026-common-cast-difference-of-data_head-and-data_tail-to.patch +Patch27: 0027-common-resolve_unique-Fix-uninitialised-return-of-po.patch +Patch28: 0028-common-fix-timeout-option-break-out-of-loop.patch +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 + BuildRequires: autoconf BuildRequires: automake