Commit 5b98d210 authored by Björn Töpel's avatar Björn Töpel Committed by Thomas Gleixner
Browse files

genirq/matrix: Dynamic bitmap allocation



A future user of the matrix allocator, does 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: default avatarBjörn Töpel <bjorn@rivosinc.com>
Signed-off-by: default avatarAnup Patel <apatel@ventanamicro.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240222094006.1030709-11-apatel@ventanamicro.com
parent 3c46fc5b
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

#include <asm/irq_vectors.h>

#define IRQ_MATRIX_BITS		NR_VECTORS

#ifndef __ASSEMBLY__

#include <linux/percpu.h>
+17 −11
Original line number Diff line number Diff line
@@ -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;
}