@@ -1774,34 +1774,36 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
/* Deregister the admin queue's interrupt */
free_irq(dev->entry[0].vector, dev->queues[0]);
- vecs = nr_io_queues;
+ result = pci_msix_table_size(pdev);
+ if (result < 0)
+ goto msi;
+
+ vecs = min(result, nr_io_queues);
for (i = 0; i < vecs; i++)
dev->entry[i].entry = i;
- for (;;) {
- result = pci_enable_msix(pdev, dev->entry, vecs);
- if (result <= 0)
- break;
- vecs = result;
- }
- if (result < 0) {
- vecs = nr_io_queues;
- if (vecs > 32)
- vecs = 32;
- for (;;) {
- result = pci_enable_msi_block(pdev, vecs);
- if (result == 0) {
- for (i = 0; i < vecs; i++)
- dev->entry[i].vector = i + pdev->irq;
- break;
- } else if (result < 0) {
- vecs = 1;
- break;
- }
- vecs = result;
- }
+ result = pci_enable_msix(pdev, dev->entry, vecs);
+ if (result == 0)
+ goto irq;
+
+ msi:
+ result = pci_get_msi_cap(pdev);
+ if (result < 0)
+ goto no_msi;
+
+ vecs = min(result, nr_io_queues);
+
+ result = pci_enable_msi_block(pdev, vecs);
+ if (result == 0) {
+ for (i = 0; i < vecs; i++)
+ dev->entry[i].vector = i + pdev->irq;
+ goto irq;
}
+ no_msi:
+ vecs = 1;
+
+ irq:
/*
* Should investigate if there's a performance win from allocating
* more queues than interrupt vectors; it might allow the submission
As result of recent re-design of the MSI/MSI-X interrupts enabling pattern this driver has to be updated to use the new technique to obtain a optimal number of MSI/MSI-X interrupts required. Signed-off-by: Alexander Gordeev <agordeev@redhat.com> --- drivers/block/nvme-core.c | 48 +++++++++++++++++++++++--------------------- 1 files changed, 25 insertions(+), 23 deletions(-)