From 25194aee36d18264fdae97c7347338fec1ed13e2 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 31 2020 09:41:27 +0000 Subject: import numactl-2.0.12-5.el7 --- diff --git a/SOURCES/numactl-2.0.12-Update-manpage-description-of-numa_node_to_cpu_updat.patch b/SOURCES/numactl-2.0.12-Update-manpage-description-of-numa_node_to_cpu_updat.patch new file mode 100644 index 0000000..14f07fc --- /dev/null +++ b/SOURCES/numactl-2.0.12-Update-manpage-description-of-numa_node_to_cpu_updat.patch @@ -0,0 +1,28 @@ +From 034ad86281330ccd1cfe22d40698dd15c2453853 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Mon, 16 Sep 2019 13:50:24 -0700 +Subject: [PATCH 2/2] Update manpage description of numa_node_to_cpu_update() + +--- + numa.3 | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/numa.3 b/numa.3 +index e54cb0b..3e18098 100644 +--- a/numa.3 ++++ b/numa.3 +@@ -799,8 +799,10 @@ will be set to + and \-1 returned. On success 0 is returned. + + .BR numa_node_to_cpu_update () +-Mark the node's cpus bitmask stale, then get the latest bitmask by calling ++Mark cpus bitmask of all nodes stale, then get the latest bitmask by calling + .BR numa_node_to_cpus () ++This allows to update the libnuma state after a CPU hotplug event. The application ++is in charge of detecting CPU hotplug events. + + .BR numa_node_of_cpu () + returns the node that a cpu belongs to. If the user supplies an invalid cpu +-- +2.7.5 + diff --git a/SOURCES/numactl-2.0.12-libnuma-introduce-an-API-to-outdate-cpu-to-node-mapp.patch b/SOURCES/numactl-2.0.12-libnuma-introduce-an-API-to-outdate-cpu-to-node-mapp.patch new file mode 100644 index 0000000..0ef372c --- /dev/null +++ b/SOURCES/numactl-2.0.12-libnuma-introduce-an-API-to-outdate-cpu-to-node-mapp.patch @@ -0,0 +1,183 @@ +From 3cc2e004cd5891a87d8bde2b9ddd814f68d1835a Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +Date: Mon, 15 Jul 2019 16:24:39 +0800 +Subject: [PATCH 1/2] libnuma: introduce an API to outdate cpu to node mapping + +numa_node_to_cpus() caches the cpu to node mapping, and not updates it +during the cpu online/offline event. + +Ideally, in order to update the mapping automatically, it requires +something like udev to spy on kernel event socket, and update cache if +event happen. This solution is a little complicated inside a libnuma.so. In +stead of doing so, exposing an API numa_node_to_cpu_outdated() for user, +and saddling the event-detecting task to the user. + +So the user of libnuma can work using either of the following models: + -1. blindless outdate cache if careless about performance + numa_node_to_cpu_outdated(); + numa_node_to_cpu(); + -2. event driven spy on kernel event, if happened, call + numa_node_to_cpu_outdated(); + +Signed-off-by: Pingfan Liu +--- + libnuma.c | 32 ++++++++++++++++++++++++++++---- + numa.3 | 7 +++++++ + numa.h | 2 ++ + versions.ldscript | 1 + + 4 files changed, 38 insertions(+), 4 deletions(-) + +diff --git a/libnuma.c b/libnuma.c +index cac8851..756a171 100644 +--- a/libnuma.c ++++ b/libnuma.c +@@ -58,7 +58,9 @@ struct bitmask *numa_possible_cpus_ptr = NULL; + struct bitmask *numa_nodes_ptr = NULL; + static struct bitmask *numa_memnode_ptr = NULL; + static unsigned long *node_cpu_mask_v1[NUMA_NUM_NODES]; ++static char node_cpu_mask_v1_stale = 1; + static struct bitmask **node_cpu_mask_v2; ++static char node_cpu_mask_v2_stale = 1; + + WEAK void numa_error(char *where); + +@@ -1272,6 +1274,7 @@ numa_node_to_cpus_v1(int node, unsigned long *buffer, int bufferlen) + int err = 0; + char fn[64]; + FILE *f; ++ char update; + char *line = NULL; + size_t len = 0; + struct bitmask bitmask; +@@ -1287,7 +1290,8 @@ numa_node_to_cpus_v1(int node, unsigned long *buffer, int bufferlen) + } + if (bufferlen > buflen_needed) + memset(buffer, 0, bufferlen); +- if (node_cpu_mask_v1[node]) { ++ update = __atomic_fetch_and(&node_cpu_mask_v1_stale, 0, __ATOMIC_RELAXED); ++ if (node_cpu_mask_v1[node] && !update) { + memcpy(buffer, node_cpu_mask_v1[node], buflen_needed); + return 0; + } +@@ -1328,7 +1332,15 @@ numa_node_to_cpus_v1(int node, unsigned long *buffer, int bufferlen) + + /* slightly racy, see above */ + if (node_cpu_mask_v1[node]) { +- if (mask != buffer) ++ if (update) { ++ /* ++ * There may be readers on node_cpu_mask_v1[], hence it can not ++ * be freed. ++ */ ++ memcpy(node_cpu_mask_v1[node], mask, buflen_needed); ++ free(mask); ++ mask = NULL; ++ } else if (mask != buffer) + free(mask); + } else { + node_cpu_mask_v1[node] = mask; +@@ -1352,6 +1364,7 @@ numa_node_to_cpus_v2(int node, struct bitmask *buffer) + int nnodes = numa_max_node(); + char fn[64], *line = NULL; + FILE *f; ++ char update; + size_t len = 0; + struct bitmask *mask; + +@@ -1364,7 +1377,8 @@ numa_node_to_cpus_v2(int node, struct bitmask *buffer) + } + numa_bitmask_clearall(buffer); + +- if (node_cpu_mask_v2[node]) { ++ update = __atomic_fetch_and(&node_cpu_mask_v2_stale, 0, __ATOMIC_RELAXED); ++ if (node_cpu_mask_v2[node] && !update) { + /* have already constructed a mask for this node */ + if (buffer->size < node_cpu_mask_v2[node]->size) { + errno = EINVAL; +@@ -1407,8 +1421,12 @@ numa_node_to_cpus_v2(int node, struct bitmask *buffer) + /* slightly racy, see above */ + /* save the mask we created */ + if (node_cpu_mask_v2[node]) { ++ if (update) { ++ copy_bitmask_to_bitmask(mask, node_cpu_mask_v2[node]); ++ numa_bitmask_free(mask); ++ mask = NULL; + /* how could this be? */ +- if (mask != buffer) ++ } else if (mask != buffer) + numa_bitmask_free(mask); + } else { + /* we don't want to cache faulty result */ +@@ -1424,6 +1442,12 @@ __asm__(".symver numa_node_to_cpus_v2,numa_node_to_cpus@@libnuma_1.2"); + make_internal_alias(numa_node_to_cpus_v1); + make_internal_alias(numa_node_to_cpus_v2); + ++void numa_node_to_cpu_update(void) ++{ ++ __atomic_store_n(&node_cpu_mask_v1_stale, 1, __ATOMIC_RELAXED); ++ __atomic_store_n(&node_cpu_mask_v2_stale, 1, __ATOMIC_RELAXED); ++} ++ + /* report the node of the specified cpu */ + int numa_node_of_cpu(int cpu) + { +diff --git a/numa.3 b/numa.3 +index ba00572..e54cb0b 100644 +--- a/numa.3 ++++ b/numa.3 +@@ -124,6 +124,8 @@ numa \- NUMA policy library + .br + .BI "int numa_node_to_cpus(int " node ", struct bitmask *" mask "); + .br ++.BI "void numa_node_to_cpu_update();" ++.br + .BI "int numa_node_of_cpu(int " cpu "); + .sp + .BI "struct bitmask *numa_allocate_cpumask();" +@@ -232,6 +234,7 @@ Most functions in this library are only concerned about numa nodes and + their memory. + The exceptions to this are: + .IR numa_node_to_cpus (), ++.IR numa_node_to_cpu_update (), + .IR numa_node_of_cpu (), + .IR numa_bind (), + .IR numa_run_on_node (), +@@ -795,6 +798,10 @@ will be set to + .I ERANGE + and \-1 returned. On success 0 is returned. + ++.BR numa_node_to_cpu_update () ++Mark the node's cpus bitmask stale, then get the latest bitmask by calling ++.BR numa_node_to_cpus () ++ + .BR numa_node_of_cpu () + returns the node that a cpu belongs to. If the user supplies an invalid cpu + .I errno +diff --git a/numa.h b/numa.h +index 3a8c543..7316d1e 100644 +--- a/numa.h ++++ b/numa.h +@@ -282,6 +282,8 @@ static inline void numa_free_cpumask(struct bitmask *b) + /* Convert node to CPU mask. -1/errno on failure, otherwise 0. */ + int numa_node_to_cpus(int, struct bitmask *); + ++void numa_node_to_cpu_update(void); ++ + /* report the node of the specified cpu. -1/errno on invalid cpu. */ + int numa_node_of_cpu(int cpu); + +diff --git a/versions.ldscript b/versions.ldscript +index 4b04936..23074a0 100644 +--- a/versions.ldscript ++++ b/versions.ldscript +@@ -60,6 +60,7 @@ libnuma_1.1 { + numa_tonodemask_memory; + numa_warn; + numa_exit_on_warn; ++ numa_node_to_cpu_update; + local: + *; + }; +-- +2.7.5 + diff --git a/SPECS/numactl.spec b/SPECS/numactl.spec index 59325ce..80305ec 100644 --- a/SPECS/numactl.spec +++ b/SPECS/numactl.spec @@ -1,7 +1,7 @@ Name: numactl Summary: Library for tuning for Non Uniform Memory Access machines Version: 2.0.12 -Release: 3%{?dist}.1 +Release: 5%{?dist} # libnuma is LGPLv2 and GPLv2 # numactl binaries are GPLv2 only License: GPLv2 @@ -14,7 +14,9 @@ BuildRequires: libtool automake autoconf ExcludeArch: s390 s390x %{arm} Patch1: numactl-2.0.12-numastat-when-reading-no-exist-pid-return-EXIT_FAILU.patch -Patch2: numactl-2.0.12-Fix-crashes-when-using-the-touch-option.patch +Patch2: numactl-2.0.12-libnuma-introduce-an-API-to-outdate-cpu-to-node-mapp.patch +Patch3: numactl-2.0.12-Update-manpage-description-of-numa_node_to_cpu_updat.patch +Patch4: numactl-2.0.12-Fix-crashes-when-using-the-touch-option.patch %description Simple NUMA policy support. It consists of a numactl program to run @@ -43,6 +45,8 @@ Provides development headers for numa library calls %setup -q -n %{name}-%{version} %patch1 -p1 %patch2 -p1 +%patch3 -p1 +%patch4 -p1 %build %configure --prefix=/usr --libdir=%{_libdir} @@ -86,9 +90,12 @@ make DESTDIR=$RPM_BUILD_ROOT install %{_mandir}/man3/*.3* %changelog -* Thu Oct 17 2019 Pingfan Liu - 2.0.12-3.1 +* Fri Oct 18 2019 Pingfan Liu - 2.0.12-5 - Fix crashes when using the "--touch" option +* Wed Sep 18 2019 Pingfan Liu - 2.0.12-4 +- libnuma: introduce an API to outdate cpu to node mapping + * Sat Jun 1 2019 Pingfan Liu - 2.0.12-3 - numastat: bail out if reading no-exist pid