--- zzzz-none-000/linux-5.15.111/kernel/irq/matrix.c 2023-05-11 14:00:40.000000000 +0000 +++ puma7-atom-6670-761/linux-5.15.111/kernel/irq/matrix.c 2024-02-07 10:23:28.000000000 +0000 @@ -367,6 +367,73 @@ trace_irq_matrix_remove_reserved(m); } +#ifdef CONFIG_INTEL_PCI_MULTI_MSI +static unsigned int matrix_alloc_area_block(struct irq_matrix *m, struct cpumap *cm, + unsigned int num, bool managed) +{ + unsigned int area, start = m->alloc_start; + unsigned int end = m->alloc_end; + unsigned int align_mask = 0; + + /* Contiguous allocations must be aligned for MSI */ + align_mask = 1 << fls(num - 1); + /* Convert from align requirement to align mask */ + align_mask--; + + bitmap_or(m->scratch_map, cm->managed_map, m->system_map, end); + bitmap_or(m->scratch_map, m->scratch_map, cm->alloc_map, end); + area = bitmap_find_next_zero_area(m->scratch_map, end, start, num, align_mask); + if (area >= end) + return area; + if (managed) + bitmap_set(cm->managed_map, area, num); + else + bitmap_set(cm->alloc_map, area, num); + return area; +} + +/** + * irq_matrix_alloc_block - Allocate a regular interrupt in a CPU map + * @m: Matrix pointer + * @msk: Which CPUs to search in + * @reserved: Allocate previously reserved interrupts + * @mapped_cpu: Pointer to store the CPU for which the irq was allocated + * @num: Number of interrupts + */ +int irq_matrix_alloc_block(struct irq_matrix *m, const struct cpumask *msk, + bool reserved, unsigned int *mapped_cpu, unsigned int num) +{ + unsigned int cpu, bit; + struct cpumap *cm; + + /* + * Not required in theory, but matrix_find_best_cpu() uses + * for_each_cpu() which ignores the cpumask on UP . + */ + if (cpumask_empty(msk)) + return -EINVAL; + + cpu = matrix_find_best_cpu(m, msk); + if (cpu == UINT_MAX) + return -ENOSPC; + + cm = per_cpu_ptr(m->maps, cpu); + bit = matrix_alloc_area_block(m, cm, num, false); + if (bit >= m->alloc_end) + return -ENOSPC; + cm->allocated += num; + cm->available -= num; + m->total_allocated += num; + m->global_available -= num; + if (reserved) + m->global_reserved -= num; + *mapped_cpu = cpu; + trace_irq_matrix_alloc(bit, cpu, m, cm); + return bit; + +} +#endif /* CONFIG_INTEL_PCI_MULTI_MSI */ + /** * irq_matrix_alloc - Allocate a regular interrupt in a CPU map * @m: Matrix pointer