numaif.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /* Copyright (C) 2020, Google LLC. */
  3. #ifndef SELFTEST_KVM_NUMAIF_H
  4. #define SELFTEST_KVM_NUMAIF_H
  5. #include <dirent.h>
  6. #include <linux/mempolicy.h>
  7. #include "kvm_syscalls.h"
  8. KVM_SYSCALL_DEFINE(get_mempolicy, 5, int *, policy, const unsigned long *, nmask,
  9. unsigned long, maxnode, void *, addr, int, flags);
  10. KVM_SYSCALL_DEFINE(set_mempolicy, 3, int, mode, const unsigned long *, nmask,
  11. unsigned long, maxnode);
  12. KVM_SYSCALL_DEFINE(set_mempolicy_home_node, 4, unsigned long, start,
  13. unsigned long, len, unsigned long, home_node,
  14. unsigned long, flags);
  15. KVM_SYSCALL_DEFINE(migrate_pages, 4, int, pid, unsigned long, maxnode,
  16. const unsigned long *, frommask, const unsigned long *, tomask);
  17. KVM_SYSCALL_DEFINE(move_pages, 6, int, pid, unsigned long, count, void *, pages,
  18. const int *, nodes, int *, status, int, flags);
  19. KVM_SYSCALL_DEFINE(mbind, 6, void *, addr, unsigned long, size, int, mode,
  20. const unsigned long *, nodemask, unsigned long, maxnode,
  21. unsigned int, flags);
  22. static inline int get_max_numa_node(void)
  23. {
  24. struct dirent *de;
  25. int max_node = 0;
  26. DIR *d;
  27. /*
  28. * Assume there's a single node if the kernel doesn't support NUMA,
  29. * or if no nodes are found.
  30. */
  31. d = opendir("/sys/devices/system/node");
  32. if (!d)
  33. return 0;
  34. while ((de = readdir(d)) != NULL) {
  35. int node_id;
  36. char *endptr;
  37. if (strncmp(de->d_name, "node", 4) != 0)
  38. continue;
  39. node_id = strtol(de->d_name + 4, &endptr, 10);
  40. if (*endptr != '\0')
  41. continue;
  42. if (node_id > max_node)
  43. max_node = node_id;
  44. }
  45. closedir(d);
  46. return max_node;
  47. }
  48. static bool is_numa_available(void)
  49. {
  50. /*
  51. * Probe for NUMA by doing a dummy get_mempolicy(). If the syscall
  52. * fails with ENOSYS, then the kernel was built without NUMA support.
  53. * if the syscall fails with EPERM, then the process/user lacks the
  54. * necessary capabilities (CAP_SYS_NICE).
  55. */
  56. return !get_mempolicy(NULL, NULL, 0, NULL, 0) ||
  57. (errno != ENOSYS && errno != EPERM);
  58. }
  59. static inline bool is_multi_numa_node_system(void)
  60. {
  61. return is_numa_available() && get_max_numa_node() >= 1;
  62. }
  63. #endif /* SELFTEST_KVM_NUMAIF_H */