ioctl_userfaultfd(2) | System Calls Manual | ioctl_userfaultfd(2) |
ioctl_userfaultfd - создаёт файловый дескриптор для обработки страничных ошибок в пользовательском пространстве
Standard C library (libc, -lc)
#include <linux/userfaultfd.h> /* определения констант UFFD* */ #include <sys/ioctl.h>
int ioctl(int fd, int cmd, ...);
Над объектом userfaultfd (созданным вызовом userfaultfd(2)) можно выполнять различные операции ioctl(2) используя вызовы вида:
ioctl(fd, cmd, argp);
Операции ioctl(2) описаны ниже. Операции UFFDIO_API, UFFDIO_REGISTER и UFFDIO_UNREGISTER используются для настройки поведения userfaultfd. Они позволяют вызывающему выбрать какие свойства нужно включить и какие типы событий будут доставляться приложению. Остальные операции являются операциями над диапазоном. Эти операции позволяют вызывающему приложению воспринимать события страничных ошибок.
(начиная с Linux 4.3) Включить работу с userfaultfd и выполнить согласование программного интерфейса.
В аргументе argp содержится указатель на структуру uffdio_api, определённую следующим образом:
struct uffdio_api { __u64 api; /* запрашиваемая версия API (входные данные) */ __u64 features; /* запрашиваемые свойства (входные/выходные) */ __u64 ioctls; /* доступные операции ioctl() (выходные данные) */ };
В поле api задаётся версия программного интерфейса, запрашиваемого приложением.
Ядро проверяет, что поддерживает запрашиваемую версию программного интерфейса и изменять поля features и ioctls в битовой маске, представляющей все доступные свойства и общие операции ioctl(2).
Before Linux 4.11, the features field must be initialized to zero before the call to UFFDIO_API, and zero (i.e., no feature bits) is placed in the features field by the kernel upon return from ioctl(2).
Начиная с Linux 4.11 поле features можно использовать для запроса поддержки определённых свойств и явно включить свойства userfaultfd, которые по умолчанию выключены. Ядро всегда сообщает о всех доступных свойствах через поле features.
Чтобы включить свойство userfaultfd приложение должно установить соответствующий бит в поле features. Если ядро поддерживает все запрошенные свойств, то он включит их. В противном случае оно обнулит возвращаемую структуру uffdio_api и вернёт EINVAL.
Могут устанавливаться следующие биты свойств:
Возвращаемое поле ioctls можно содержать следующие биты:
This ioctl(2) operation returns 0 on success. On error, -1 is returned and errno is set to indicate the error. Possible errors include:
(Since Linux 4.3.) Register a memory address range with the userfaultfd object. The pages in the range must be "compatible". Please refer to the list of register modes below for the compatible memory backends for each mode.
В аргументе argp содержится указатель на структуру uffdio_register, определённую следующим образом:
struct uffdio_range { __u64 start; /* начало диапазона */ __u64 len; /* длина диапазона (в байтах) */ }; struct uffdio_register { struct uffdio_range range; __u64 mode; /* желаемый режим операции (входные данные) */ __u64 ioctls; /* доступные операции ioctl() (результат) */ };
В поле range задаётся диапазон памяти (начинающийся с start и длиной len байт), который должен обрабатываться userfaultfd.
В поле mode задаётся режим операции на этим диапазоном памяти. У режима userfaultfd могут быть указаны следующие значения (через операцию ИЛИ) для задаваемого диапазона:
If the operation is successful, the kernel modifies the ioctls bit-mask field to indicate which ioctl(2) operations are available for the specified range. This returned bit mask can contain the following bits:
This ioctl(2) operation returns 0 on success. On error, -1 is returned and errno is set to indicate the error. Possible errors include:
(начиная с Linux 4.3) Снять регистрацию диапазона адресов памяти в userfaultfd. Страницы в диапазоне должны быть «совместимыми» (смотрите описание UFFDIO_REGISTER).
Снимаемый с регистрации диапазон адресов задаётся в структуре uffdio_range, которая указывается в argp.
This ioctl(2) operation returns 0 on success. On error, -1 is returned and errno is set to indicate the error. Possible errors include:
(начиная с Linux 4.3) Атомарно копировать непрерывный участок памяти в зарегистрированный в userfault диапазон и разбудить заблокированную нить (не обязательно). Адреса источника и назначения и количество копируемых байт задаётся в полях src, dst и len структуры uffdio_copy, на которую указывает argp:
struct uffdio_copy { __u64 dst; /* Destination of copy */ __u64 src; /* Source of copy */ __u64 len; /* Number of bytes to copy */ __u64 mode; /* Flags controlling behavior of copy */ __s64 copy; /* Number of bytes copied, or negated error */ };
Для изменения поведения операции UFFDIO_COPY можно использовать следующие значения mode (побитовое ИЛИ):
Поле copy используется ядром для возврата количества байт, которые были скопированы, или ошибки (отрицательное значение, подобное errno). Если значение, возвращённое в copy, не совпадает со значением, указанным в len, то операция завершается ошибкой EAGAIN. Поле copy используется только для результата; оно не читается операцией UFFDIO_COPY.
This ioctl(2) operation returns 0 on success. In this case, the entire area was copied. On error, -1 is returned and errno is set to indicate the error. Possible errors include:
(начиная с Linux 4.3) Обнулить диапазон памяти, зарегистрированный в userfaultfd.
Запрашиваемый диапазон указывается в поле range структуры uffdio_zeropage, на которую указывает argp:
struct uffdio_zeropage { struct uffdio_range range; __u64 mode; /* флаги, определяющие поведение копирования */ __s64 zeropage; /* количество обнуляемых байт или отрицательная ошибка */ };
Для изменения поведения операции UFFDIO_ZEROPAGE можно использовать следующие значения mode (побитовое ИЛИ):
Поле zeropage используется ядром для возврата количества байт, которые были обнулены, или ошибки (также, как для UFFDIO_COPY). Если значение, возвращённое в zeropage, не совпадает со значением, указанным в range.len, то операция завершается ошибкой EAGAIN. Поле zeropage используется только для результата; оно не читается операцией UFFDIO_ZEROPAGE.
This ioctl(2) operation returns 0 on success. In this case, the entire area was zeroed. On error, -1 is returned and errno is set to indicate the error. Possible errors include:
(начиная с Linux 4.3) Разбудить нить, которая ждёт решения страничной ошибки в указанном диапазоне адресов памяти.
Операция UFFDIO_WAKE используется вместе с UFFDIO_COPY и UFFDIO_ZEROPAGE, у которых установлен бит UFFDIO_COPY_MODE_DONTWAKE или UFFDIO_ZEROPAGE_MODE_DONTWAKE в поле mode. При отслеживании userfault можно выполнять несколько операций UFFDIO_COPY и UFFDIO_ZEROPAGE вместе и затем явно будить нить с ошибкой с помощью UFFDIO_WAKE.
В аргументе argp содержится указатель на структуру uffdio_range (показана выше), в которой задаётся диапазон адресов.
This ioctl(2) operation returns 0 on success. On error, -1 is returned and errno is set to indicate the error. Possible errors include:
Write-protect or write-unprotect a userfaultfd-registered memory range registered with mode UFFDIO_REGISTER_MODE_WP.
The argp argument is a pointer to a uffdio_range structure as shown below:
struct uffdio_writeprotect { struct uffdio_range range; /* Range to change write permission*/ __u64 mode; /* Mode to change write permission */ };
There are two mode bits that are supported in this structure:
This ioctl(2) operation returns 0 on success. On error, -1 is returned and errno is set to indicate the error. Possible errors include:
(Since Linux 5.13.) Resolve a minor page fault by installing page table entries for existing pages in the page cache.
The argp argument is a pointer to a uffdio_continue structure as shown below:
struct uffdio_continue { struct uffdio_range range; /* Range to install PTEs for and continue */ __u64 mode; /* Flags controlling the behavior of continue */ __s64 mapped; /* Number of bytes mapped, or negated error */ };
Для изменения поведения операции UFFDIO_CONTINUE можно использовать следующие значения mode (побитовое ИЛИ):
The mapped field is used by the kernel to return the number of bytes that were actually mapped, or an error in the same manner as UFFDIO_COPY. If the value returned in the mapped field doesn't match the value that was specified in range.len, the operation fails with the error EAGAIN. The mapped field is output-only; it is not read by the UFFDIO_CONTINUE operation.
This ioctl(2) operation returns 0 on success. In this case, the entire area was mapped. On error, -1 is returned and errno is set to indicate the error. Possible errors include:
Смотрите описание приведённое выше для каждой операции.
Смотрите описание приведённое выше для каждой операции. Также для всех описанных выше операций могут возникать общие ошибки:
Данные операции ioctl(2) есть только в Linux.
Чтобы определить доступные свойства userfault и включить некоторые из них нужно закрыть файловый дескриптор userfaultfd после первой операции UFFDIO_API, которая запрашивает доступность свойств, и повторно открыть его перед второй операцией UFFDIO_API, которая теперь включит желаемый свойства.
Смотрите userfaultfd(2).
ioctl(2), mmap(2), userfaultfd(2)
Файл Documentation/admin-guide/mm/userfaultfd.rst из дерева исходного кода ядра Linux
Русский перевод этой страницы руководства был сделан Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.
15 декабря 2022 г. | Linux man-pages 6.03 |