mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 02:09:42 +00:00
iommu/amd: Add align parameter to alloc_irq_index()
For multi-MSI IRQ ranges the IRQ index needs to be aligned
to the power-of-two of the requested IRQ count. Extend the
alloc_irq_index() function to allow such an allocation.
Reported-by: Thomas Gleixner <tglx@linutronix.de>
Fixes: 2b32450634
('iommu/amd: Add routines to manage irq remapping tables')
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
9e66317d3c
commit
37946d95fc
1 changed files with 14 additions and 8 deletions
|
@ -3660,11 +3660,11 @@ static struct irq_remap_table *get_irq_table(u16 devid, bool ioapic)
|
|||
return table;
|
||||
}
|
||||
|
||||
static int alloc_irq_index(u16 devid, int count)
|
||||
static int alloc_irq_index(u16 devid, int count, bool align)
|
||||
{
|
||||
struct irq_remap_table *table;
|
||||
int index, c, alignment = 1;
|
||||
unsigned long flags;
|
||||
int index, c;
|
||||
struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
|
||||
|
||||
if (!iommu)
|
||||
|
@ -3674,16 +3674,22 @@ static int alloc_irq_index(u16 devid, int count)
|
|||
if (!table)
|
||||
return -ENODEV;
|
||||
|
||||
if (align)
|
||||
alignment = roundup_pow_of_two(count);
|
||||
|
||||
spin_lock_irqsave(&table->lock, flags);
|
||||
|
||||
/* Scan table for free entries */
|
||||
for (c = 0, index = table->min_index;
|
||||
for (index = ALIGN(table->min_index, alignment), c = 0;
|
||||
index < MAX_IRQS_PER_TABLE;
|
||||
++index) {
|
||||
if (!iommu->irte_ops->is_allocated(table, index))
|
||||
index++) {
|
||||
if (!iommu->irte_ops->is_allocated(table, index)) {
|
||||
c += 1;
|
||||
else
|
||||
c = 0;
|
||||
} else {
|
||||
c = 0;
|
||||
index = ALIGN(index, alignment);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c == count) {
|
||||
for (; c != 0; --c)
|
||||
|
@ -4096,7 +4102,7 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq,
|
|||
else
|
||||
ret = -ENOMEM;
|
||||
} else {
|
||||
index = alloc_irq_index(devid, nr_irqs);
|
||||
index = alloc_irq_index(devid, nr_irqs, false);
|
||||
}
|
||||
if (index < 0) {
|
||||
pr_warn("Failed to allocate IRTE\n");
|
||||
|
|
Loading…
Reference in a new issue