Skip to content

Commit

Permalink
x86/irq/vector: Initialize matrix allocator
Browse files Browse the repository at this point in the history
Initialize the matrix allocator and add the proper accounting points to the
code.

No functional change, just preparation.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Juergen Gross <jgross@suse.com>
Tested-by: Yu Chen <yu.c.chen@intel.com>
Acked-by: Juergen Gross <jgross@suse.com>
Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Alok Kataria <akataria@vmware.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Rui Zhang <rui.zhang@intel.com>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Len Brown <lenb@kernel.org>
Link: https://lkml.kernel.org/r/20170913213155.108410660@linutronix.de
  • Loading branch information
Thomas Gleixner committed Sep 25, 2017
1 parent 9f9e3bb commit 0fa115d
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 6 deletions.
1 change: 1 addition & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ config X86
select GENERIC_FIND_FIRST_BIT
select GENERIC_IOMAP
select GENERIC_IRQ_EFFECTIVE_AFF_MASK if SMP
select GENERIC_IRQ_MATRIX_ALLOCATOR if X86_LOCAL_APIC
select GENERIC_IRQ_MIGRATION if SMP
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
Expand Down
6 changes: 6 additions & 0 deletions arch/x86/include/asm/apic.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ static inline int apic_is_clustered_box(void)
#endif

extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask);
extern void lapic_assign_system_vectors(void);
extern void lapic_assign_legacy_vector(unsigned int isairq, bool replace);
extern void lapic_online(void);
extern void lapic_offline(void);

#else /* !CONFIG_X86_LOCAL_APIC */
static inline void lapic_shutdown(void) { }
Expand All @@ -179,6 +183,8 @@ static inline void disable_local_APIC(void) { }
# define setup_secondary_APIC_clock x86_init_noop
static inline void lapic_update_tsc_freq(void) { }
static inline void apic_intr_mode_init(void) { }
static inline void lapic_assign_system_vectors(void) { }
static inline void lapic_assign_legacy_vector(unsigned int i, bool r) { }
#endif /* !CONFIG_X86_LOCAL_APIC */

#ifdef CONFIG_X86_X2APIC
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/include/asm/hw_irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

#include <asm/irq_vectors.h>

#define IRQ_MATRIX_BITS NR_VECTORS

#ifndef __ASSEMBLY__

#include <linux/percpu.h>
Expand Down Expand Up @@ -130,7 +132,6 @@ extern struct irq_cfg *irq_cfg(unsigned int irq);
extern struct irq_cfg *irqd_cfg(struct irq_data *irq_data);
extern void lock_vector_lock(void);
extern void unlock_vector_lock(void);
extern void setup_vector_irq(int cpu);
#ifdef CONFIG_SMP
extern void send_cleanup_vector(struct irq_cfg *);
extern void irq_complete_move(struct irq_cfg *cfg);
Expand Down
56 changes: 52 additions & 4 deletions arch/x86/kernel/apic/vector.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ EXPORT_SYMBOL_GPL(x86_vector_domain);
static DEFINE_RAW_SPINLOCK(vector_lock);
static cpumask_var_t vector_cpumask, vector_searchmask, searched_cpumask;
static struct irq_chip lapic_controller;
static struct irq_matrix *vector_matrix;
#ifdef CONFIG_SMP
static DEFINE_PER_CPU(struct hlist_head, cleanup_list);
#endif
Expand Down Expand Up @@ -404,6 +405,36 @@ int __init arch_probe_nr_irqs(void)
return legacy_pic->probe();
}

void lapic_assign_legacy_vector(unsigned int irq, bool replace)
{
/*
* Use assign system here so it wont get accounted as allocated
* and moveable in the cpu hotplug check and it prevents managed
* irq reservation from touching it.
*/
irq_matrix_assign_system(vector_matrix, ISA_IRQ_VECTOR(irq), replace);
}

void __init lapic_assign_system_vectors(void)
{
unsigned int i, vector = 0;

for_each_set_bit_from(vector, system_vectors, NR_VECTORS)
irq_matrix_assign_system(vector_matrix, vector, false);

if (nr_legacy_irqs() > 1)
lapic_assign_legacy_vector(PIC_CASCADE_IR, false);

/* System vectors are reserved, online it */
irq_matrix_online(vector_matrix);

/* Mark the preallocated legacy interrupts */
for (i = 0; i < nr_legacy_irqs(); i++) {
if (i != PIC_CASCADE_IR)
irq_matrix_assign(vector_matrix, ISA_IRQ_VECTOR(i));
}
}

int __init arch_early_irq_init(void)
{
struct fwnode_handle *fn;
Expand All @@ -423,6 +454,14 @@ int __init arch_early_irq_init(void)
BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL));
BUG_ON(!alloc_cpumask_var(&searched_cpumask, GFP_KERNEL));

/*
* Allocate the vector matrix allocator data structure and limit the
* search area.
*/
vector_matrix = irq_alloc_matrix(NR_VECTORS, FIRST_EXTERNAL_VECTOR,
FIRST_SYSTEM_VECTOR);
BUG_ON(!vector_matrix);

return arch_early_ioapic_init();
}

Expand Down Expand Up @@ -454,14 +493,16 @@ static struct irq_desc *__setup_vector_irq(int vector)
return irq_to_desc(isairq);
}

/*
* Setup the vector to irq mappings. Must be called with vector_lock held.
*/
void setup_vector_irq(int cpu)
/* Online the local APIC infrastructure and initialize the vectors */
void lapic_online(void)
{
unsigned int vector;

lockdep_assert_held(&vector_lock);

/* Online the vector matrix array for this CPU */
irq_matrix_online(vector_matrix);

/*
* The interrupt affinity logic never targets interrupts to offline
* CPUs. The exception are the legacy PIC interrupts. In general
Expand All @@ -482,6 +523,13 @@ void setup_vector_irq(int cpu)
vector_update_shutdown_irqs();
}

void lapic_offline(void)
{
lock_vector_lock();
irq_matrix_offline(vector_matrix);
unlock_vector_lock();
}

static int apic_retrigger_irq(struct irq_data *irqd)
{
struct apic_chip_data *apicd = apic_chip_data(irqd);
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/i8259.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ static void make_8259A_irq(unsigned int irq)
io_apic_irqs &= ~(1<<irq);
irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
enable_irq(irq);
lapic_assign_legacy_vector(irq, true);
}

/*
Expand Down
1 change: 1 addition & 0 deletions arch/x86/kernel/irqinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ void __init native_init_IRQ(void)
x86_init.irqs.pre_vector_init();

idt_setup_apic_and_irq_gates();
lapic_assign_system_vectors();

if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs())
setup_irq(2, &irq2);
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ static void notrace start_secondary(void *unused)
* from seeing a half valid vector space.
*/
lock_vector_lock();
setup_vector_irq(smp_processor_id());
lapic_online();
set_cpu_online(smp_processor_id(), true);
unlock_vector_lock();
cpu_set_state_online(smp_processor_id());
Expand Down Expand Up @@ -1518,6 +1518,7 @@ void cpu_disable_common(void)
remove_cpu_from_maps(cpu);
unlock_vector_lock();
fixup_irqs();
lapic_offline();
}

int native_cpu_disable(void)
Expand Down

0 comments on commit 0fa115d

Please sign in to comment.