Skip to content

Commit 2f75d9e

Browse files
committed
genirq: Implement bitmap matrix allocator
Implement the infrastructure for a simple bitmap based allocator, which will replace the x86 vector allocator. It's in the core code as other architectures might be able to reuse/extend it. For now it only implements allocations for single CPUs, but it's simple to add multi CPU allocation support if required. The concept is rather simple: Global information: system_vector bitmap global accounting PerCPU information: allocation bitmap managed allocation bitmap local accounting The system vector bitmap is used to exclude vectors system wide from the allocation space. The allocation bitmap is used to keep track of per cpu used vectors. The managed allocation bitmap is used to reserve vectors for managed interrupts. When a regular (non managed) interrupt allocation happens then the following rule applies: tmpmap = system_map | alloc_map | managed_map find_zero_bit(tmpmap) Oring the bitmaps together gives the real available space. The same rule applies for reserving a managed interrupt vector. But contrary to the regular interrupts the reservation only marks the bit in the managed map and therefor excludes it from the regular allocations. The managed map is only cleaned out when the a managed interrupt is completely released and it stays alive accross CPU offline/online operations. For managed interrupt allocations the rule is: tmpmap = managed_map & ~alloc_map find_first_bit(tmpmap) This returns the first bit which is in the managed map, but not yet allocated in the allocation map. The allocation marks it in the allocation map and hands it back to the caller for use. The rest of the code are helper functions to handle the various requirements and the accounting which are necessary to replace the x86 vector allocation code. The result is a single patch as the evolution of this infrastructure cannot be represented in bits and pieces. Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Juergen Gross <[email protected]> Tested-by: Yu Chen <[email protected]> Acked-by: Juergen Gross <[email protected]> Cc: Boris Ostrovsky <[email protected]> Cc: Tony Luck <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: Alok Kataria <[email protected]> Cc: Joerg Roedel <[email protected]> Cc: "Rafael J. Wysocki" <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Paolo Bonzini <[email protected]> Cc: Rui Zhang <[email protected]> Cc: "K. Y. Srinivasan" <[email protected]> Cc: Arjan van de Ven <[email protected]> Cc: Dan Williams <[email protected]> Cc: Chris Metcalf <[email protected]> Cc: Len Brown <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 22d0b12 commit 2f75d9e

File tree

4 files changed

+454
-0
lines changed

4 files changed

+454
-0
lines changed

include/linux/irq.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,28 @@ static inline u32 irq_reg_readl(struct irq_chip_generic *gc,
11131113
return readl(gc->reg_base + reg_offset);
11141114
}
11151115

1116+
struct irq_matrix;
1117+
struct irq_matrix *irq_alloc_matrix(unsigned int matrix_bits,
1118+
unsigned int alloc_start,
1119+
unsigned int alloc_end);
1120+
void irq_matrix_online(struct irq_matrix *m);
1121+
void irq_matrix_offline(struct irq_matrix *m);
1122+
void irq_matrix_assign_system(struct irq_matrix *m, unsigned int bit, bool replace);
1123+
int irq_matrix_reserve_managed(struct irq_matrix *m, const struct cpumask *msk);
1124+
void irq_matrix_remove_managed(struct irq_matrix *m, const struct cpumask *msk);
1125+
int irq_matrix_alloc_managed(struct irq_matrix *m, unsigned int cpu);
1126+
void irq_matrix_reserve(struct irq_matrix *m);
1127+
void irq_matrix_remove_reserved(struct irq_matrix *m);
1128+
int irq_matrix_alloc(struct irq_matrix *m, const struct cpumask *msk,
1129+
bool reserved, unsigned int *mapped_cpu);
1130+
void irq_matrix_free(struct irq_matrix *m, unsigned int cpu,
1131+
unsigned int bit, bool managed);
1132+
void irq_matrix_assign(struct irq_matrix *m, unsigned int bit);
1133+
unsigned int irq_matrix_available(struct irq_matrix *m, bool cpudown);
1134+
unsigned int irq_matrix_allocated(struct irq_matrix *m);
1135+
unsigned int irq_matrix_reserved(struct irq_matrix *m);
1136+
void irq_matrix_debug_show(struct seq_file *sf, struct irq_matrix *m, int ind);
1137+
11161138
/* Contrary to Linux irqs, for hardware irqs the irq number 0 is valid */
11171139
#define INVALID_HWIRQ (~0UL)
11181140
irq_hw_number_t ipi_get_hwirq(unsigned int irq, unsigned int cpu);

kernel/irq/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ config HANDLE_DOMAIN_IRQ
9797
config IRQ_TIMINGS
9898
bool
9999

100+
config GENERIC_IRQ_MATRIX_ALLOCATOR
101+
bool
102+
100103
config IRQ_DOMAIN_DEBUG
101104
bool "Expose hardware/virtual IRQ mapping via debugfs"
102105
depends on IRQ_DOMAIN && DEBUG_FS

kernel/irq/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ obj-$(CONFIG_GENERIC_MSI_IRQ) += msi.o
1313
obj-$(CONFIG_GENERIC_IRQ_IPI) += ipi.o
1414
obj-$(CONFIG_SMP) += affinity.o
1515
obj-$(CONFIG_GENERIC_IRQ_DEBUGFS) += debugfs.o
16+
obj-$(CONFIG_GENERIC_IRQ_MATRIX_ALLOCATOR) += matrix.o

0 commit comments

Comments
 (0)