History

membarrier: Provide GLOBAL_EXPEDITED command

Allow expedited membarrier to be used for data shared between processes through shared memory. Processes wishing to receive the membarriers register with MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED. Those which want to issue membarrier invoke MEMBARRIER_CMD_GLOBAL_EXPEDITED. This allows extremely simple kernel-level implementation: we have almost everything we need with the PRIVATE_EXPEDITED barrier code. All we need to do is to add a flag in the mm_struct that will be used to check whether we need to send the IPI to the current thread of each CPU. There is a slight downside to this approach compared to targeting specific shared memory users: when performing a membarrier operation, all registered "global" receivers will get the barrier, even if they don't share a memory mapping with the sender issuing MEMBARRIER_CMD_GLOBAL_EXPEDITED. This registration approach seems to fit the requirement of not disturbing processes that really deeply care about real-time: they simply should not register with MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED. In order to align the membarrier command names, the "MEMBARRIER_CMD_SHARED" command is renamed to "MEMBARRIER_CMD_GLOBAL", keeping an alias of MEMBARRIER_CMD_SHARED to MEMBARRIER_CMD_GLOBAL for UAPI header backward compatibility.

Mathieu Desnoyers committed 8 years ago

Commit c5f58bd1 parent 306e0604 files · +153 −18Browse files

Showing the changes to include/uapi/linux (1 of 4 files). Show all

Unified · Split

include/uapi/linux/membarrier.h+35−7
@@ -31,7 +31,7 @@ · 30 unmodified lines
3131 * enum membarrier_cmd - membarrier system call command
3232 * @MEMBARRIER_CMD_QUERY: Query the set of supported commands. It returns
3333 * a bitmask of valid commands.
34− * @MEMBARRIER_CMD_SHARED: Execute a memory barrier on all running threads.
34+ * @MEMBARRIER_CMD_GLOBAL: Execute a memory barrier on all running threads.
3535 * Upon return from system call, the caller thread
3636 * is ensured that all running threads have passed
3737 * through a state where all memory accesses to
@@ -40,6 +40,28 @@ · 2 unmodified lines
4040 * (non-running threads are de facto in such a
4141 * state). This covers threads from all processes
4242 * running on the system. This command returns 0.
43+ * @MEMBARRIER_CMD_GLOBAL_EXPEDITED:
44+ * Execute a memory barrier on all running threads
45+ * of all processes which previously registered
46+ * with MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED.
47+ * Upon return from system call, the caller thread
48+ * is ensured that all running threads have passed
49+ * through a state where all memory accesses to
50+ * user-space addresses match program order between
51+ * entry to and return from the system call
52+ * (non-running threads are de facto in such a
53+ * state). This only covers threads from processes
54+ * which registered with
55+ * MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED.
56+ * This command returns 0. Given that
57+ * registration is about the intent to receive
58+ * the barriers, it is valid to invoke
59+ * MEMBARRIER_CMD_GLOBAL_EXPEDITED from a
60+ * non-registered process.
61+ * @MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED:
62+ * Register the process intent to receive
63+ * MEMBARRIER_CMD_GLOBAL_EXPEDITED memory
64+ * barriers. Always returns 0.
4365 * @MEMBARRIER_CMD_PRIVATE_EXPEDITED:
4466 * Execute a memory barrier on each running
4567 * thread belonging to the same process as the current
@@ -64,18 +86,24 @@ · 18 unmodified lines
6486 * Register the process intent to use
6587 * MEMBARRIER_CMD_PRIVATE_EXPEDITED. Always
6688 * returns 0.
89+ * @MEMBARRIER_CMD_SHARED:
90+ * Alias to MEMBARRIER_CMD_GLOBAL. Provided for
91+ * header backward compatibility.
6792 *
6893 * Command to be passed to the membarrier system call. The commands need to
6994 * be a single bit each, except for MEMBARRIER_CMD_QUERY which is assigned to
7095 * the value 0.
7196 */
7297 enum membarrier_cmd {
73− MEMBARRIER_CMD_QUERY = 0,
74− MEMBARRIER_CMD_SHARED = (1 << 0),
75− /* reserved for MEMBARRIER_CMD_SHARED_EXPEDITED (1 << 1) */
76− /* reserved for MEMBARRIER_CMD_PRIVATE (1 << 2) */
77− MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3),
78− MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
98+ MEMBARRIER_CMD_QUERY = 0,
99+ MEMBARRIER_CMD_GLOBAL = (1 << 0),
100+ MEMBARRIER_CMD_GLOBAL_EXPEDITED = (1 << 1),
101+ MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = (1 << 2),
102+ MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3),
103+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
104+
105+ /* Alias for header backward compatibility. */
106+ MEMBARRIER_CMD_SHARED = MEMBARRIER_CMD_GLOBAL,
79107 };
80108
81109 #endif /* _UAPI_LINUX_MEMBARRIER_H */