Re: [RFC PATCH] genirq/matrix: Dynamic bitmap allocation

From: Anup Patel
Date: Thu Oct 26 2023 - 08:26:57 EST


On Thu, Oct 26, 2023 at 3:50 PM Björn Töpel <bjorn@xxxxxxxxxx> wrote:
>
> From: Björn Töpel <bjorn@xxxxxxxxxxxx>
>
> Some (future) users of the irq matrix allocator, do not know the size
> of the matrix bitmaps at compile time.
>
> To avoid wasting memory on unnecessary large bitmaps, size the bitmap
> at matrix allocation time.
>
> Signed-off-by: Björn Töpel <bjorn@xxxxxxxxxxxx>
> ---
> Here's a cleaned up, boot tested, proper patch.
>
> Thomas, this is just FYI/RFC. This change would only make sense, if
> the RISC-V AIA series starts using the IRQ matrix allocator.

I have dropped "multi-MSI" support from the AIA v12 series
and also integrated the IRQ matrix allocator. This patch is
included in the AIA v12 series.

For reference, look at riscv_aia_v12 branch at:
https://github.com/avpatel/linux.git

I still need to rebase this upon device MSI domain support
from Thomas.

Regards,
Anup


>
>
> Björn
> ---
> arch/x86/include/asm/hw_irq.h | 2 --
> kernel/irq/matrix.c | 28 +++++++++++++++++-----------
> 2 files changed, 17 insertions(+), 13 deletions(-)
>
> diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
> index 551829884734..dcfaa3812306 100644
> --- a/arch/x86/include/asm/hw_irq.h
> +++ b/arch/x86/include/asm/hw_irq.h
> @@ -16,8 +16,6 @@
>
> #include <asm/irq_vectors.h>
>
> -#define IRQ_MATRIX_BITS NR_VECTORS
> -
> #ifndef __ASSEMBLY__
>
> #include <linux/percpu.h>
> diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c
> index 1698e77645ac..996cbb46d654 100644
> --- a/kernel/irq/matrix.c
> +++ b/kernel/irq/matrix.c
> @@ -8,8 +8,6 @@
> #include <linux/cpu.h>
> #include <linux/irq.h>
>
> -#define IRQ_MATRIX_SIZE (BITS_TO_LONGS(IRQ_MATRIX_BITS))
> -
> struct cpumap {
> unsigned int available;
> unsigned int allocated;
> @@ -17,8 +15,8 @@ struct cpumap {
> unsigned int managed_allocated;
> bool initialized;
> bool online;
> - unsigned long alloc_map[IRQ_MATRIX_SIZE];
> - unsigned long managed_map[IRQ_MATRIX_SIZE];
> + unsigned long *managed_map;
> + unsigned long alloc_map[];
> };
>
> struct irq_matrix {
> @@ -32,8 +30,8 @@ struct irq_matrix {
> unsigned int total_allocated;
> unsigned int online_maps;
> struct cpumap __percpu *maps;
> - unsigned long scratch_map[IRQ_MATRIX_SIZE];
> - unsigned long system_map[IRQ_MATRIX_SIZE];
> + unsigned long *system_map;
> + unsigned long scratch_map[];
> };
>
> #define CREATE_TRACE_POINTS
> @@ -50,24 +48,32 @@ __init struct irq_matrix *irq_alloc_matrix(unsigned int matrix_bits,
> unsigned int alloc_start,
> unsigned int alloc_end)
> {
> + unsigned int cpu, matrix_size = BITS_TO_LONGS(matrix_bits);
> struct irq_matrix *m;
>
> - if (matrix_bits > IRQ_MATRIX_BITS)
> - return NULL;
> -
> - m = kzalloc(sizeof(*m), GFP_KERNEL);
> + m = kzalloc(struct_size(m, scratch_map, matrix_size * 2), GFP_KERNEL);
> if (!m)
> return NULL;
>
> + m->system_map = &m->scratch_map[matrix_size];
> +
> m->matrix_bits = matrix_bits;
> m->alloc_start = alloc_start;
> m->alloc_end = alloc_end;
> m->alloc_size = alloc_end - alloc_start;
> - m->maps = alloc_percpu(*m->maps);
> + m->maps = __alloc_percpu(struct_size(m->maps, alloc_map, matrix_size * 2),
> + __alignof__(*m->maps));
> if (!m->maps) {
> kfree(m);
> return NULL;
> }
> +
> + for_each_possible_cpu(cpu) {
> + struct cpumap *cm = per_cpu_ptr(m->maps, cpu);
> +
> + cm->managed_map = &cm->alloc_map[matrix_size];
> + }
> +
> return m;
> }
>
>
> base-commit: 611da07b89fdd53f140d7b33013f255bf0ed8f34
> --
> 2.40.1
>