sys_membarrier underwent changes between its original implementation and
its upcoming inclusion into the Linux kernel. Update its use to follow
those changes.
Should the prior user-space code be built against a kernel header that
defines SYS_membarrier, and executed against that kernel, the following
scenarios may happen:
- -1 will be returned with EINVAL errno if the 2nd argument (flags) is
non-zero (the previous ABI expected a single argument),
- (MEMBARRIER_EXPEDITED | MEMBARRIER_QUERY) defined as
(1 << 0) | (1 << 16) will return -1 with EINVAL errno, because valid
commands are now one-hot.
Therefore, should an incompatible user-space code try to use
sys_membarrier, it will simply think that the system does not have
membarrier support due to the negative return value upon query.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
# define membarrier(...) -ENOSYS
#endif
# define membarrier(...) -ENOSYS
#endif
-#define MEMBARRIER_EXPEDITED (1 << 0)
-#define MEMBARRIER_DELAYED (1 << 1)
-#define MEMBARRIER_QUERY (1 << 16)
+enum membarrier_cmd {
+ MEMBARRIER_CMD_QUERY = 0,
+ MEMBARRIER_CMD_SHARED = (1 << 0),
+};
#ifdef RCU_MEMBARRIER
static int init_done;
#ifdef RCU_MEMBARRIER
static int init_done;
static void smp_mb_master(int group)
{
if (caa_likely(rcu_has_sys_membarrier))
static void smp_mb_master(int group)
{
if (caa_likely(rcu_has_sys_membarrier))
- (void) membarrier(MEMBARRIER_EXPEDITED);
+ (void) membarrier(MEMBARRIER_CMD_SHARED, 0);
#ifdef RCU_MEMBARRIER
void rcu_init(void)
{
#ifdef RCU_MEMBARRIER
void rcu_init(void)
{
if (init_done)
return;
init_done = 1;
if (init_done)
return;
init_done = 1;
- if (!membarrier(MEMBARRIER_EXPEDITED | MEMBARRIER_QUERY))
+ ret = membarrier(MEMBARRIER_CMD_QUERY, 0);
+ if (ret >= 0 && (ret & MEMBARRIER_CMD_SHARED)) {
rcu_has_sys_membarrier = 1;
rcu_has_sys_membarrier = 1;