NVME: I/O QID timeout completion polled问题

  • 问题分析

在系统使用过程中,内核dmesg有nvme: I/O QID timeout,completion polled信息报出。

NVME: I/O QID timeout completion polled问题_第1张图片

先看报Warning的代码:

static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)

{

... ...

if (__nvme_poll(nvmeq, req->tag)) {

                dev_warn(dev->ctrl.device,

                         "I/O %d QID %d timeout, completion polled\n",

                         req->tag, nvmeq->qid);

                return BLK_EH_DONE;

}

... ...

}

可以看出Warning是在IO的timeout处理函数报出的,其原因是:系统在下发一个IO后长时间没有收到IO回复,此时会触发一个timeout来处理,但是timeout在处理过程中发现这个IO实际上回来了(也就是处于NVMe的nvmeq中),但是系统一直没有处理这个IO,没有处理的原因是系统漏掉了这个中断。具体步骤如下:

  1. 应用下发一个IO,此时会触发一个定时器来检测这个IO完成情况
  2. 底层设备完成了这个IO,并把结果放在nvmeq中,然后通过中断告知内核
  3. 内核把这个中断漏了,导致nvmeq中的IO完成结果不处理
  4. 定时器到期,检查到IO完成结果在nvmeq中,定时器处理函数会处理这个IO的完成结果,返回IO完成状态给内核给应用层,并报一个Warning

从上面具体步骤分析可以看出,漏中断报这个Waring不会导致IO丢失,但是会导致IO的延迟加大。

问题解决

通过构建测试环境发现在ARM64下(鲲鹏、飞腾都有测试),在调用set_irq_affinity后会有很小很小的概率miss中断,此外,通过核外的/proc/irq/smp_affinity接口也可以复现(写一个脚本不停地改中断的亲和性,再用dd写盘,就有一定的概率出现),此问题应该是ARM64 gic-v3的硬件缺陷(测试发现社区5.6内核都能复现出来),目前最新的麒麟内核修复了这一问题。

你可能感兴趣的:(NVME)