Sheepdog块设备驱动死锁的问题
这篇讲的是一个在压测Sheepdog块设备驱动时遇到的诡异死锁问题。作者在将Sheepdog虚拟磁盘挂载为宿主机本地块设备,并运行QEMU虚拟机进行高强度IO写入后,偶尔会触发系统卡死,甚至基础命令如`ps -ef`也会被阻塞。 通过`sysrq-trigger`工具抓取进程状态,作者定位到两个关键进程:一个是Sheepdog服务进程(sheep),正卡在内核的内存回收路径`shrink_page_list`上;另一个是QEMU进程,也处于不可中断的D状态。两者形成了一个经典的资源依赖环。 死锁的根因在于内存与IO的相互等待:sheep进程因内存不足,试图回收一个内存页,而该页恰好被QEMU的页缓存占用。QEMU若要释放此页,需将其回写到作为后端存储的Sheepdog设备上。但这个回写请求又必须通过本机的Sheepdog驱动发送给已经卡住的sheep进程处理。于是,sheep等待页释放,QEMU等待sheep响应,形成了无法打破的死锁。 这个问题并非编码缺陷,而是在特定部署架构(本地驱动与存储服务同机运行)下难以避免的竞争条件。作者最终得出结论,解决之道是将存储客户端驱动与存储服务节点分离部署,避免资源回收路径上的循环依赖。