Re: [PATCH 11/14] irq: add support for allocating (and affinitizing) sets of IRQs
From: Jens Axboe <axboe@kernel.dk>
Date: 2018-10-30 17:43:17
Also in:
linux-scsi, lkml
Subsystem:
pci subsystem, the rest · Maintainers:
Bjorn Helgaas, Linus Torvalds
On 10/30/18 11:34 AM, Jens Axboe wrote:
On 10/30/18 11:25 AM, Thomas Gleixner wrote:quoted
Jens, On Tue, 30 Oct 2018, Jens Axboe wrote:quoted
On 10/30/18 10:02 AM, Keith Busch wrote:quoted
pci_alloc_irq_vectors_affinity() starts at the provided max_vecs. If that doesn't work, it will iterate down to min_vecs without returning to the caller. The caller doesn't have a chance to adjust its sets between iterations when you provide a range. The 'masks' overrun problem happens if the caller provides min_vecs as a smaller value than the sum of the set (plus any reserved). If it's up to the caller to ensure that doesn't happen, then min and max must both be the same value, and that value must also be the same as the set sum + reserved vectors. The range just becomes redundant since it is already bounded by the set. Using the nvme example, it would need something like this to prevent the 'masks' overrun:OK, now I hear what you are saying. And you are right, the callers needs to provide minvec == maxvec for sets, and then have a loop around that to adjust as needed.But then we should enforce it in the core code, right?Yes, I was going to ask you if you want a followup patch for that, or an updated version of the original?
Here's an incremental, I'm going to fold this into the original unless I hear otherwise.
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index af24ed50a245..e6c6e10b9ceb 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c@@ -1036,6 +1036,13 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec, if (maxvec < minvec) return -ERANGE; + /* + * If the caller is passing in sets, we can't support a range of + * vectors. The caller needs to handle that. + */ + if (affd->nr_sets && minvec != maxvec) + return -EINVAL; + if (WARN_ON_ONCE(dev->msi_enabled)) return -EINVAL;
@@ -1087,6 +1094,13 @@ static int __pci_enable_msix_range(struct pci_dev *dev, if (maxvec < minvec) return -ERANGE; + /* + * If the caller is passing in sets, we can't support a range of + * supported vectors. The caller needs to handle that. + */ + if (affd->nr_sets && minvec != maxvec) + return -EINVAL; + if (WARN_ON_ONCE(dev->msix_enabled)) return -EINVAL;
--
Jens Axboe