提交 b35f58df 编写于 作者: J Jens Axboe 提交者: Caspar Zhang

nvme: fix handling of EINVAL on pci_alloc_irq_vectors_affinity()

to #28991349

commit db29eb059cdc571f9d75cec4a41b9884b3b8286a upstream

At least on SPARC, if MSI/MSI-X isn't supported, we get EINVAL if
we ask for more than one vector. This isn't covered by our ENOSPC
check.

If we get EINVAL, decrease our ask to just one vector, instead of
bailing out in error.

Fixes: 3b6592f70ad7 ("nvme: utilize two queue maps, one for reads and one for writes")
Reported-by: NGuenter Roeck <linux@roeck-us.net>
Tested-by: NGuenter Roeck <linux@roeck-us.net>
Signed-off-by: NJens Axboe <axboe@kernel.dk>
Signed-off-by: NXiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
Reviewed-by: NJoseph Qi <joseph.qi@linux.alibaba.com>
上级 e84fc182
...@@ -2112,15 +2112,11 @@ static int nvme_setup_irqs(struct nvme_dev *dev, int nr_io_queues) ...@@ -2112,15 +2112,11 @@ static int nvme_setup_irqs(struct nvme_dev *dev, int nr_io_queues)
affd.nr_sets = 1; affd.nr_sets = 1;
/* /*
* Need IRQs for read+write queues, and one for the admin queue. * If we got a failure and we're down to asking for just
* If we can't get more than one vector, we have to share the * 1 + 1 queues, just ask for a single vector. We'll share
* admin queue and IO queue vector. For that case, don't add * that between the single IO queue and the admin queue.
* an extra vector for the admin queue, or we'll continue
* asking for 2 and get -ENOSPC in return.
*/ */
if (result == -ENOSPC && nr_io_queues == 1) if (!(result < 0 && nr_io_queues == 1))
nr_io_queues = 1;
else
nr_io_queues = irq_sets[0] + irq_sets[1] + 1; nr_io_queues = irq_sets[0] + irq_sets[1] + 1;
result = pci_alloc_irq_vectors_affinity(pdev, nr_io_queues, result = pci_alloc_irq_vectors_affinity(pdev, nr_io_queues,
...@@ -2128,13 +2124,19 @@ static int nvme_setup_irqs(struct nvme_dev *dev, int nr_io_queues) ...@@ -2128,13 +2124,19 @@ static int nvme_setup_irqs(struct nvme_dev *dev, int nr_io_queues)
PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd); PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd);
/* /*
* Need to reduce our vec counts * Need to reduce our vec counts. If we get ENOSPC, the
* platform should support mulitple vecs, we just need
* to decrease our ask. If we get EINVAL, the platform
* likely does not. Back down to ask for just one vector.
*/ */
if (result == -ENOSPC) { if (result == -ENOSPC) {
nr_io_queues--; nr_io_queues--;
if (!nr_io_queues) if (!nr_io_queues)
return result; return result;
continue; continue;
} else if (result == -EINVAL) {
nr_io_queues = 1;
continue;
} else if (result <= 0) } else if (result <= 0)
return -EIO; return -EIO;
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册