Changeset View
Standalone View
sys/sys/membarrier.h
- This file was added.
/*- | |||||
* Copyright (c) 2021 The FreeBSD Foundation | |||||
* | |||||
* This software were developed by Konstantin Belousov <kib@FreeBSD.org> | |||||
* under sponsorship from the FreeBSD Foundation. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
*/ | |||||
#ifndef __SYS_MEMBARRIER_H__ | |||||
#define __SYS_MEMBARRIER_H__ | |||||
#include <sys/cdefs.h> | |||||
/* | |||||
* The enum membarrier_cmd values are bits. The MEMBARRIER_CMD_QUERY | |||||
* command returns a bitset indicating which commands are supported. | |||||
* Also the value of MEMBARRIER_CMD_QUERY is zero, so it is | |||||
* effectively not returned by the query. | |||||
*/ | |||||
enum membarrier_cmd { | |||||
MEMBARRIER_CMD_QUERY = 0x00000000, | |||||
MEMBARRIER_CMD_GLOBAL = 0x00000001, | |||||
MEMBARRIER_CMD_SHARED = MEMBARRIER_CMD_GLOBAL, | |||||
theraven: It's confusing reading this that each command is a separate bit, yet the `membarrier` call… | |||||
Done Inline ActionsI found it very strange that MEMBARRIER_CMDs are bitmask values but packed in enum. But I do not have strong opinion. kib: I found it very strange that MEMBARRIER_CMDs are bitmask values but packed in enum. But I do… | |||||
Done Inline ActionsPlease can you add the requested comment explaining *why* they are separate bits (i.e. so that MEMBARRIER_CMD_QUERY can return the set of supported commands as a bitfield)? theraven: Please can you add the requested comment explaining *why* they are separate bits (i.e. so that… | |||||
MEMBARRIER_CMD_GLOBAL_EXPEDITED = 0x00000002, | |||||
MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED = 0x00000004, | |||||
MEMBARRIER_CMD_PRIVATE_EXPEDITED = 0x00000008, | |||||
Done Inline ActionsSource compatibility with what? Source code that relies on restartable sequences won't work on FreeBSD. glibc does not provide a wrapper around this, so any source code that actually uses it is using the system call via syscall. theraven: Source compatibility with what? Source code that relies on restartable sequences won't work on… | |||||
Done Inline ActionsSource compatible with Linux. For instance I see a code in urcu which tests for presence of _EXPEDITED_RSEQ in _QUERY response. With this constant present in the header, the code just compiles and works without RSEQ support (well, it requires replacing __syscall with direct function call, but you should see what I mean) kib: Source compatible with Linux. For instance I see a code in urcu which tests for presence of… | |||||
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = 0x00000010, | |||||
MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE = 0x00000020, | |||||
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = 0x00000040, | |||||
/* | |||||
* RSEQ constants are defined for source compatibility but are | |||||
Done Inline ActionsThis is unused and relates to a flag that is not supported. It is confusing for consuming code if flags are defined in headers for features that the OS doesn't support. theraven: This is unused and relates to a flag that is not supported. It is confusing for consuming code… | |||||
Done Inline ActionsIt reserves the ABI values for future extensions, there is nothing unusual. I will probably look at rseq stuff after this bits are landed. kib: It reserves the ABI values for future extensions, there is nothing unusual.
I will probably… | |||||
* not yes supported, MEMBARRIER_CMD_QUERY does not return | |||||
* them in the mask. | |||||
*/ | |||||
MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ = 0x00000080, | |||||
Not Done Inline ActionsNote that until very recently this was a two-argument function on Linux. My Ubuntu 20.04 install with a 5.11 kernel has the two-argument version. I wouldn't be surprised if Linux changes the number of arguments in the future. If we want to avoid breakage then we may want to do an open-like thing here and make the libc wrapper membarrier(int, unsigned, ...) and forward to the correct kernel variant based on the second argument. theraven: Note that until very recently this was a two-argument function on Linux. My Ubuntu 20.04… | |||||
Done Inline ActionsMy instance of the manual page states that the syscall takes three args. I certainly can go with libc wrapper as you suggested, but lets postpone it. I want to do some more systematic review of consumers. I looked at urcu, which requires a patch anyway due to use of syscall, and I was not able to pace verona build system. kib: My instance of the manual page states that the syscall takes three args. I certainly can go… | |||||
MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ = 0x00000100, | |||||
}; | |||||
enum membarrier_cmd_flag { | |||||
MEMBARRIER_CMD_FLAG_CPU = 0x00000001, | |||||
}; | |||||
#ifndef _KERNEL | |||||
__BEGIN_DECLS | |||||
int membarrier(int, unsigned, int); | |||||
__END_DECLS | |||||
#endif /* _KERNEL */ | |||||
#endif /* __SYS_MEMBARRIER_H__ */ |
It's confusing reading this that each command is a separate bit, yet the membarrier call requires that you provide a single one. Please can you add a comment that this is because MEMBARRIER_CMD_QUERY returns a bitmask of all supported commands.
I was going to ask if we can be better than Linux here and provide an enum so that these are somewhat type-safe, but I note that the Linux headers actually do define these as an enum, rather than as macros. Please can we do the same?