本想记录一些 RWF_NOWAIT 相关的行为,没想到之前大部分已经写过。完全没有印象。😭
补充一些新体会。
AIO 🔗
bpftrace 🔗
前文梳理了打开 RWF_NOWAIT 后提交 AIO 有时候会碰到 EAGAIN 的情况如:
- trylock inode 失败;
- 发生了 alloc write (如果是面向文件系统);
- 有脏页;
- 设备过载。
修改了上述返回 EAGAIN 的代码,加了日志和并把调用的地方从 static inline 变成可跟踪的 wrapper 方法。重新编译内核后,得到比较奇怪的发现:虽然bpftrace -l 能列出相关 wrapper,并且能注入 probe,但是 bpftrace 却一直抓不到 wrapper 的执行(从日志看 wrapper 确实被调用了)。
AIO on Filesystem 🔗
发生 EAGAIN 时比较不容易正确判断是否能重试。libuv 是转交到线程池, 而 seastar 就直接重新丢到队列(官方只支持 xfs 文件系统)。自己开发软件, 使用 RWF_NOWAIT 需要非常小心。
libaio 🔗
在 Linux 平台,libaio 的 io_set_callback() 很有迷惑性。实际上 Linux native AIO 从来就不支持回调。
AI 🔗
调试代码的时候,对某个调试日志一直比较疑惑。也就是类似下面的生产者/消费者线程中,唤醒的时候有非常小的概率此时等待队列为空。
[ producer thread ] | [ consumer thread ]
|
io_submit() | io_getevents()
wait() | wake()
由于 wake() 的返回加了日志打印,AI 提示如果 wake() 先于 wait() 执行,可能会不断打印日志 – 间接让我知道了队列可能为空的原因。
MISC 🔗
偶然和夫人聊起高中时,学校曾经邀请来宾做过的演讲。印象中有三位:
- 一位貌似来自省内高考作文组。语文老师事先播放了一遍该嘉宾在外校做的座谈。来我校后做的发言几乎一摸一样。也算是边际成本接近零了。
- 《红岩》的作者。
- 陈钟梁, 带一点即兴,挺好。