
RDMA完成事件处理:ibv_get_cq_event与ibv_ack_cq_events从一次诡异的丢包说起去年调一个NVMe over RDMA的存储方案,压测跑到一半,IO突然卡死。排查了两天,发现CQ事件处理线程里漏调了ibv_ack_cq_events——结果CQ的事件通道被内核堵死,后续的完成通知再也收不到。更坑的是,ibv_get_cq_event本身不报错,只是默默阻塞,你根本不知道是没事件还是事件通道挂了。这种坑,踩过一次就记住了。今天把CQ事件处理的完整链路掰开揉碎讲清楚,代码里哪些地方容易翻车,我直接标出来。CQ事件模型:别把通知和完成搞混很多新手把“CQ事件”和“WC(工作完成)”当成一回事,这是第一个认知误区。CQ事件是内核通知用户态“你的CQ里有新完成项了”,而WC是你从CQ里poll出来的具体完成记录。事件是信号,WC是数据,两者通过CQ这个对象关联。RDMA的事件机制分两层:异步事件:通过ibv_get_async_event获取,处理设备级异常(比如端口down、QP错误)。这个和CQ无关,别混用。完成事件:通过ibv_get_cq_event获取,通知你某个CQ有新的完成项可读。完成事件依赖一个叫“Completion Event Channel”的东西——本质上是一个文件描述符,内核往里面写数据,