RWF_NONBLOCK & EAGAIN

· 384 words · 1 minute read

通过 Linux AIO 做 non_blocking IO, 碰到一个奇怪的问题,记录一下。 I/O 面向的是 Ext4 文件系统,而不是块。

RWF_NOWAIT 🔗

RWF_NOWAIT 的语义在 io_submit(2) 里有描述,libaio 的测试用例中也包含了相关描述。大意相同,也就是 io_getevents(2)event.res 字段为 EAGAIN 的若干可能如下:

  * RWF_NOWAIT will cause -EAGAIN to be returned in the io_event for
  * any I/O that cannot be serviced without blocking the submission
  * thread.  Instances covered by the kernel at the time this test was
  * written include:
  * - O_DIRECT I/O to a file offset that has populated page cache pages
  * - the submission context cannot obtain the inode lock
  * - space allocation is necessary
  * - we need to wait for other I/O (e.g. in the misaligned I/O case)
  * - ...

神奇的 EAGAIN 🔗

加了日志,基本上排除了对应上面若干条目的场景,但是还是得到了 EAGAIN.

  • 测试应用放在 Debian 12 容器跑在 CentOS 8 上,得到 EAGAIN. 宿主机的 bpftrace 得到 -529;
  • 测试应用跑在 CentOS 8 虚拟机,不会 EAGAIN. 此时,bpftrace 也得到 -529.
  • 测试应用跑在 Debian 12 物理机,得到 EAGAIN. 此时,bpftrace 得到 -11.

神奇的 -529 🔗

-11 代表 -EAGAIN. 但是 -529 是怎么来的呢?

$ bpftrace -e 'kretprobe:generic_file_direct_write,\
    kretprobe:ext4_file_write_iter\
    {printf("%-6d %-16s: %d [%s]\n", pid, comm, retval, probe);}'
685053 aio-test        : -529 [kretprobe:generic_file_direct_write]
685053 aio-test        : -529 [kretprobe:ext4_file_write_iter]

trace-cmd 🔗

在 F 老师的帮助下,用 trace-cmd 生成了内核执行路径。待分析。

comments powered by Disqus