Skip to the content.

iouring NO_SQARRAY

uapi 定义:

/*
 * Removes indirection through the SQ index array.
 */
#define IORING_SETUP_NO_SQARRAY		(1U << 16)

背景:io_uring 的 SQ 是两级结构

提交队列实际上是两层:

  1. sq_array:一个 u32 数组,每个元素存的是指向 sqes 的下标
  2. sqes:真正的 struct io_uring_sqe 数组

提交时 sq.head/tail 先索引到 sq_array,再通过 sq_array[i] 的值去取真正的 SQE。 这是历史遗留设计,理论上允许用户乱序填充 sq_array 来重排提交顺序,但实际上 “没人真正用过,liburing 也没暴露它”(Pavel Begunkov 原话)。

这个 flag 做什么

设置后内核不再创建、也不再使用 sq_array,sq.head/tail 直接指向 sqes 数组, cached_sq_head & mask 就是 SQE 下标。对应代码 io_get_sqe():

static bool io_get_sqe(struct io_ring_ctx *ctx, const struct io_uring_sqe **sqe)
{
	unsigned mask = ctx->sq_entries - 1;
	unsigned head = ctx->cached_sq_head++ & mask;

	if (static_branch_unlikely(&io_key_has_sqarray.key) &&
	    (!(ctx->flags & IORING_SETUP_NO_SQARRAY))) {
		head = READ_ONCE(ctx->sq_array[head]);   // 这层间接被跳过
		...
	}
	...
}

引入 commit:2af89abda7d9 (“io_uring: add option to remove SQ indirection”),2023-08, 6.6。

To my knowledge, no one has ever seriously used it, nor liburing exposes it to users. Add IORING_SETUP_NO_SQARRAY, when set we don’t bother creating and using the sq_array and SQ heads/tails will be pointing directly into the SQ. Improves memory footprint, in term of both allocations as well as cache usage, and also should make io_get_sqe() less branchy in the end.

收益

注意点

相关

后续基于它的 IORING_SETUP_SQ_REWIND 非环形提交扩展(commit 5247c034a67f “io_uring: introduce non-circular SQ”)。

TODO

这让我想起来了 vittio 中的 split queue 和 packed queue ,不过,为什么不是一开始就设计为 NO_SQARRAY

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。