linux: create io_uring sqpoll ring lazily (#4315)

It's been reported that creating many event loops introduces measurable
overhead now that libuv creates an sqpoll-enabled ring.

I don't really see any change in CPU time with or without this change
but deferring ring creation until it's actually used seems like a good
idea, and comes with no downsides that I can think of, so let's do it.

Fixes: https://github.com/libuv/libuv/issues/4308
This commit is contained in:
Ben Noordhuis 2024-02-14 11:20:44 +01:00 committed by GitHub
parent 7b9e37c7da
commit 507f3046d1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -622,7 +622,7 @@ fail:
static void uv__iou_delete(struct uv__iou* iou) {
if (iou->ringfd != -1) {
if (iou->ringfd > -1) {
munmap(iou->sq, iou->maxlen);
munmap(iou->sqe, iou->sqelen);
uv__close(iou->ringfd);
@ -636,7 +636,7 @@ int uv__platform_loop_init(uv_loop_t* loop) {
lfields = uv__get_internal_fields(loop);
lfields->ctl.ringfd = -1;
lfields->iou.ringfd = -1;
lfields->iou.ringfd = -2; /* "uninitialized" */
loop->inotify_watchers = NULL;
loop->inotify_fd = -1;
@ -645,7 +645,6 @@ int uv__platform_loop_init(uv_loop_t* loop) {
if (loop->backend_fd == -1)
return UV__ERR(errno);
uv__iou_init(loop->backend_fd, &lfields->iou, 64, UV__IORING_SETUP_SQPOLL);
uv__iou_init(loop->backend_fd, &lfields->ctl, 256, 0);
return 0;
@ -764,6 +763,15 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou,
uint32_t mask;
uint32_t slot;
/* Lazily create the ring. State machine: -2 means uninitialized, -1 means
* initialization failed. Anything else is a valid ring file descriptor.
*/
if (iou->ringfd == -2) {
uv__iou_init(loop->backend_fd, iou, 64, UV__IORING_SETUP_SQPOLL);
if (iou->ringfd == -2)
iou->ringfd = -1; /* "failed" */
}
if (iou->ringfd == -1)
return NULL;