1
0
mirror of https://github.com/libuv/libuv synced 2025-03-28 21:13:16 +00:00

linux: disable SQPOLL io_uring by default (#4492)

The SQPOLL io_uring instance wasn't providing consistent behaviour to
users depending on kernel versions, load shape, ... creating issues
difficult to track and fix. Don't use this ring by default but allow
enabling it by calling `uv_loop_configure()` with
`UV_LOOP_ENABLE_IO_URING_SQPOLL`.
This commit is contained in:
Santiago Gimeno 2024-08-06 22:10:13 +02:00 committed by GitHub
parent 9b3b61f606
commit e78e29c231
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 30 additions and 3 deletions

View File

@ -16,7 +16,10 @@ Starting with libuv v1.45.0, some file operations on Linux are handed off to
`io_uring <https://en.wikipedia.org/wiki/Io_uring>` when possible. Apart from
a (sometimes significant) increase in throughput there should be no change in
observable behavior. Libuv reverts to using its threadpool when the necessary
kernel features are unavailable or unsuitable.
kernel features are unavailable or unsuitable. Starting with libuv v1.49.0 this
behavior was reverted and Libuv on Linux by default will be using the threadpool
again. In order to enable io_uring the :c:type:`uv_loop_t` instance must be
configured with the :c:type:`UV_LOOP_ENABLE_IO_URING_SQPOLL` option.
.. note::
On Windows `uv_fs_*` functions use utf-8 encoding.

View File

@ -73,8 +73,13 @@ API
This option is necessary to use :c:func:`uv_metrics_idle_time`.
- UV_LOOP_ENABLE_IO_URING_SQPOLL: Enable SQPOLL io_uring instance to handle
asynchronous file system operations.
.. versionchanged:: 1.39.0 added the UV_METRICS_IDLE_TIME option.
.. versionchanged:: 1.49.0 added the UV_LOOP_ENABLE_IO_URING_SQPOLL option.
.. c:function:: int uv_loop_close(uv_loop_t* loop)
Releases all internal loop resources. Call this function only when the loop

View File

@ -260,7 +260,9 @@ typedef struct uv_metrics_s uv_metrics_t;
typedef enum {
UV_LOOP_BLOCK_SIGNAL = 0,
UV_METRICS_IDLE_TIME
UV_METRICS_IDLE_TIME,
UV_LOOP_USE_IO_URING_SQPOLL
#define UV_LOOP_USE_IO_URING_SQPOLL UV_LOOP_USE_IO_URING_SQPOLL
} uv_loop_option;
typedef enum {

View File

@ -157,7 +157,8 @@ typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t;
/* loop flags */
enum {
UV_LOOP_BLOCK_SIGPROF = 0x1,
UV_LOOP_REAP_CHILDREN = 0x2
UV_LOOP_REAP_CHILDREN = 0x2,
UV_LOOP_ENABLE_IO_URING_SQPOLL = 0x4
};
/* flags of excluding ifaddr */

View File

@ -761,6 +761,14 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou,
* initialization failed. Anything else is a valid ring file descriptor.
*/
if (iou->ringfd == -2) {
/* By default, the SQPOLL is not created. Enable only if the loop is
* configured with UV_LOOP_USE_IO_URING_SQPOLL.
*/
if ((loop->flags & UV_LOOP_ENABLE_IO_URING_SQPOLL) == 0) {
iou->ringfd = -1;
return NULL;
}
uv__iou_init(loop->backend_fd, iou, 64, UV__IORING_SETUP_SQPOLL);
if (iou->ringfd == -2)
iou->ringfd = -1; /* "failed" */

View File

@ -217,6 +217,14 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
return 0;
}
#if defined(__linux__)
if (option == UV_LOOP_USE_IO_URING_SQPOLL) {
loop->flags |= UV_LOOP_ENABLE_IO_URING_SQPOLL;
return 0;
}
#endif
if (option != UV_LOOP_BLOCK_SIGNAL)
return UV_ENOSYS;