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:
Родитель
9e66317d3c
Коммит
37946d95fc
|
@ -3660,11 +3660,11 @@ out_unlock:
|
||||||
return table;
|
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;
|
struct irq_remap_table *table;
|
||||||
|
int index, c, alignment = 1;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int index, c;
|
|
||||||
struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
|
struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
|
||||||
|
|
||||||
if (!iommu)
|
if (!iommu)
|
||||||
|
@ -3674,16 +3674,22 @@ static int alloc_irq_index(u16 devid, int count)
|
||||||
if (!table)
|
if (!table)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (align)
|
||||||
|
alignment = roundup_pow_of_two(count);
|
||||||
|
|
||||||
spin_lock_irqsave(&table->lock, flags);
|
spin_lock_irqsave(&table->lock, flags);
|
||||||
|
|
||||||
/* Scan table for free entries */
|
/* 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 < MAX_IRQS_PER_TABLE;
|
||||||
++index) {
|
index++) {
|
||||||
if (!iommu->irte_ops->is_allocated(table, index))
|
if (!iommu->irte_ops->is_allocated(table, index)) {
|
||||||
c += 1;
|
c += 1;
|
||||||
else
|
} else {
|
||||||
c = 0;
|
c = 0;
|
||||||
|
index = ALIGN(index, alignment);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (c == count) {
|
if (c == count) {
|
||||||
for (; c != 0; --c)
|
for (; c != 0; --c)
|
||||||
|
@ -4096,7 +4102,7 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq,
|
||||||
else
|
else
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
} else {
|
} else {
|
||||||
index = alloc_irq_index(devid, nr_irqs);
|
index = alloc_irq_index(devid, nr_irqs, false);
|
||||||
}
|
}
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
pr_warn("Failed to allocate IRTE\n");
|
pr_warn("Failed to allocate IRTE\n");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче