membarrier_test_impl.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #define _GNU_SOURCE
  3. #include <linux/membarrier.h>
  4. #include <syscall.h>
  5. #include <stdio.h>
  6. #include <errno.h>
  7. #include <string.h>
  8. #include <pthread.h>
  9. #include "../kselftest.h"
  10. static int registrations;
  11. static int sys_membarrier(int cmd, int flags)
  12. {
  13. return syscall(__NR_membarrier, cmd, flags);
  14. }
  15. static int test_membarrier_get_registrations(int cmd)
  16. {
  17. int ret, flags = 0;
  18. const char *test_name =
  19. "sys membarrier MEMBARRIER_CMD_GET_REGISTRATIONS";
  20. registrations |= cmd;
  21. ret = sys_membarrier(MEMBARRIER_CMD_GET_REGISTRATIONS, 0);
  22. if (ret < 0) {
  23. ksft_exit_fail_msg(
  24. "%s test: flags = %d, errno = %d\n",
  25. test_name, flags, errno);
  26. } else if (ret != registrations) {
  27. ksft_exit_fail_msg(
  28. "%s test: flags = %d, ret = %d, registrations = %d\n",
  29. test_name, flags, ret, registrations);
  30. }
  31. ksft_test_result_pass(
  32. "%s test: flags = %d, ret = %d, registrations = %d\n",
  33. test_name, flags, ret, registrations);
  34. return 0;
  35. }
  36. static int test_membarrier_cmd_fail(void)
  37. {
  38. int cmd = -1, flags = 0;
  39. const char *test_name = "sys membarrier invalid command";
  40. if (sys_membarrier(cmd, flags) != -1) {
  41. ksft_exit_fail_msg(
  42. "%s test: command = %d, flags = %d. Should fail, but passed\n",
  43. test_name, cmd, flags);
  44. }
  45. if (errno != EINVAL) {
  46. ksft_exit_fail_msg(
  47. "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
  48. test_name, flags, EINVAL, strerror(EINVAL),
  49. errno, strerror(errno));
  50. }
  51. ksft_test_result_pass(
  52. "%s test: command = %d, flags = %d, errno = %d. Failed as expected\n",
  53. test_name, cmd, flags, errno);
  54. return 0;
  55. }
  56. static int test_membarrier_flags_fail(void)
  57. {
  58. int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
  59. const char *test_name = "sys membarrier MEMBARRIER_CMD_QUERY invalid flags";
  60. if (sys_membarrier(cmd, flags) != -1) {
  61. ksft_exit_fail_msg(
  62. "%s test: flags = %d. Should fail, but passed\n",
  63. test_name, flags);
  64. }
  65. if (errno != EINVAL) {
  66. ksft_exit_fail_msg(
  67. "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
  68. test_name, flags, EINVAL, strerror(EINVAL),
  69. errno, strerror(errno));
  70. }
  71. ksft_test_result_pass(
  72. "%s test: flags = %d, errno = %d. Failed as expected\n",
  73. test_name, flags, errno);
  74. return 0;
  75. }
  76. static int test_membarrier_global_success(void)
  77. {
  78. int cmd = MEMBARRIER_CMD_GLOBAL, flags = 0;
  79. const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL";
  80. if (sys_membarrier(cmd, flags) != 0) {
  81. ksft_exit_fail_msg(
  82. "%s test: flags = %d, errno = %d\n",
  83. test_name, flags, errno);
  84. }
  85. ksft_test_result_pass(
  86. "%s test: flags = %d\n", test_name, flags);
  87. return 0;
  88. }
  89. static int test_membarrier_private_expedited_fail(void)
  90. {
  91. int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
  92. const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED not registered failure";
  93. if (sys_membarrier(cmd, flags) != -1) {
  94. ksft_exit_fail_msg(
  95. "%s test: flags = %d. Should fail, but passed\n",
  96. test_name, flags);
  97. }
  98. if (errno != EPERM) {
  99. ksft_exit_fail_msg(
  100. "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
  101. test_name, flags, EPERM, strerror(EPERM),
  102. errno, strerror(errno));
  103. }
  104. ksft_test_result_pass(
  105. "%s test: flags = %d, errno = %d\n",
  106. test_name, flags, errno);
  107. return 0;
  108. }
  109. static int test_membarrier_register_private_expedited_success(void)
  110. {
  111. int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, flags = 0;
  112. const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED";
  113. if (sys_membarrier(cmd, flags) != 0) {
  114. ksft_exit_fail_msg(
  115. "%s test: flags = %d, errno = %d\n",
  116. test_name, flags, errno);
  117. }
  118. ksft_test_result_pass(
  119. "%s test: flags = %d\n",
  120. test_name, flags);
  121. test_membarrier_get_registrations(cmd);
  122. return 0;
  123. }
  124. static int test_membarrier_private_expedited_success(void)
  125. {
  126. int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
  127. const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED";
  128. if (sys_membarrier(cmd, flags) != 0) {
  129. ksft_exit_fail_msg(
  130. "%s test: flags = %d, errno = %d\n",
  131. test_name, flags, errno);
  132. }
  133. ksft_test_result_pass(
  134. "%s test: flags = %d\n",
  135. test_name, flags);
  136. return 0;
  137. }
  138. static int test_membarrier_private_expedited_sync_core_fail(void)
  139. {
  140. int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
  141. const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE not registered failure";
  142. if (sys_membarrier(cmd, flags) != -1) {
  143. ksft_exit_fail_msg(
  144. "%s test: flags = %d. Should fail, but passed\n",
  145. test_name, flags);
  146. }
  147. if (errno != EPERM) {
  148. ksft_exit_fail_msg(
  149. "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
  150. test_name, flags, EPERM, strerror(EPERM),
  151. errno, strerror(errno));
  152. }
  153. ksft_test_result_pass(
  154. "%s test: flags = %d, errno = %d\n",
  155. test_name, flags, errno);
  156. return 0;
  157. }
  158. static int test_membarrier_register_private_expedited_sync_core_success(void)
  159. {
  160. int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
  161. const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE";
  162. if (sys_membarrier(cmd, flags) != 0) {
  163. ksft_exit_fail_msg(
  164. "%s test: flags = %d, errno = %d\n",
  165. test_name, flags, errno);
  166. }
  167. ksft_test_result_pass(
  168. "%s test: flags = %d\n",
  169. test_name, flags);
  170. test_membarrier_get_registrations(cmd);
  171. return 0;
  172. }
  173. static int test_membarrier_private_expedited_sync_core_success(void)
  174. {
  175. int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
  176. const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE";
  177. if (sys_membarrier(cmd, flags) != 0) {
  178. ksft_exit_fail_msg(
  179. "%s test: flags = %d, errno = %d\n",
  180. test_name, flags, errno);
  181. }
  182. ksft_test_result_pass(
  183. "%s test: flags = %d\n",
  184. test_name, flags);
  185. return 0;
  186. }
  187. static int test_membarrier_register_global_expedited_success(void)
  188. {
  189. int cmd = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, flags = 0;
  190. const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED";
  191. if (sys_membarrier(cmd, flags) != 0) {
  192. ksft_exit_fail_msg(
  193. "%s test: flags = %d, errno = %d\n",
  194. test_name, flags, errno);
  195. }
  196. ksft_test_result_pass(
  197. "%s test: flags = %d\n",
  198. test_name, flags);
  199. test_membarrier_get_registrations(cmd);
  200. return 0;
  201. }
  202. static int test_membarrier_global_expedited_success(void)
  203. {
  204. int cmd = MEMBARRIER_CMD_GLOBAL_EXPEDITED, flags = 0;
  205. const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL_EXPEDITED";
  206. if (sys_membarrier(cmd, flags) != 0) {
  207. ksft_exit_fail_msg(
  208. "%s test: flags = %d, errno = %d\n",
  209. test_name, flags, errno);
  210. }
  211. ksft_test_result_pass(
  212. "%s test: flags = %d\n",
  213. test_name, flags);
  214. return 0;
  215. }
  216. static int test_membarrier_fail(void)
  217. {
  218. int status;
  219. status = test_membarrier_cmd_fail();
  220. if (status)
  221. return status;
  222. status = test_membarrier_flags_fail();
  223. if (status)
  224. return status;
  225. status = test_membarrier_private_expedited_fail();
  226. if (status)
  227. return status;
  228. status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
  229. if (status < 0) {
  230. ksft_test_result_fail("sys_membarrier() failed\n");
  231. return status;
  232. }
  233. if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {
  234. status = test_membarrier_private_expedited_sync_core_fail();
  235. if (status)
  236. return status;
  237. }
  238. return 0;
  239. }
  240. static int test_membarrier_success(void)
  241. {
  242. int status;
  243. status = test_membarrier_global_success();
  244. if (status)
  245. return status;
  246. status = test_membarrier_register_private_expedited_success();
  247. if (status)
  248. return status;
  249. status = test_membarrier_private_expedited_success();
  250. if (status)
  251. return status;
  252. status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
  253. if (status < 0) {
  254. ksft_test_result_fail("sys_membarrier() failed\n");
  255. return status;
  256. }
  257. if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {
  258. status = test_membarrier_register_private_expedited_sync_core_success();
  259. if (status)
  260. return status;
  261. status = test_membarrier_private_expedited_sync_core_success();
  262. if (status)
  263. return status;
  264. }
  265. /*
  266. * It is valid to send a global membarrier from a non-registered
  267. * process.
  268. */
  269. status = test_membarrier_global_expedited_success();
  270. if (status)
  271. return status;
  272. status = test_membarrier_register_global_expedited_success();
  273. if (status)
  274. return status;
  275. status = test_membarrier_global_expedited_success();
  276. if (status)
  277. return status;
  278. return 0;
  279. }
  280. static int test_membarrier_query(void)
  281. {
  282. int flags = 0, ret;
  283. ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags);
  284. if (ret < 0) {
  285. if (errno == ENOSYS) {
  286. /*
  287. * It is valid to build a kernel with
  288. * CONFIG_MEMBARRIER=n. However, this skips the tests.
  289. */
  290. ksft_exit_skip(
  291. "sys membarrier (CONFIG_MEMBARRIER) is disabled.\n");
  292. }
  293. ksft_exit_fail_msg("sys_membarrier() failed\n");
  294. }
  295. if (!(ret & MEMBARRIER_CMD_GLOBAL))
  296. ksft_exit_skip(
  297. "sys_membarrier unsupported: CMD_GLOBAL not found.\n");
  298. ksft_test_result_pass("sys_membarrier available\n");
  299. return 0;
  300. }