From: Sohil Mehta <sohil.mehta@intel.com>
To: x86@kernel.org
Cc: Sohil Mehta <sohil.mehta@intel.com>,
Tony Luck <tony.luck@intel.com>,
Dave Hansen <dave.hansen@intel.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
"H . Peter Anvin" <hpa@zytor.com>,
Andy Lutomirski <luto@kernel.org>, Jens Axboe <axboe@kernel.dk>,
Christian Brauner <christian@brauner.io>,
Peter Zijlstra <peterz@infradead.org>,
Shuah Khan <shuah@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Jonathan Corbet <corbet@lwn.net>, Ashok Raj <ashok.raj@intel.com>,
Jacob Pan <jacob.jun.pan@linux.intel.com>,
Gayatri Kammela <gayatri.kammela@intel.com>,
Zeng Guang <guang.zeng@intel.com>,
Dan Williams <dan.j.williams@intel.com>,
Randy E Witt <randy.e.witt@intel.com>,
Ravi V Shankar <ravi.v.shankar@intel.com>,
Ramesh Thomas <ramesh.thomas@intel.com>,
linux-api@vger.kernel.org, linux-arch@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org
Subject: [RFC PATCH 01/13] x86/uintr/man-page: Include man pages draft for reference
Date: Mon, 13 Sep 2021 13:01:20 -0700 [thread overview]
Message-ID: <20210913200132.3396598-2-sohil.mehta@intel.com> (raw)
In-Reply-To: <20210913200132.3396598-1-sohil.mehta@intel.com>
Included here in plain text format for reference and review.
<Will eventually send the man pages in groff format separately to the
man-pages repository.>
The formatting for the man pages still needs a little bit of work.
Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
---
tools/uintr/manpages/0_overview.txt | 265 ++++++++++++++++++
tools/uintr/manpages/1_register_receiver.txt | 122 ++++++++
.../uintr/manpages/2_unregister_receiver.txt | 62 ++++
tools/uintr/manpages/3_create_fd.txt | 104 +++++++
tools/uintr/manpages/4_register_sender.txt | 121 ++++++++
tools/uintr/manpages/5_unregister_sender.txt | 79 ++++++
tools/uintr/manpages/6_wait.txt | 59 ++++
7 files changed, 812 insertions(+)
create mode 100644 tools/uintr/manpages/0_overview.txt
create mode 100644 tools/uintr/manpages/1_register_receiver.txt
create mode 100644 tools/uintr/manpages/2_unregister_receiver.txt
create mode 100644 tools/uintr/manpages/3_create_fd.txt
create mode 100644 tools/uintr/manpages/4_register_sender.txt
create mode 100644 tools/uintr/manpages/5_unregister_sender.txt
create mode 100644 tools/uintr/manpages/6_wait.txt
diff --git a/tools/uintr/manpages/0_overview.txt b/tools/uintr/manpages/0_overview.txt
new file mode 100644
index 000000000000..349538effb15
--- /dev/null
+++ b/tools/uintr/manpages/0_overview.txt
@@ -0,0 +1,265 @@
+UINTR(7) Miscellaneous Information Manual UINTR(7)
+
+
+
+NAME
+ Uintr - overview of User Interrupts
+
+DESCRIPTION
+ User Interrupts (Uintr) provides a low latency event delivery and inter
+ process communication mechanism. These events can be delivered directly
+ to userspace without a transition to the kernel.
+
+ In the User Interrupts hardware architecture, a receiver is always
+ expected to be a user space task. However, a user interrupt can be sent
+ by another user space task, kernel or an external source (like a
+ device). The feature that allows another userspace task to send an
+ interrupt is referred to as User IPI.
+
+ Uintr is a hardware dependent, opt-in feature. Application aren't
+ expected or able to send or receive interrupts unless they register
+ themselves with the kernel using the syscall interface described below.
+ It is recommended that applications wanting to use User Interrupts call
+ uintr_register_handler(2) and test whether the call succeeds.
+
+ Hardware support for User interrupts may be detected using other
+ mechanisms but they could be misleading and are generally not needed:
+ - Using the cpuid instruction (Refer the Intel Software Developers
+ Manual).
+ - Checking for the "uintr" string in /proc/cpuinfo under the "flags"
+ field.
+
+
+ Applications wanting to use Uintr should also be able to function
+ without it as well. Uintr support might be unavailable because of any
+ one of the following reasons:
+ - the kernel code does not contain support
+ - the kernel support has been disabled
+ - the hardware does not support it
+
+
+ Uintr syscall interface
+ Applications can use and manage Uintr using the system calls described
+ here. The Uintr system calls are available only if the kernel is
+ configured with the CONFIG_X86_USER_INTERRUPTS option.
+
+ 1) A user application registers an interrupt handler using
+ uintr_register_handler(2). The registered interrupt handler will be
+ invoked when a user interrupt is delivered to that thread. Only one
+ interrupt handler can be registered by a particular thread within a
+ process.
+
+ 2) Each thread that registered a handler has its own unique vector
+ space of 64 vectors. The thread can then use uintr_create_fd(2) to
+ register a vector and create a user interrupt file descriptor -
+ uintr_fd.
+
+ 3) The uintr_fd is only associated with only one Uintr vector. A new
+ uintr_fd must be created for each of the 64 vectors. uintr_fd is
+ automatically inherited by forked processes but the receiver can also
+ share the uintr_fd with potential senders using any of the existing FD
+ sharing mechanisms (like pidfd_getfd(2) or socket sendmsg(2)). Access
+ to uintr_fd allows a sender to generate an interrupt with the
+ associated vector. Upon interrupt delivery, the interrupt handler is
+ invoked with the vector number pushed onto the stack to identify the
+ source of the interrupt.
+
+ 4) Each thread has a local flag called User Interrupt flag (UIF). The
+ thread can set or clear this flag to enable or disable interrupts. The
+ default value of UIF is always 0 (Interrupts disabled). A receiver must
+ execute the _stui() intrinsic instruction at some point (before or
+ anytime after registration) to start receiving user interrupts. To
+ disable interrupts during critical sections the thread can call the
+ _clui() instruction to clear UIF.
+
+ 5a) For sending a user IPI, the sender task registers with the kernel
+ using uintr_register_sender(2). The kernel would setup the routing
+ tables to connect the sender and receiver. The syscall returns an index
+ that can be used with the 'SENDUIPI <index>' instruction to send a user
+ IPI. If the receiver is running, the interrupt is delivered directly
+ to the receiver without any kernel intervention.
+
+ 5b) If the sender is the kernel or an external source, the uintr_fd can
+ be passed onto the related kernel entity to allow them to connect and
+ generate the user interrupt. <The exact details of this API are still
+ being worked upon.>
+
+ 6) The receiver can block in the kernel while it is waiting for user
+ interrupts to get delivered using uintr_wait(2). If the receiver has
+ been context switched out due to other reasons the user interrupt will
+ be delivered when the receiver gets scheduled back in.
+
+ <The behavior when the receiver has made some other blocking system
+ call like sleep(2) or read(2) is still to be decided. We are evaluating
+ if a thread made another blocking syscall should be interrupted and
+ woken up when a user interrupt arrives for that thread. uintr_wait(2)
+ has been implemented as a placeholder in the meantime.>
+
+ 7) The sender and receiver are expected to coordinate and then call the
+ teardown syscalls to terminate the connection:
+ a. A sender unregisters with uintr_unregister_sender(2)
+ b. A vector is unregistered using close(uintr_fd)
+ c. A receiver unregisters with uintr_unregister_handler(2)
+
+ If the sender and receiver aren't able to coordinate, some shared
+ kernel resources between them would get freed later when the file
+ descriptors get released automatically on process exit.
+
+
+ Multi-threaded applications need to be careful when using Uintr since
+ it is a thread specific feature. Actions by one thread don't reflect on
+ other threads of the same application.
+
+
+ Toolchain support
+ Support has added to GCC(11.1) and Binutils(2.36.1) to enable user
+ interrupt intrinsic instructions and compiler flag (-muintr).
+
+ The "(interrupt)" attribute can be used to compile a function as a user
+ interrupt handler. In conjunction with the 'muintr' flag, the compiler
+ would:
+ - Generate the entry and exit sequences for the User interrupt
+ handler
+ - Handle the saving and restoring of registers
+ - Call uiret to return from a user interrupt handler
+
+ User Interrupts related compiler intrinsic instructions -
+ <x86gprintrin.h>:
+
+ _clui() - Disable user interrupts - clear UIF (User Interrupt Flag).
+
+ _stui() - enable user interrupts - set UIF.
+
+ _testui() - test current value of UIF.
+
+ _uiret() - return from a user interrupt handler.
+
+ _senduipi <uipi_index> - send a user IPI to a target task. The
+ uipi_index is obtained using uintr_register_sender(2).
+
+
+ Interrupt handler restrictions
+ There are restrictions on what can be done in a user interrupt handler.
+
+ For example, the handler and the functions called from the handler
+ should only use general purpose registers.
+
+ For details refer the Uintr compiler programming guide.
+ https://github.com/intel/uintr-compiler-guide/blob/uintr-
+ gcc-11.1/UINTR-compiler-guide.pdf
+
+
+CONFORMING TO
+ Uintr related system calls are Linux specific.
+
+EXAMPLES
+ Build
+ To compile this sample an updated toolchain is needed.
+ - Use GCC release 11 or higher &
+ - Use Binutils release 2.36 or higher
+
+ gcc -muintr -mgeneral-regs-only -minline-all-stringops uipi_sample.c -lpthread -o uipi_sample
+
+
+ Run
+ $./uipi_sample
+ Receiver enabled interrupts
+ Sending IPI from sender thread
+ -- User Interrupt handler --
+ Success
+
+
+ Program source
+ #define _GNU_SOURCE
+ #include <pthread.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <syscall.h>
+ #include <unistd.h>
+ #include <x86gprintrin.h>
+
+ #define __NR_uintr_register_handler 449
+ #define __NR_uintr_unregister_handler 450
+ #define __NR_uintr_create_fd 451
+ #define __NR_uintr_register_sender 452
+ #define __NR_uintr_unregister_sender 453
+
+ #define uintr_register_handler(handler, flags) syscall(__NR_uintr_register_handler, handler, flags)
+ #define uintr_unregister_handler(flags) syscall(__NR_uintr_unregister_handler, flags)
+ #define uintr_create_fd(vector, flags) syscall(__NR_uintr_create_fd, vector, flags)
+ #define uintr_register_sender(fd, flags) syscall(__NR_uintr_register_sender, fd, flags)
+ #define uintr_unregister_sender(fd, flags) syscall(__NR_uintr_unregister_sender, fd, flags)
+
+ unsigned int uintr_received;
+ unsigned int uintr_fd;
+
+ void __attribute__ ((interrupt)) uintr_handler(struct __uintr_frame *ui_frame,
+ unsigned long long vector)
+ {
+ static const char print[] = "\t-- User Interrupt handler --\n";
+
+ write(STDOUT_FILENO, print, sizeof(print) - 1);
+ uintr_received = 1;
+ }
+
+ void *sender_thread(void *arg)
+ {
+ int uipi_index;
+
+ uipi_index = uintr_register_sender(uintr_fd, 0);
+ if (uipi_index < 0) {
+ printf("Sender register error\n");
+ exit(EXIT_FAILURE);
+ }
+
+ printf("Sending IPI from sender thread\n");
+ _senduipi(uipi_index);
+
+ uintr_unregister_sender(uintr_fd, 0);
+
+ return NULL;
+ }
+
+ int main(int argc, char *argv[])
+ {
+ pthread_t pt;
+
+ if (uintr_register_handler(uintr_handler, 0)) {
+ printf("Interrupt handler register error\n");
+ exit(EXIT_FAILURE);
+ }
+
+ uintr_fd = uintr_create_fd(0, 0);
+ if (uintr_fd < 0) {
+ printf("Interrupt vector registration error\n");
+ exit(EXIT_FAILURE);
+ }
+
+ _stui();
+ printf("Receiver enabled interrupts\n");
+
+ if (pthread_create(&pt, NULL, &sender_thread, NULL)) {
+ printf("Error creating sender thread\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* Do some other work */
+ while (!uintr_received)
+ usleep(1);
+
+ pthread_join(pt, NULL);
+ close(uintr_fd);
+ uintr_unregister_handler(0);
+
+ printf("Success\n");
+ exit(EXIT_SUCCESS);
+ }
+
+
+NOTES
+ Currently, there is no glibc wrapper for the Uintr related system call;
+ call the system calls using syscall(2).
+
+
+
+ UINTR(7)
diff --git a/tools/uintr/manpages/1_register_receiver.txt b/tools/uintr/manpages/1_register_receiver.txt
new file mode 100644
index 000000000000..4b6652c94faa
--- /dev/null
+++ b/tools/uintr/manpages/1_register_receiver.txt
@@ -0,0 +1,122 @@
+uintr_register_handler(2) System Calls Manual uintr_register_handler(2)
+
+
+
+NAME
+ uintr_register_handler - register a user interrupt handler
+
+
+SYNOPSIS
+ int uintr_register_handler(u64 handler_address, unsigned int flags);
+
+
+DESCRIPTION
+ uintr_register_handler() registers a user interrupt handler for the
+ calling process. In case of multi-threaded processes the user interrupt
+ handler is only registered for the thread that makes this system call.
+
+ The handler_address is the function that would be invoked when the
+ process receives a user interrupt. The function should be defined as
+ below:
+
+ void __attribute__ ((interrupt)) ui_handler(struct __uintr_frame *frame,
+ unsigned long long vector)
+
+ For more details and an example for the handler definition refer
+ uintr(7).
+
+ Providing an invalid handler_address could lead to undefined behavior
+ for the process.
+
+ The flags argument is reserved for future use. Currently, it must be
+ specified as 0.
+
+ Each user thread can register only one interrupt handler. Each thread
+ that would like to be a receiver must register once. The registration
+ is not inherited across forks(2) or when additional threads are created
+ within the same process.
+
+ Each thread within a process gets its own interrupt vector space for 64
+ vectors. The vector number is pushed onto the stack when a user
+ interrupt is delivered. Since the vector space is per-thread, each
+ receiver can receive up to 64 unique interrupt events.
+
+ For information on creating uintr_fd to register and manage interrupt
+ vectors, refer uintr_create_fd(2) system call.
+
+ Once an interrupt handler is registered it cannot be changed before the
+ handler is unregistered via uintr_unregister_handler(2). Calling
+ uintr_unregister_handler(2) would however invalidate the current
+ interrupt resources registered with the kernel.
+
+ The interrupt handler gets invoked only while the process is running.
+ If the process is scheduled out or blocked in the kernel, interrupts
+ will be delivered when the process is scheduled again. <A mechanism to
+ unblock a process as soon as a user interrupt is posted is being worked
+ upon.>
+
+
+ Interrupt handler restrictions
+ There are restrictions on what can be done in a user interrupt handler.
+
+ For example, the handler and the functions called from the handler
+ should only use general purpose registers.
+
+ For details refer the Uintr compiler programming guide.
+ https://github.com/intel/uintr-compiler-guide/blob/uintr-
+ gcc-11.1/UINTR-compiler-guide.pdf
+
+
+ Security implications
+ A lot of security issues that are applicable to signal handlers, also
+ apply to user interrupt handlers.
+
+ The user interrupt handler by-itself need not be re-entrant since
+ interrupts are automatically disabled when the handler is invoked. But
+ this isn't valid if the handler is shared between multiple threads or
+ nested interrupts have been enabled.
+
+ Similar to signal handlers, the functions that are called from a user
+ interrupt should be async-signal-safe. Refer signal-safety(7) for a
+ discussion of async-signal-safe functions.
+
+ It is recommended to disable interrupts using _clui() instruction
+ before executing any privileged code. Doing so would prevent a user
+ interrupt handler from running at a higher privilege level.
+
+
+RETURN VALUE
+ On success, uintr_register_handler() returns 0. On error, -1 is
+ returned and errno is set to indicate the cause of the error.
+
+
+ERRORS
+ EOPNOTSUPP Underlying hardware doesn't have support for Uintr.
+
+ EINVAL flags is not 0.
+
+ EFAULT handler address is not valid.
+
+ ENOMEM The system is out of available memory.
+
+ EBUSY An interrupt handler has already been registered.
+
+
+VERSIONS
+ uintr_register_handler() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+ uintr_register_handler() is Linux specific.
+
+
+NOTES
+ Currently, there is no glibc wrapper for this system call; call it
+ using syscall(2).
+
+ The user interrupt related system calls need hardware support to
+ generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+ uintr_register_handler(2)
diff --git a/tools/uintr/manpages/2_unregister_receiver.txt b/tools/uintr/manpages/2_unregister_receiver.txt
new file mode 100644
index 000000000000..dd6981f33597
--- /dev/null
+++ b/tools/uintr/manpages/2_unregister_receiver.txt
@@ -0,0 +1,62 @@
+uintr_unregister_handler(2) System Calls Manual uintr_unregister_handler(2)
+
+
+
+NAME
+ uintr_unregister_handler - unregister a user interrupt handler
+
+
+SYNOPSIS
+ int uintr_unregister_handler(unsigned int flags);
+
+
+DESCRIPTION
+ uintr_unregister_handler() unregisters a previously registered user
+ interrupt handler. If no interrupt handler was registered by the
+ process uintr_unregister_handler() would return an error.
+
+ Since interrupt handler is local to a thread, only the thread that has
+ registered via uintr_register_handler(2) can call
+ uintr_unregister_handler().
+
+ The interrupt resources such as interrupt vectors and uintr_fd, that
+ have been allocated for this thread, would be deactivated. Other
+ senders posting interrupts to this thread will not be delivered.
+
+ The kernel does not automatically close the uintr_fds related to this
+ process/thread when uintr_unregister_handler() is called. The
+ application is expected to close the unused uintr_fds before or the
+ after the handler has been unregistered.
+
+
+RETURN VALUE
+ On success, uintr_unregister_handler() returns 0. On error, -1 is
+ returned and errno is set to indicate the cause of the error.
+
+
+ERRORS
+ EOPNOTSUPP Underlying hardware doesn't have support for Uintr.
+
+ EINVAL flags is not 0.
+
+ EINVAL No registered user interrupt handler.
+
+
+VERSIONS
+ uintr_unregister_handler() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+ uintr_unregister_handler() is Linux specific.
+
+
+NOTES
+ Currently, there is no glibc wrapper for this system call; call it
+ using syscall(2).
+
+ The user interrupt related system calls need hardware support to
+ generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+ uintr_unregister_handler(2)
diff --git a/tools/uintr/manpages/3_create_fd.txt b/tools/uintr/manpages/3_create_fd.txt
new file mode 100644
index 000000000000..e90b0dce2703
--- /dev/null
+++ b/tools/uintr/manpages/3_create_fd.txt
@@ -0,0 +1,104 @@
+uintr_create_fd(2) System Calls Manual uintr_create_fd(2)
+
+
+
+NAME
+ uintr_create_fd - Create a user interrupt file descriptor - uintr_fd
+
+
+SYNOPSIS
+ int uintr_create_fd(u64 vector, unsigned int flags);
+
+
+DESCRIPTION
+ uintr_create_fd() allocates a new user interrupt file descriptor
+ (uintr_fd) based on the vector registered by the calling process. The
+ uintr_fd can be shared with other processes and the kernel to allow
+ them to generate interrupts with the associated vector.
+
+ The caller must have registered a handler via uintr_register_handler(2)
+ before attempting to create uintr_fd. The interrupts generated based on
+ this uintr_fd will be delivered only to the thread that created this
+ file descriptor. A unique uintr_fd is generated for each vector
+ registered using uintr_create_fd().
+
+ Each thread has a private vector space of 64 vectors ranging from 0-63.
+ Vector number 63 has the highest priority while vector number 0 has the
+ lowest. If two or more interrupts are pending to be delivered then the
+ interrupt with the higher vector number will be delivered first
+ followed by the ones with lower vector numbers. Applications can choose
+ appropriate vector numbers to prioritize certain interrupts over
+ others.
+
+ Upon interrupt delivery, the handler is invoked with the vector number
+ pushed onto the stack to help identify the source of the interrupt.
+ Since the vector space is per-thread, each receiver can receive up to
+ 64 unique interrupt events.
+
+ A receiver can choose to share the same uintr_fd with multiple senders.
+ Since an interrupt with the same vector number would be delivered, the
+ receiver would need to use other mechanisms to identify the exact
+ source of the interrupt.
+
+ The flags argument is reserved for future use. Currently, it must be
+ specified as 0.
+
+ close(2)
+ When the file descriptor is no longer required it should be
+ closed. When all file descriptors associated with the same
+ uintr_fd object have been closed, the resources for object are
+ freed by the kernel.
+
+ fork(2)
+ A copy of the file descriptor created by uintr_create_fd() is
+ inherited by the child produced by fork(2). The duplicate file
+ descriptor is associated with the same uintr_fd object. The
+ close-on-exec flag (FD_CLOEXEC; see fcntl(2)) is set on the
+ file descriptor returned by uintr_create_fd().
+
+ For information on how to generate interrupts with uintr_fd refer
+ uintr_register_sender(2).
+
+
+RETURN VALUE
+ On success, uintr_create_fd() returns a new uintr_fd file descriptor.
+ On error, -1 is returned and errno is set to indicate the cause of the
+ error.
+
+
+ERRORS
+ EOPNOTSUPP Underlying hardware doesn't have support for Uintr.
+
+ EINVAL flags is not 0.
+
+ EFAULT handler address is not valid.
+
+ EMFILE The per-process limit on the number of open file
+ descriptors has been reached.
+
+ ENFILE The system-wide limit on the total number of open files
+ has been reached.
+
+ ENODEV Could not mount (internal) anonymous inode device.
+
+ ENOMEM The system is out of available memory to allocate uintr_fd.
+
+
+VERSIONS
+ uintr_create_fd() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+ uintr_create_fd() is Linux specific.
+
+
+NOTES
+ Currently, there is no glibc wrapper for this system call; call it
+ using syscall(2).
+
+ The user interrupt related system calls need hardware support to
+ generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+ uintr_create_fd(2)
diff --git a/tools/uintr/manpages/4_register_sender.txt b/tools/uintr/manpages/4_register_sender.txt
new file mode 100644
index 000000000000..1dc17f4c041f
--- /dev/null
+++ b/tools/uintr/manpages/4_register_sender.txt
@@ -0,0 +1,121 @@
+uintr_register_sender(2) System Calls Manual uintr_register_sender(2)
+
+
+
+NAME
+ uintr_register_sender - Register a user inter-process interrupt sender
+
+
+SYNOPSIS
+ int uintr_register_sender(int uintr_fd, unsigned int flags);
+
+
+DESCRIPTION
+ uintr_register_sender() allows a sender process to connect with a Uintr
+ receiver based on the uintr_fd. It returns a user IPI index
+ (uipi_index) that the sender process can use in conjunction with the
+ SENDUIPI instruction to generate a user IPI.
+
+ When a sender executes 'SENDUIPI <uipi_index>', a user IPI can be
+ delivered by the hardware to the receiver without any intervention from
+ the kernel. Upon IPI delivery, the handler is invoked with the vector
+ number, associated with uintr_fd, pushed onto the stack to help
+ identify the source of the interrupt.
+
+ If the receiver for the thread is running the hardware would directly
+ deliver the user IPI to the receiver. If the receiver is not running or
+ has disabled receiving interrupts using the STUI instruction, the
+ interrupt will be stored in memory and delivered when the receiver is
+ able to receive it.
+
+ If the sender tries to send multiple IPIs while the receiver is not
+ able to receive them then all the IPIs with the same vector would be
+ coalesced. Only a single IPI per vector would be delivered.
+
+ uintr_register_sender() can be used to connect with multiple uintr_fds.
+ uintr_register_sender() would return a unique uipi_index for each
+ uintr_fd the sender connects with.
+
+ In case of a multi-threaded process, the uipi_index is only valid for
+ the thread that registered itself. Other threads would need to register
+ themselves if they intend to be a user IPI sender. Executing SENDUIPI
+ on different threads can have varying results based on the connections
+ that have been setup.
+
+ <We are also considering an alternate approach where the same
+ uipi_index would be valid for all threads that are part of the same
+ process. All threads would see consistent SENDUIPI behaviour in that
+ case.>
+
+ If a process uses SENDUIPI without registering using
+ uintr_register_sender() it receives a SIGILL signal. If a process uses
+ an illegal uipi_index, it receives a SIGSEGV signal. See sigaction(2)
+ for details of the information available with that signal.
+
+ The flags argument is reserved for future use. Currently, it must be
+ specified as 0.
+
+ close(2)
+ When the file descriptor is no longer required it should be
+ closed. When all file descriptors associated with the same
+ uintr_fd object have been closed, the resources for object are
+ freed by the kernel. Freeing the uintr_fd object would also
+ result in the associated uipi_index to be freed.
+
+ fork(2)
+ A copy of uintr_fd is inherited by the child produced by
+ fork(2). However the uipi_index would not get inherited by the
+ child. If the child wants to send a user IPI it would have to
+ explicitly register itself using the uintr_register_sender()
+ system call.
+
+ For information on how to unregister a sender refer
+ uintr_unregister_sender(2).
+
+
+RETURN VALUE
+ On success, uintr_register_sender() returns a new user IPI index -
+ uipi_index. On error, -1 is returned and errno is set to indicate the
+ cause of the error.
+
+
+ERRORS
+ EOPNOTSUPP Underlying hardware doesn't have support for uintr(7).
+
+ EOPNOTSUPP uintr_fd does not refer to a Uintr instance.
+
+ EBADF The uintr_fd passed to the kernel is invalid.
+
+ EINVAL flags is not 0.
+
+ EISCONN A connection to this uintr_fd has already been established.
+
+ ECONNRESET The user interrupt receiver has disabled the connection.
+
+ ESHUTDOWN The user interrupt receiver has exited the connection.
+
+ ENOSPC No uipi_index can be allocated. The system has run out of
+ the available user IPI indexes.
+
+ ENOMEM The system is out of available memory to register a user
+ IPI sender.
+
+
+VERSIONS
+ uintr_register_sender() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+ uintr_register_sender() is Linux specific.
+
+
+NOTES
+ Currently, there is no glibc wrapper for this system call; call it
+ using syscall(2).
+
+ The user interrupt related system calls need hardware support to
+ generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+ uintr_register_sender(2)
diff --git a/tools/uintr/manpages/5_unregister_sender.txt b/tools/uintr/manpages/5_unregister_sender.txt
new file mode 100644
index 000000000000..31a8c574dc25
--- /dev/null
+++ b/tools/uintr/manpages/5_unregister_sender.txt
@@ -0,0 +1,79 @@
+uintr_unregister_sender(2) System Calls Manual uintr_unregister_sender(2)
+
+
+
+NAME
+ uintr_unregister_sender - Unregister a user inter-process interrupt
+ sender
+
+
+SYNOPSIS
+ int uintr_unregister_sender(int uintr_fd, unsigned int flags);
+
+
+DESCRIPTION
+ uintr_unregister_sender() unregisters a sender process from a uintr_fd
+ it had previously connected with. If no connection is present with this
+ uintr_fd the system call return an error.
+
+ The uipi_index that was allocated during uintr_register_sender(2) will
+ also be freed. If a process tries to use a uipi_index after it has been
+ freed it would receive a SIGSEGV signal.
+
+ In case of a multi-threaded process uintr_unregister_sender() will only
+ disconnect the thread that makes this call. Other threads can continue
+ to use their connection with the uintr_fd based on their uipi_index.
+
+ <We are considering an alternate approach where all threads in a
+ process see a consistent view of the uipi_index. In that case,
+ uintr_unregister_sender() would disconnect all threads from uintr_fd.>
+
+ The flags argument is reserved for future use. Currently, it must be
+ specified as 0.
+
+ close(2)
+ When the file descriptor is no longer required it should be
+ closed. When all file descriptors associated with the same
+ uintr_fd object have been closed, the resources for object are
+ freed by the kernel. Freeing the uintr_fd object would also
+ result in the associated uipi_index to be freed.
+
+ The behavior of uintr_unregister_sender() system call after uintr_fd
+ has been close is undefined.
+
+
+RETURN VALUE
+ On success, uintr_unregister_sender() returns 0. On error, -1 is
+ returned and errno is set to indicate the cause of the error.
+
+
+ERRORS
+ EOPNOTSUPP Underlying hardware doesn't have support for uintr(7).
+
+ EOPNOTSUPP uintr_fd does not refer to a Uintr instance.
+
+ EBADF The uintr_fd passed to the kernel is invalid.
+
+ EINVAL flags is not 0.
+
+ EINVAL No connection has been setup with this uintr_fd.
+
+
+VERSIONS
+ uintr_unregister_sender() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+ uintr_unregister_sender() is Linux specific.
+
+
+NOTES
+ Currently, there is no glibc wrapper for this system call; call it
+ using syscall(2).
+
+ The user interrupt related system calls need hardware support to
+ generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+ uintr_unregister_sender(2)
diff --git a/tools/uintr/manpages/6_wait.txt b/tools/uintr/manpages/6_wait.txt
new file mode 100644
index 000000000000..f281a6ce83aa
--- /dev/null
+++ b/tools/uintr/manpages/6_wait.txt
@@ -0,0 +1,59 @@
+uintr_wait(2) System Calls Manual uintr_wait(2)
+
+
+
+NAME
+ uintr_wait - wait for user interrupts
+
+
+SYNOPSIS
+ int uintr_wait(unsigned int flags);
+
+
+DESCRIPTION
+ uintr_wait() causes the calling process (or thread) to sleep until a
+ user interrupt is delivered.
+
+ uintr_wait() will block in the kernel only when a interrupt handler has
+ been registered using uintr_register_handler(2)
+
+ <uintr_wait() is a placeholder syscall while we decide on the behaviour
+ of blocking system calls like sleep(2) and read(2) being interrupted by
+ uintr(7).>
+
+
+RETURN VALUE
+ uintr_wait() returns only when a user interrupt is received and the
+ interrupt handler function returned. In this case, -1 is returned and
+ errno is set to EINTR.
+
+
+ERRORS
+ EOPNOTSUPP Underlying hardware doesn't have support for Uintr.
+
+ EOPNOTSUPP No interrupt handler registered.
+
+ EINVAL flags is not 0.
+
+ EINTR A user interrupt was received and the interrupt handler
+ returned.
+
+
+VERSIONS
+ uintr_wait() first appeared in Linux <tbd>.
+
+
+CONFORMING TO
+ uintr_wait() is Linux specific.
+
+
+NOTES
+ Currently, there is no glibc wrapper for this system call; call it
+ using syscall(2).
+
+ The user interrupt related system calls need hardware support to
+ generate and receive user interrupts. Refer uintr(7) for details.
+
+
+
+ uintr_wait(2)
--
2.33.0
next prev parent reply other threads:[~2021-09-13 20:04 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-13 20:01 [RFC PATCH 00/13] x86 User Interrupts support Sohil Mehta
2021-09-13 20:01 ` Sohil Mehta [this message]
2021-09-13 20:01 ` [RFC PATCH 02/13] Documentation/x86: Add documentation for User Interrupts Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 03/13] x86/cpu: Enumerate User Interrupts support Sohil Mehta
2021-09-23 22:24 ` Thomas Gleixner
2021-09-24 19:59 ` Sohil Mehta
2021-09-27 20:42 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 04/13] x86/fpu/xstate: Enumerate User Interrupts supervisor state Sohil Mehta
2021-09-23 22:34 ` Thomas Gleixner
2021-09-27 22:25 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 05/13] x86/irq: Reserve a user IPI notification vector Sohil Mehta
2021-09-23 23:07 ` Thomas Gleixner
2021-09-25 13:30 ` Thomas Gleixner
2021-09-26 12:39 ` Thomas Gleixner
2021-09-27 19:07 ` Sohil Mehta
2021-09-28 8:11 ` Thomas Gleixner
2021-09-27 19:26 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 06/13] x86/uintr: Introduce uintr receiver syscalls Sohil Mehta
2021-09-23 12:26 ` Greg KH
2021-09-24 0:05 ` Thomas Gleixner
2021-09-27 23:20 ` Sohil Mehta
2021-09-28 4:39 ` Greg KH
2021-09-28 16:47 ` Sohil Mehta
2021-09-23 23:52 ` Thomas Gleixner
2021-09-27 23:57 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 07/13] x86/process/64: Add uintr task context switch support Sohil Mehta
2021-09-24 0:41 ` Thomas Gleixner
2021-09-28 0:30 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 08/13] x86/process/64: Clean up uintr task fork and exit paths Sohil Mehta
2021-09-24 1:02 ` Thomas Gleixner
2021-09-28 1:23 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 09/13] x86/uintr: Introduce vector registration and uintr_fd syscall Sohil Mehta
2021-09-24 10:33 ` Thomas Gleixner
2021-09-28 20:40 ` Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 10/13] x86/uintr: Introduce user IPI sender syscalls Sohil Mehta
2021-09-23 12:28 ` Greg KH
2021-09-28 18:01 ` Sohil Mehta
2021-09-29 7:04 ` Greg KH
2021-09-29 14:27 ` Sohil Mehta
2021-09-24 10:54 ` Thomas Gleixner
2021-09-13 20:01 ` [RFC PATCH 11/13] x86/uintr: Introduce uintr_wait() syscall Sohil Mehta
2021-09-24 11:04 ` Thomas Gleixner
2021-09-25 12:08 ` Thomas Gleixner
2021-09-28 23:13 ` Sohil Mehta
2021-09-28 23:08 ` Sohil Mehta
2021-09-26 14:41 ` Thomas Gleixner
2021-09-29 1:09 ` Sohil Mehta
2021-09-29 3:30 ` Andy Lutomirski
2021-09-29 4:56 ` Sohil Mehta
2021-09-30 18:08 ` Andy Lutomirski
2021-09-30 19:29 ` Thomas Gleixner
2021-09-30 22:01 ` Andy Lutomirski
2021-10-01 0:01 ` Thomas Gleixner
2021-10-01 4:41 ` Andy Lutomirski
2021-10-01 9:56 ` Thomas Gleixner
2021-10-01 15:13 ` Andy Lutomirski
2021-10-01 18:04 ` Sohil Mehta
2021-10-01 21:29 ` Thomas Gleixner
2021-10-01 23:00 ` Sohil Mehta
2021-10-01 23:04 ` Andy Lutomirski
2021-09-13 20:01 ` [RFC PATCH 12/13] x86/uintr: Wire up the user interrupt syscalls Sohil Mehta
2021-09-13 20:01 ` [RFC PATCH 13/13] selftests/x86: Add basic tests for User IPI Sohil Mehta
2021-09-13 20:27 ` [RFC PATCH 00/13] x86 User Interrupts support Dave Hansen
2021-09-14 19:03 ` Mehta, Sohil
2021-09-23 12:19 ` Greg KH
2021-09-23 14:09 ` Greg KH
2021-09-23 14:46 ` Dave Hansen
2021-09-23 15:07 ` Greg KH
2021-09-23 23:24 ` Sohil Mehta
2021-09-23 23:09 ` Sohil Mehta
2021-09-24 0:17 ` Sohil Mehta
2021-09-23 14:39 ` Jens Axboe
2021-09-29 4:31 ` Andy Lutomirski
2021-09-30 16:30 ` Stefan Hajnoczi
2021-09-30 17:24 ` Sohil Mehta
2021-09-30 17:26 ` Andy Lutomirski
2021-10-01 16:35 ` Stefan Hajnoczi
2021-10-01 16:35 ` Stefan Hajnoczi
2021-10-01 16:41 ` Richard Henderson
2021-10-01 16:41 ` Richard Henderson
2021-09-30 16:26 ` Stefan Hajnoczi
2021-10-01 0:40 ` Sohil Mehta
2021-10-01 8:19 ` Pavel Machek
2021-11-18 22:19 ` Sohil Mehta
2021-11-16 3:49 ` Prakash Sangappa
2021-11-18 21:44 ` Sohil Mehta
2021-12-22 16:17 ` Chrisma Pakha
2022-01-07 2:08 ` Sohil Mehta
2022-01-17 1:14 ` Chrisma Pakha
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210913200132.3396598-2-sohil.mehta@intel.com \
--to=sohil.mehta@intel.com \
--cc=arnd@arndb.de \
--cc=ashok.raj@intel.com \
--cc=axboe@kernel.dk \
--cc=bp@alien8.de \
--cc=christian@brauner.io \
--cc=corbet@lwn.net \
--cc=dan.j.williams@intel.com \
--cc=dave.hansen@intel.com \
--cc=gayatri.kammela@intel.com \
--cc=guang.zeng@intel.com \
--cc=hpa@zytor.com \
--cc=jacob.jun.pan@linux.intel.com \
--cc=linux-api@vger.kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=ramesh.thomas@intel.com \
--cc=randy.e.witt@intel.com \
--cc=ravi.v.shankar@intel.com \
--cc=shuah@kernel.org \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.