genirq/affinity: Handle pre/post vectors in irq_calc_affinity_vectors()

Only calculate the affinity for the main I/O vectors, and skip the pre or
post vectors specified by struct irq_affinity.

Also remove the irq_affinity cpumask argument that has never been used.  If
we ever need it in the future we can pass it through struct irq_affinity.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Acked-by: Jens Axboe <axboe@kernel.dk>
Cc: linux-block@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Link: http://lkml.kernel.org/r/1478654107-7384-3-git-send-email-hch@lst.de
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Christoph Hellwig 2016-11-08 17:15:02 -08:00 committed by Thomas Gleixner
parent 20e407e195
commit 212bd84622
3 changed files with 16 additions and 20 deletions

View File

@ -1061,6 +1061,7 @@ EXPORT_SYMBOL(pci_msi_enabled);
static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
unsigned int flags)
{
static const struct irq_affinity default_affd;
bool affinity = flags & PCI_IRQ_AFFINITY;
int nvec;
int rc;
@ -1091,8 +1092,7 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
for (;;) {
if (affinity) {
nvec = irq_calc_affinity_vectors(dev->irq_affinity,
nvec);
nvec = irq_calc_affinity_vectors(nvec, &default_affd);
if (nvec < minvec)
return -ENOSPC;
}
@ -1132,6 +1132,7 @@ static int __pci_enable_msix_range(struct pci_dev *dev,
struct msix_entry *entries, int minvec, int maxvec,
unsigned int flags)
{
static const struct irq_affinity default_affd;
bool affinity = flags & PCI_IRQ_AFFINITY;
int rc, nvec = maxvec;
@ -1140,8 +1141,7 @@ static int __pci_enable_msix_range(struct pci_dev *dev,
for (;;) {
if (affinity) {
nvec = irq_calc_affinity_vectors(dev->irq_affinity,
nvec);
nvec = irq_calc_affinity_vectors(nvec, &default_affd);
if (nvec < minvec)
return -ENOSPC;
}

View File

@ -291,7 +291,7 @@ extern int
irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify);
struct cpumask *irq_create_affinity_masks(const struct cpumask *affinity, int nvec);
int irq_calc_affinity_vectors(const struct cpumask *affinity, int maxvec);
int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd);
#else /* CONFIG_SMP */
@ -331,7 +331,7 @@ irq_create_affinity_masks(const struct cpumask *affinity, int nvec)
}
static inline int
irq_calc_affinity_vectors(const struct cpumask *affinity, int maxvec)
irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd)
{
return maxvec;
}

View File

@ -131,24 +131,20 @@ out:
}
/**
* irq_calc_affinity_vectors - Calculate to optimal number of vectors for a given affinity mask
* @affinity: The affinity mask to spread. If NULL cpu_online_mask
* is used
* @maxvec: The maximum number of vectors available
* irq_calc_affinity_vectors - Calculate the optimal number of vectors
* @maxvec: The maximum number of vectors available
* @affd: Description of the affinity requirements
*/
int irq_calc_affinity_vectors(const struct cpumask *affinity, int maxvec)
int irq_calc_affinity_vectors(int maxvec, const struct irq_affinity *affd)
{
int cpus, ret;
int resv = affd->pre_vectors + affd->post_vectors;
int vecs = maxvec - resv;
int cpus;
/* Stabilize the cpumasks */
get_online_cpus();
/* If the supplied affinity mask is NULL, use cpu online mask */
if (!affinity)
affinity = cpu_online_mask;
cpus = cpumask_weight(affinity);
ret = (cpus < maxvec) ? cpus : maxvec;
cpus = cpumask_weight(cpu_online_mask);
put_online_cpus();
return ret;
return min(cpus, vecs) + resv;
}