lkml.org 
[lkml]   [2023]   [Feb]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2] rseq.2: New man page for the rseq(2) API
    Date
    Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
    ---
    man2/rseq.2 | 461 ++++++++++++++++++++++++++++++++++++++++++++++++++++
    1 file changed, 461 insertions(+)
    create mode 100644 man2/rseq.2

    diff --git a/man2/rseq.2 b/man2/rseq.2
    new file mode 100644
    index 000000000..1a7e4a893
    --- /dev/null
    +++ b/man2/rseq.2
    @@ -0,0 +1,461 @@
    +.\" Copyright 2015-2023 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
    +.\"
    +.\" SPDX-License-Identifier: Linux-man-pages-copyleft
    +.\"
    +.TH rseq 2 (date) "Linux man-pages (unreleased)"
    +.SH NAME
    +rseq \- restartable sequences system call
    +.SH LIBRARY
    +Standard C library
    +.RI ( libc ", " \-lc )
    +.SH SYNOPSIS
    +.nf
    +.PP
    +.BR "#include <linux/rseq.h>" " /* Definition of " RSEQ_* " constants */"
    +.BR "#include <sys/syscall.h>" " /* Definition of " SYS_* " constants */"
    +.B #include <unistd.h>
    +.PP
    +.BI "int syscall(SYS_rseq, struct rseq *" rseq ", uint32_t " rseq_len ,
    +.BI " int " flags ", uint32_t " sig );
    +.fi
    +.PP
    +.IR Note :
    +glibc provides no wrapper for
    +.BR rseq (),
    +necessitating the use of
    +.BR syscall (2).
    +.SH DESCRIPTION
    +The
    +.BR rseq ()
    +ABI accelerates specific user-space operations by registering a
    +per-thread data structure shared between kernel and userspace.
    +This data structure can be read from or written to by user-space to skip
    +otherwise expensive system calls.
    +.PP
    +A restartable sequence is a sequence of instructions
    +guaranteed to be executed atomically with respect to
    +other threads and signal handlers on the current CPU.
    +If its execution does not complete atomically,
    +the kernel changes the execution flow by jumping to an abort handler
    +defined by user-space for that restartable sequence.
    +.PP
    +Using restartable sequences requires to register a
    +.BR rseq ()
    +ABI per-thread data structure
    +.RI ( "struct rseq" )
    +through the
    +.BR rseq ()
    +system call.
    +Only one
    +.BR rseq ()
    +ABI can be registered per thread,
    +so user-space libraries and applications must follow a user-space ABI
    +defining how to share this resource.
    +The ABI defining how to share this resource between applications and
    +libraries is defined by the C library.
    +Allocation of the per-thread
    +.BR rseq ()
    +ABI and its registration to the kernel is handled by glibc since version
    +2.35.
    +.PP
    +The
    +.BR rseq ()
    +ABI per-thread data structure contains a
    +.I rseq_cs
    +field which points to the currently executing critical section.
    +For each thread, a single rseq critical section can run at any given
    +point.
    +Each critical section needs to be implemented in assembly.
    +.PP
    +The
    +.BR rseq ()
    +ABI accelerates user-space operations on per-cpu data by defining a
    +shared data structure ABI between each user-space thread and the kernel.
    +.PP
    +It allows user-space to perform update operations on per-cpu data
    +without requiring heavy-weight atomic operations.
    +.PP
    +The term CPU used in this documentation refers to a hardware execution
    +context.
    +For instance, each CPU number returned by
    +.BR sched_getcpu ()
    +is a CPU.
    +The current CPU means to the CPU on which the registered thread is
    +running.
    +.PP
    +Restartable sequences are atomic with respect to preemption (making it
    +atomic with respect to other threads running on the same CPU),
    +as well as signal delivery (user-space execution contexts nested over
    +the same thread).
    +They either complete atomically with respect to preemption on the
    +current CPU and signal delivery, or they are aborted.
    +.PP
    +Restartable sequences are suited for update operations on per-cpu data.
    +.PP
    +Restartable sequences can be used on data structures shared between threads
    +within a process,
    +and on data structures shared between threads across different
    +processes.
    +.PP
    +Some examples of operations that can be accelerated or improved by this ABI:
    +.IP \(bu 3
    +Memory allocator per-cpu free-lists,
    +.IP \(bu 3
    +Querying the current CPU number,
    +.IP \(bu 3
    +Incrementing per-CPU counters,
    +.IP \(bu 3
    +Modifying data protected by per-CPU spinlocks,
    +.IP \(bu 3
    +Inserting/removing elements in per-CPU linked-lists,
    +.IP \(bu 3
    +Writing/reading per-CPU ring buffers content.
    +.IP \(bu 3
    +Accurately reading performance monitoring unit counters with respect to
    +thread migration.
    +.PP
    +Restartable sequences must not perform system calls.
    +Doing so may result in termination of the process by a segmentation
    +fault.
    +.PP
    +The
    +.I rseq
    +argument is a pointer to the thread-local
    +.I struct rseq
    +to be shared between kernel and user-space.
    +.PP
    +The structure
    +.I struct rseq
    +is an extensible structure.
    +Additional feature fields can be added in future kernel versions.
    +Its layout is as follows:
    +.TP
    +.B Structure alignment
    +This structure is aligned on either 32-byte boundary,
    +or on the alignment value returned by
    +.IR getauxval ()
    +invoked with
    +.B AT_RSEQ_ALIGN
    +if the structure size differs from 32 bytes.
    +.TP
    +.B Structure size
    +This structure size needs to be at least 32 bytes.
    +It can be either 32 bytes,
    +or it needs to be large enough to hold the result of
    +.IR getauxval ()
    +invoked with
    +.BR AT_RSEQ_FEATURE_SIZE .
    +Its size is passed as parameter to the
    +.BR rseq ()
    +system call.
    +.in +4n
    +.IP
    +.EX
    +#include <linux/rseq.h>
    +
    +struct rseq {
    + __u32 cpu_id_start;
    + __u32 cpu_id;
    + union {
    + /* ... */
    + } rseq_cs;
    + __u32 flags;
    + __u32 node_id;
    + __u32 mm_cid;
    +} __attribute__((aligned(32)));
    +.EE
    +.in
    +.TP
    +.B Fields
    +.RS
    +.TP
    +.I cpu_id_start
    +Always-updated value of the CPU number on which the registered thread is
    +running.
    +Initialized by user-space to 0,
    +updated by the kernel for threads registered with
    +.BR rseq ().
    +Its value is 0 when
    +.BR rseq ()
    +is not registered.
    +Its value should always be confirmed by reading the
    +.I cpu_id
    +field before user-space performs any side-effect
    +(e.g. storing to memory).
    +.IP
    +Because it is initialized to 0,
    +this field can be loaded by user-space and
    +used to index per-cpu data structures
    +without having to check whether its value is within valid bounds.
    +.IP
    +For user-space applications executed on a kernel without
    +.BR rseq ()
    +support,
    +the cpu_id_start field stays initialized at 0.
    +It is therefore valid to use it as an offset in per-cpu data structures,
    +and only validate whether it's actually the current CPU number by
    +comparing it with the cpu_id field within the rseq critical section.
    +If the kernel does not provide
    +.BR rseq ()
    +support, that cpu_id field stays initialized at -1,
    +so the comparison always fails, as intended.
    +.IP
    +This field should only be read by the thread which registered this data
    +structure.
    +Aligned on 32-bit.
    +.IP
    +It is up to user space to implement a fall-back mechanism for scenarios where
    +.BR rseq ()
    +is not available.
    +.TP
    +.I cpu_id
    +Always-updated value of the CPU number on which the registered thread is
    +running.
    +Initialized by user-space to -1,
    +updated by the kernel for threads registered with
    +.BR rseq ().
    +.IP
    +This field should only be read by the thread which registered this data
    +structure.
    +Aligned on 32-bit.
    +.TP
    +.I rseq_cs
    +The rseq_cs field is a pointer to a
    +.IR "struct rseq_cs" .
    +Is is NULL when no rseq assembly block critical section is active for
    +the registered thread.
    +Setting it to point to a critical section descriptor
    +.RI ( "struct rseq_cs")
    +marks the beginning of the critical section.
    +.IP
    +Initialized by user-space to NULL.
    +.IP
    +Updated by user-space, which sets the address of the currently
    +active rseq_cs at the beginning of assembly instruction sequence
    +block,
    +and set to NULL by the kernel when it restarts an assembly instruction
    +sequence block,
    +as well as when the kernel detects that it is preempting or delivering a
    +signal outside of the range targeted by the rseq_cs.
    +Also needs to be set to NULL by user-space before reclaiming memory that
    +contains the targeted
    +.IR "struct rseq_cs" .
    +.IP
    +Read and set by the kernel.
    +.IP
    +This field should only be updated by the thread which registered this
    +data structure.
    +Aligned on 64-bit.
    +.TP
    +.I flags
    +Flags indicating the restart behavior for the registered thread.
    +This is mainly used for debugging purposes.
    +Can be a combination of:
    +.RS
    +.TP
    +.B RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT
    +Inhibit instruction sequence block restart on preemption for this
    +thread.
    +This flag is deprecated since Linux 6.1.
    +.TP
    +.B RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL
    +Inhibit instruction sequence block restart on signal delivery for this
    +thread.
    +This flag is deprecated since Linux 6.1.
    +.TP
    +.B RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE
    +Inhibit instruction sequence block restart on migration for this thread.
    +This flag is deprecated since Linux 6.1.
    +.RE
    +.IP
    +Initialized by user-space, used by the kernel.
    +.TP
    +.I node_id
    +Always-updated value of the current NUMA node ID.
    +.IP
    +Initialized by user-space to 0.
    +.IP
    +Updated by the kernel.
    +Read by user-space with single-copy atomicity semantics.
    +This field should only be read by the thread which registered
    +this data structure.
    +Aligned on 32-bit.
    +.TP
    +.I mm_cid
    +Contains the current thread's concurrency ID
    +(allocated uniquely within a memory map).
    +.IP
    +Updated by the kernel.
    +Read by user-space with single-copy atomicity semantics.
    +This field should only be read by the thread which registered this data
    +structure.
    +Aligned on 32-bit.
    +.IP
    +This concurrency ID is within the possible cpus range,
    +and is temporarily (and uniquely) assigned while threads are actively
    +running within a memory map.
    +If a memory map has fewer threads than cores,
    +or is limited to run on few cores concurrently through sched affinity or
    +cgroup cpusets,
    +the concurrency IDs will be values close to 0,
    +thus allowing efficient use of user-space memory for per-cpu data
    +structures.
    +.RE
    +.PP
    +The layout of
    +.I struct rseq_cs
    +version 0 is as follows:
    +.TP
    +.B Structure alignment
    +This structure is aligned on 32-byte boundary.
    +.TP
    +.B Structure size
    +This structure has a fixed size of 32 bytes.
    +.in +4n
    +.IP
    +.EX
    +#include <linux/rseq.h>
    +
    +struct rseq_cs {
    + __u32 version;
    + __u32 flags;
    + __u64 start_ip;
    + __u64 post_commit_offset;
    + __u64 abort_ip;
    +} __attribute__((aligned(32)));
    +.EE
    +.in
    +.TP
    +.B Fields
    +.RS
    +.TP
    +.I version
    +Version of this structure.
    +Should be initialized to 0.
    +.TP
    +.I flags
    +.RS
    +Flags indicating the restart behavior of this structure.
    +Can be a combination of:
    +.TP
    +.B RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT
    +Inhibit instruction sequence block restart on preemption for this
    +critical section.
    +This flag is deprecated since Linux 6.1.
    +.TP
    +.B RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL
    +Inhibit instruction sequence block restart on signal delivery for this
    +critical section.
    +This flag is deprecated since Linux 6.1.
    +.TP
    +.B RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE
    +Inhibit instruction sequence block restart on migration for this
    +critical section.
    +This flag is deprecated since Linux 6.1.
    +.RE
    +.TP
    +.I start_ip
    +Instruction pointer address of the first instruction of the sequence of
    +consecutive assembly instructions.
    +.TP
    +.I post_commit_offset
    +Offset (from start_ip address) of the address after the last instruction
    +of the sequence of consecutive assembly instructions.
    +.TP
    +.I abort_ip
    +Instruction pointer address where to move the execution flow in case of
    +abort of the sequence of consecutive assembly instructions.
    +.RE
    +.PP
    +The
    +.I rseq_len
    +argument is the size of the
    +.I struct rseq
    +to register.
    +.PP
    +The
    +.I flags
    +argument is 0 for registration, and
    +.B RSEQ_FLAG_UNREGISTER
    +for unregistration.
    +.PP
    +The
    +.I sig
    +argument is the 32-bit signature to be expected before the abort
    +handler code.
    +.PP
    +A single library per process should keep the
    +.I struct rseq
    +in a per-thread data structure.
    +The
    +.I cpu_id
    +field should be initialized to -1, and the
    +.I cpu_id_start
    +field should be initialized to a possible CPU value (typically 0).
    +.PP
    +Each thread is responsible for registering and unregistering its
    +.IR "struct rseq" .
    +No more than one
    +.I struct rseq
    +address can be registered per thread at a given time.
    +.PP
    +Reclaim of
    +.I struct rseq
    +object's memory must only be done after either an explicit rseq
    +unregistration is performed or after the thread exits.
    +.PP
    +In a typical usage scenario, the thread registering the
    +.I struct rseq
    +will be performing loads and stores from/to that structure.
    +It is however also allowed to read that structure from other threads.
    +The
    +.I struct rseq
    +field updates performed by the kernel provide relaxed atomicity
    +semantics (atomic store, without memory ordering),
    +which guarantee that other threads performing relaxed atomic reads
    +(atomic load, without memory ordering) of the cpu number fields will
    +always observe a consistent value.
    +.SH RETURN VALUE
    +A return value of 0 indicates success.
    +On error, \-1 is returned, and
    +.I errno
    +is set appropriately.
    +.SH ERRORS
    +.TP
    +.B EINVAL
    +Either
    +.I flags
    +contains an invalid value, or
    +.I rseq
    +contains an address which is not appropriately aligned, or
    +.I rseq_len
    +contains an incorrect size.
    +.TP
    +.B ENOSYS
    +The
    +.BR rseq ()
    +system call is not implemented by this kernel.
    +.TP
    +.B EFAULT
    +.I rseq
    +is an invalid address.
    +.TP
    +.B EBUSY
    +Restartable sequence is already registered for this thread.
    +.TP
    +.B EPERM
    +The
    +.I sig
    +argument on unregistration does not match the signature received
    +on registration.
    +.SH VERSIONS
    +The
    +.BR rseq ()
    +system call was added in Linux 4.18.
    +.SH STANDARDS
    +.BR rseq ()
    +is Linux-specific.
    +.SH SEE ALSO
    +.BR sched_getcpu (3) ,
    +.BR membarrier (2) ,
    +.BR getauxval (3)
    --
    2.30.2
    \
     
     \ /
      Last update: 2023-03-27 00:24    [W:4.039 / U:0.372 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site