membarrier_test.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #define _GNU_SOURCE
  2. #define __EXPORTED_HEADERS__
  3. #include <linux/membarrier.h>
  4. #include <asm-generic/unistd.h>
  5. #include <sys/syscall.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8. #include <string.h>
  9. #include "../kselftest.h"
  10. enum test_membarrier_status {
  11. TEST_MEMBARRIER_PASS = 0,
  12. TEST_MEMBARRIER_FAIL,
  13. TEST_MEMBARRIER_SKIP,
  14. };
  15. static int sys_membarrier(int cmd, int flags)
  16. {
  17. return syscall(__NR_membarrier, cmd, flags);
  18. }
  19. static enum test_membarrier_status test_membarrier_cmd_fail(void)
  20. {
  21. int cmd = -1, flags = 0;
  22. if (sys_membarrier(cmd, flags) != -1) {
  23. printf("membarrier: Wrong command should fail but passed.\n");
  24. return TEST_MEMBARRIER_FAIL;
  25. }
  26. return TEST_MEMBARRIER_PASS;
  27. }
  28. static enum test_membarrier_status test_membarrier_flags_fail(void)
  29. {
  30. int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
  31. if (sys_membarrier(cmd, flags) != -1) {
  32. printf("membarrier: Wrong flags should fail but passed.\n");
  33. return TEST_MEMBARRIER_FAIL;
  34. }
  35. return TEST_MEMBARRIER_PASS;
  36. }
  37. static enum test_membarrier_status test_membarrier_success(void)
  38. {
  39. int cmd = MEMBARRIER_CMD_SHARED, flags = 0;
  40. if (sys_membarrier(cmd, flags) != 0) {
  41. printf("membarrier: Executing MEMBARRIER_CMD_SHARED failed. %s.\n",
  42. strerror(errno));
  43. return TEST_MEMBARRIER_FAIL;
  44. }
  45. printf("membarrier: MEMBARRIER_CMD_SHARED success.\n");
  46. return TEST_MEMBARRIER_PASS;
  47. }
  48. static enum test_membarrier_status test_membarrier(void)
  49. {
  50. enum test_membarrier_status status;
  51. status = test_membarrier_cmd_fail();
  52. if (status)
  53. return status;
  54. status = test_membarrier_flags_fail();
  55. if (status)
  56. return status;
  57. status = test_membarrier_success();
  58. if (status)
  59. return status;
  60. return TEST_MEMBARRIER_PASS;
  61. }
  62. static enum test_membarrier_status test_membarrier_query(void)
  63. {
  64. int flags = 0, ret;
  65. printf("membarrier MEMBARRIER_CMD_QUERY ");
  66. ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags);
  67. if (ret < 0) {
  68. printf("failed. %s.\n", strerror(errno));
  69. switch (errno) {
  70. case ENOSYS:
  71. /*
  72. * It is valid to build a kernel with
  73. * CONFIG_MEMBARRIER=n. However, this skips the tests.
  74. */
  75. return TEST_MEMBARRIER_SKIP;
  76. case EINVAL:
  77. default:
  78. return TEST_MEMBARRIER_FAIL;
  79. }
  80. }
  81. if (!(ret & MEMBARRIER_CMD_SHARED)) {
  82. printf("command MEMBARRIER_CMD_SHARED is not supported.\n");
  83. return TEST_MEMBARRIER_FAIL;
  84. }
  85. printf("syscall available.\n");
  86. return TEST_MEMBARRIER_PASS;
  87. }
  88. int main(int argc, char **argv)
  89. {
  90. switch (test_membarrier_query()) {
  91. case TEST_MEMBARRIER_FAIL:
  92. return ksft_exit_fail();
  93. case TEST_MEMBARRIER_SKIP:
  94. return ksft_exit_skip();
  95. }
  96. switch (test_membarrier()) {
  97. case TEST_MEMBARRIER_FAIL:
  98. return ksft_exit_fail();
  99. case TEST_MEMBARRIER_SKIP:
  100. return ksft_exit_skip();
  101. }
  102. printf("membarrier: tests done!\n");
  103. return ksft_exit_pass();
  104. }