membarrier_test.c 2.6 KB

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