summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShivank Garg <shivankg@amd.com>2025-10-16 10:28:51 -0700
committerSean Christopherson <seanjc@google.com>2025-10-20 06:30:44 -0700
commite698e89b3ed1772e543a5ab4c072b9bbdb730948 (patch)
treeae895b6d66e6a1c1de69fad85d2a8eba0053f5cb
parentfe7baebb99de95f171911d085abcfab1db04a7ed (diff)
KVM: selftests: Add helpers to probe for NUMA support, and multi-node systems
Add NUMA helpers to probe for support/availability and to check if the test is running on a multi-node system. The APIs will be used to verify guest_memfd NUMA support. Signed-off-by: Shivank Garg <shivankg@amd.com> [sean: land helpers in numaif.h, add comments, tweak names] Link: https://lore.kernel.org/r/20251016172853.52451-11-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
-rw-r--r--tools/testing/selftests/kvm/include/numaif.h52
1 files changed, 52 insertions, 0 deletions
diff --git a/tools/testing/selftests/kvm/include/numaif.h b/tools/testing/selftests/kvm/include/numaif.h
index 1554003c40a1..29572a6d789c 100644
--- a/tools/testing/selftests/kvm/include/numaif.h
+++ b/tools/testing/selftests/kvm/include/numaif.h
@@ -4,6 +4,8 @@
#ifndef SELFTEST_KVM_NUMAIF_H
#define SELFTEST_KVM_NUMAIF_H
+#include <dirent.h>
+
#include <linux/mempolicy.h>
#include "kvm_syscalls.h"
@@ -28,4 +30,54 @@ KVM_SYSCALL_DEFINE(mbind, 6, void *, addr, unsigned long, size, int, mode,
const unsigned long *, nodemask, unsigned long, maxnode,
unsigned int, flags);
+static inline int get_max_numa_node(void)
+{
+ struct dirent *de;
+ int max_node = 0;
+ DIR *d;
+
+ /*
+ * Assume there's a single node if the kernel doesn't support NUMA,
+ * or if no nodes are found.
+ */
+ d = opendir("/sys/devices/system/node");
+ if (!d)
+ return 0;
+
+ while ((de = readdir(d)) != NULL) {
+ int node_id;
+ char *endptr;
+
+ if (strncmp(de->d_name, "node", 4) != 0)
+ continue;
+
+ node_id = strtol(de->d_name + 4, &endptr, 10);
+ if (*endptr != '\0')
+ continue;
+
+ if (node_id > max_node)
+ max_node = node_id;
+ }
+ closedir(d);
+
+ return max_node;
+}
+
+static bool is_numa_available(void)
+{
+ /*
+ * Probe for NUMA by doing a dummy get_mempolicy(). If the syscall
+ * fails with ENOSYS, then the kernel was built without NUMA support.
+ * if the syscall fails with EPERM, then the process/user lacks the
+ * necessary capabilities (CAP_SYS_NICE).
+ */
+ return !get_mempolicy(NULL, NULL, 0, NULL, 0) ||
+ (errno != ENOSYS && errno != EPERM);
+}
+
+static inline bool is_multi_numa_node_system(void)
+{
+ return is_numa_available() && get_max_numa_node() >= 1;
+}
+
#endif /* SELFTEST_KVM_NUMAIF_H */