如何保证io_uring完成队列永远不会溢出?

问题描述 投票:0回答:1

我的理解(可能是错误的)是操作可以处于 io_uring 中三种可能状态之一:

  1. 在提交队列中等待(表示为提交队列条目)
  2. In-flight(即内核已从提交队列中删除提交队列条目,但尚未完成 IO)。
  3. 已完成。

想象一个应用程序请求数百万个 IO 操作,并且有两个线程,以及一个具有 32 个提交队列条目槽的 io_uring 实例。

一个线程负责保持提交队列填满:当应用程序启动时,该线程会用 32 个条目填充提交队列。然后,当提交队列已满时,它会阻塞。一旦提交队列变得“未满”,它就会提交另一个 SQE。

另一个线程获取完成队列事件。

此应用程序可能会溢出完成队列吗?

“使用 io_uring 实现高效 IO”PDF 建议 - 是的 - 这个应用程序将溢出完成队列:

通常申请会要求提供给定尺寸的戒指,并且 假设该大小直接对应于应用程序可以在 核心。然而,由于 sqe 的生命周期只是它实际提交的生命周期,

应用程序有可能 驱动比 SQ 环大小指示的更高的待处理请求计数。应用程序必须注意不要这样做, 否则可能会导致 CQ 环溢出。缺省情况下,CQ环的大小是SQ环的2倍。这允许 在管理这方面应用了一定的灵活性,但并没有完全消除这样做的需要。如果 应用程序确实违反了此限制,它将作为 CQ 环中的溢出条件进行跟踪。

应用程序是否必须跟踪正在进行的操作数量?或者如果CQ已满,是否有更简单的方法可以暂停向SQ的提交?

linux io linux-kernel io-uring
1个回答
0
投票
我的理解是有两种可能的解决方案:

设置

IORING_SETUP_CQ_NODROP

 标志将 - 
引用 Jen Axboe:

稍微改变一下行为 对于CQ环溢出。首先,它不会溢出环,它 只是存储我们无法放入的积压完成工作 CQ环。为了防止积压无限期地增长,如果 backlog非空,我们对IO提交施加反压。任何 尝试提交具有非空积压的新 IO 将得到 -EBUSY 从内核返回。这是向应用程序发出的一个信号: 积压的 CQ 事件,并且必须在允许之前获取这些事件 提交更多 IO。

因此,调用

io_uring_enter()

 将返回 
-EBUSY

但是,如果我们使用内核线程来轮询提交队列(使用

IORING_SETUP_SQPOLL

)呢?在这种情况下,我们不会调用 
io_uring_enter()
,因此我们永远不会看到 
-EBUSY
 错误。

我认为这里的解决方案是在尝试向提交队列提交任何内容之前调用 liburing 的

io_uring_cq_has_overflow()


    

© www.soinside.com 2019 - 2024. All rights reserved.