Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #define _GNU_SOURCE
0003 #include <linux/membarrier.h>
0004 #include <syscall.h>
0005 #include <stdio.h>
0006 #include <errno.h>
0007 #include <string.h>
0008 #include <pthread.h>
0009 
0010 #include "../kselftest.h"
0011 
0012 static int sys_membarrier(int cmd, int flags)
0013 {
0014     return syscall(__NR_membarrier, cmd, flags);
0015 }
0016 
0017 static int test_membarrier_cmd_fail(void)
0018 {
0019     int cmd = -1, flags = 0;
0020     const char *test_name = "sys membarrier invalid command";
0021 
0022     if (sys_membarrier(cmd, flags) != -1) {
0023         ksft_exit_fail_msg(
0024             "%s test: command = %d, flags = %d. Should fail, but passed\n",
0025             test_name, cmd, flags);
0026     }
0027     if (errno != EINVAL) {
0028         ksft_exit_fail_msg(
0029             "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
0030             test_name, flags, EINVAL, strerror(EINVAL),
0031             errno, strerror(errno));
0032     }
0033 
0034     ksft_test_result_pass(
0035         "%s test: command = %d, flags = %d, errno = %d. Failed as expected\n",
0036         test_name, cmd, flags, errno);
0037     return 0;
0038 }
0039 
0040 static int test_membarrier_flags_fail(void)
0041 {
0042     int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
0043     const char *test_name = "sys membarrier MEMBARRIER_CMD_QUERY invalid flags";
0044 
0045     if (sys_membarrier(cmd, flags) != -1) {
0046         ksft_exit_fail_msg(
0047             "%s test: flags = %d. Should fail, but passed\n",
0048             test_name, flags);
0049     }
0050     if (errno != EINVAL) {
0051         ksft_exit_fail_msg(
0052             "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
0053             test_name, flags, EINVAL, strerror(EINVAL),
0054             errno, strerror(errno));
0055     }
0056 
0057     ksft_test_result_pass(
0058         "%s test: flags = %d, errno = %d. Failed as expected\n",
0059         test_name, flags, errno);
0060     return 0;
0061 }
0062 
0063 static int test_membarrier_global_success(void)
0064 {
0065     int cmd = MEMBARRIER_CMD_GLOBAL, flags = 0;
0066     const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL";
0067 
0068     if (sys_membarrier(cmd, flags) != 0) {
0069         ksft_exit_fail_msg(
0070             "%s test: flags = %d, errno = %d\n",
0071             test_name, flags, errno);
0072     }
0073 
0074     ksft_test_result_pass(
0075         "%s test: flags = %d\n", test_name, flags);
0076     return 0;
0077 }
0078 
0079 static int test_membarrier_private_expedited_fail(void)
0080 {
0081     int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
0082     const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED not registered failure";
0083 
0084     if (sys_membarrier(cmd, flags) != -1) {
0085         ksft_exit_fail_msg(
0086             "%s test: flags = %d. Should fail, but passed\n",
0087             test_name, flags);
0088     }
0089     if (errno != EPERM) {
0090         ksft_exit_fail_msg(
0091             "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
0092             test_name, flags, EPERM, strerror(EPERM),
0093             errno, strerror(errno));
0094     }
0095 
0096     ksft_test_result_pass(
0097         "%s test: flags = %d, errno = %d\n",
0098         test_name, flags, errno);
0099     return 0;
0100 }
0101 
0102 static int test_membarrier_register_private_expedited_success(void)
0103 {
0104     int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, flags = 0;
0105     const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED";
0106 
0107     if (sys_membarrier(cmd, flags) != 0) {
0108         ksft_exit_fail_msg(
0109             "%s test: flags = %d, errno = %d\n",
0110             test_name, flags, errno);
0111     }
0112 
0113     ksft_test_result_pass(
0114         "%s test: flags = %d\n",
0115         test_name, flags);
0116     return 0;
0117 }
0118 
0119 static int test_membarrier_private_expedited_success(void)
0120 {
0121     int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
0122     const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED";
0123 
0124     if (sys_membarrier(cmd, flags) != 0) {
0125         ksft_exit_fail_msg(
0126             "%s test: flags = %d, errno = %d\n",
0127             test_name, flags, errno);
0128     }
0129 
0130     ksft_test_result_pass(
0131         "%s test: flags = %d\n",
0132         test_name, flags);
0133     return 0;
0134 }
0135 
0136 static int test_membarrier_private_expedited_sync_core_fail(void)
0137 {
0138     int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
0139     const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE not registered failure";
0140 
0141     if (sys_membarrier(cmd, flags) != -1) {
0142         ksft_exit_fail_msg(
0143             "%s test: flags = %d. Should fail, but passed\n",
0144             test_name, flags);
0145     }
0146     if (errno != EPERM) {
0147         ksft_exit_fail_msg(
0148             "%s test: flags = %d. Should return (%d: \"%s\"), but returned (%d: \"%s\").\n",
0149             test_name, flags, EPERM, strerror(EPERM),
0150             errno, strerror(errno));
0151     }
0152 
0153     ksft_test_result_pass(
0154         "%s test: flags = %d, errno = %d\n",
0155         test_name, flags, errno);
0156     return 0;
0157 }
0158 
0159 static int test_membarrier_register_private_expedited_sync_core_success(void)
0160 {
0161     int cmd = MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE, flags = 0;
0162     const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE";
0163 
0164     if (sys_membarrier(cmd, flags) != 0) {
0165         ksft_exit_fail_msg(
0166             "%s test: flags = %d, errno = %d\n",
0167             test_name, flags, errno);
0168     }
0169 
0170     ksft_test_result_pass(
0171         "%s test: flags = %d\n",
0172         test_name, flags);
0173     return 0;
0174 }
0175 
0176 static int test_membarrier_private_expedited_sync_core_success(void)
0177 {
0178     int cmd = MEMBARRIER_CMD_PRIVATE_EXPEDITED, flags = 0;
0179     const char *test_name = "sys membarrier MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE";
0180 
0181     if (sys_membarrier(cmd, flags) != 0) {
0182         ksft_exit_fail_msg(
0183             "%s test: flags = %d, errno = %d\n",
0184             test_name, flags, errno);
0185     }
0186 
0187     ksft_test_result_pass(
0188         "%s test: flags = %d\n",
0189         test_name, flags);
0190     return 0;
0191 }
0192 
0193 static int test_membarrier_register_global_expedited_success(void)
0194 {
0195     int cmd = MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, flags = 0;
0196     const char *test_name = "sys membarrier MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED";
0197 
0198     if (sys_membarrier(cmd, flags) != 0) {
0199         ksft_exit_fail_msg(
0200             "%s test: flags = %d, errno = %d\n",
0201             test_name, flags, errno);
0202     }
0203 
0204     ksft_test_result_pass(
0205         "%s test: flags = %d\n",
0206         test_name, flags);
0207     return 0;
0208 }
0209 
0210 static int test_membarrier_global_expedited_success(void)
0211 {
0212     int cmd = MEMBARRIER_CMD_GLOBAL_EXPEDITED, flags = 0;
0213     const char *test_name = "sys membarrier MEMBARRIER_CMD_GLOBAL_EXPEDITED";
0214 
0215     if (sys_membarrier(cmd, flags) != 0) {
0216         ksft_exit_fail_msg(
0217             "%s test: flags = %d, errno = %d\n",
0218             test_name, flags, errno);
0219     }
0220 
0221     ksft_test_result_pass(
0222         "%s test: flags = %d\n",
0223         test_name, flags);
0224     return 0;
0225 }
0226 
0227 static int test_membarrier_fail(void)
0228 {
0229     int status;
0230 
0231     status = test_membarrier_cmd_fail();
0232     if (status)
0233         return status;
0234     status = test_membarrier_flags_fail();
0235     if (status)
0236         return status;
0237     status = test_membarrier_private_expedited_fail();
0238     if (status)
0239         return status;
0240     status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
0241     if (status < 0) {
0242         ksft_test_result_fail("sys_membarrier() failed\n");
0243         return status;
0244     }
0245     if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {
0246         status = test_membarrier_private_expedited_sync_core_fail();
0247         if (status)
0248             return status;
0249     }
0250     return 0;
0251 }
0252 
0253 static int test_membarrier_success(void)
0254 {
0255     int status;
0256 
0257     status = test_membarrier_global_success();
0258     if (status)
0259         return status;
0260     status = test_membarrier_register_private_expedited_success();
0261     if (status)
0262         return status;
0263     status = test_membarrier_private_expedited_success();
0264     if (status)
0265         return status;
0266     status = sys_membarrier(MEMBARRIER_CMD_QUERY, 0);
0267     if (status < 0) {
0268         ksft_test_result_fail("sys_membarrier() failed\n");
0269         return status;
0270     }
0271     if (status & MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE) {
0272         status = test_membarrier_register_private_expedited_sync_core_success();
0273         if (status)
0274             return status;
0275         status = test_membarrier_private_expedited_sync_core_success();
0276         if (status)
0277             return status;
0278     }
0279     /*
0280      * It is valid to send a global membarrier from a non-registered
0281      * process.
0282      */
0283     status = test_membarrier_global_expedited_success();
0284     if (status)
0285         return status;
0286     status = test_membarrier_register_global_expedited_success();
0287     if (status)
0288         return status;
0289     status = test_membarrier_global_expedited_success();
0290     if (status)
0291         return status;
0292     return 0;
0293 }
0294 
0295 static int test_membarrier_query(void)
0296 {
0297     int flags = 0, ret;
0298 
0299     ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags);
0300     if (ret < 0) {
0301         if (errno == ENOSYS) {
0302             /*
0303              * It is valid to build a kernel with
0304              * CONFIG_MEMBARRIER=n. However, this skips the tests.
0305              */
0306             ksft_exit_skip(
0307                 "sys membarrier (CONFIG_MEMBARRIER) is disabled.\n");
0308         }
0309         ksft_exit_fail_msg("sys_membarrier() failed\n");
0310     }
0311     if (!(ret & MEMBARRIER_CMD_GLOBAL))
0312         ksft_exit_skip(
0313             "sys_membarrier unsupported: CMD_GLOBAL not found.\n");
0314 
0315     ksft_test_result_pass("sys_membarrier available\n");
0316     return 0;
0317 }