diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2024-09-30 19:44:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-30 19:44:27 +0200 |
commit | bcc6d1c1fce27de9d6d34cc21d37f7c3e5b9d40d (patch) | |
tree | 8cf27005219e89ad7db9bf1ceb366ef6ead26e17 /src | |
parent | 675a5a53960a3535b7061acd2fd9aa96aadd1b1b (diff) | |
download | libuv-bcc6d1c1fce27de9d6d34cc21d37f7c3e5b9d40d.tar.gz libuv-bcc6d1c1fce27de9d6d34cc21d37f7c3e5b9d40d.zip |
linux: use IORING_SETUP_NO_SQARRAY when available (#4553)
Introduced in Linux 6.6, it tells the kernel to omit the sqarray from
the ring buffer.
Libuv initalizes the array once to an identity mapping and then forgets
about it, so not only does it save a little memory (ca. 1 KiB per ring)
but it also makes things more efficient kernel-side because it removes
a level of indirection.
Diffstat (limited to 'src')
-rw-r--r-- | src/unix/linux.c | 19 | ||||
-rw-r--r-- | src/uv-common.h | 1 |
2 files changed, 15 insertions, 5 deletions
diff --git a/src/unix/linux.c b/src/unix/linux.c index a5f74e89..2f726294 100644 --- a/src/unix/linux.c +++ b/src/unix/linux.c @@ -126,6 +126,7 @@ enum { UV__IORING_SETUP_SQPOLL = 2u, + UV__IORING_SETUP_NO_SQARRAY = 0x10000u, }; enum { @@ -509,10 +510,13 @@ static void uv__iou_init(int epollfd, size_t sqlen; size_t maxlen; size_t sqelen; + unsigned kernel_version; + uint32_t* sqarray; uint32_t i; char* sq; char* sqe; int ringfd; + int no_sqarray; sq = MAP_FAILED; sqe = MAP_FAILED; @@ -520,11 +524,15 @@ static void uv__iou_init(int epollfd, if (!uv__use_io_uring()) return; + kernel_version = uv__kernel_version(); + no_sqarray = + UV__IORING_SETUP_NO_SQARRAY * (kernel_version >= /* 6.6 */0x060600); + /* SQPOLL required CAP_SYS_NICE until linux v5.12 relaxed that requirement. * Mostly academic because we check for a v5.13 kernel afterwards anyway. */ memset(¶ms, 0, sizeof(params)); - params.flags = flags; + params.flags = flags | no_sqarray; if (flags & UV__IORING_SETUP_SQPOLL) params.sq_thread_idle = 10; /* milliseconds */ @@ -586,7 +594,6 @@ static void uv__iou_init(int epollfd, iou->sqhead = (uint32_t*) (sq + params.sq_off.head); iou->sqtail = (uint32_t*) (sq + params.sq_off.tail); iou->sqmask = *(uint32_t*) (sq + params.sq_off.ring_mask); - iou->sqarray = (uint32_t*) (sq + params.sq_off.array); iou->sqflags = (uint32_t*) (sq + params.sq_off.flags); iou->cqhead = (uint32_t*) (sq + params.cq_off.head); iou->cqtail = (uint32_t*) (sq + params.cq_off.tail); @@ -602,11 +609,15 @@ static void uv__iou_init(int epollfd, iou->in_flight = 0; iou->flags = 0; - if (uv__kernel_version() >= /* 5.15.0 */ 0x050F00) + if (kernel_version >= /* 5.15.0 */ 0x050F00) iou->flags |= UV__MKDIRAT_SYMLINKAT_LINKAT; + if (no_sqarray) + return; + + sqarray = (uint32_t*) (sq + params.sq_off.array); for (i = 0; i <= iou->sqmask; i++) - iou->sqarray[i] = i; /* Slot -> sqe identity mapping. */ + sqarray[i] = i; /* Slot -> sqe identity mapping. */ return; diff --git a/src/uv-common.h b/src/uv-common.h index 339e5f37..60bd0087 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -400,7 +400,6 @@ void uv__metrics_set_provider_entry_time(uv_loop_t* loop); struct uv__iou { uint32_t* sqhead; uint32_t* sqtail; - uint32_t* sqarray; uint32_t sqmask; uint32_t* sqflags; uint32_t* cqhead; |