From: Mathieu Desnoyers Date: Sat, 29 Aug 2015 03:15:33 +0000 (-0400) Subject: Update following changes to sys_membarrier ABI X-Git-Tag: v0.9.0~44 X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=commitdiff_plain;h=64f469e628fe45059f091f2808188fb52fa109c9 Update following changes to sys_membarrier ABI 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 --- diff --git a/urcu.c b/urcu.c index e773065..5ffeb79 100644 --- a/urcu.c +++ b/urcu.c @@ -77,9 +77,10 @@ # 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; @@ -167,7 +168,7 @@ static void mutex_unlock(pthread_mutex_t *mutex) static void smp_mb_master(int group) { if (caa_likely(rcu_has_sys_membarrier)) - (void) membarrier(MEMBARRIER_EXPEDITED); + (void) membarrier(MEMBARRIER_CMD_SHARED, 0); else cmm_smp_mb(); } @@ -514,11 +515,15 @@ void rcu_unregister_thread(void) #ifdef RCU_MEMBARRIER void rcu_init(void) { + int ret; + 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; + } } #endif