Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08678b08 authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar
Browse files

generic: sparse irqs: use irq_desc() together with dyn_array, instead of irq_desc[]



add CONFIG_HAVE_SPARSE_IRQ to for use condensed array.
Get rid of irq_desc[] array assumptions.

Preallocate 32 irq_desc, and irq_desc() will try to get more.

( No change in functionality is expected anywhere, except the odd build
  failure where we missed a code site or where a crossing commit itroduces
  new irq_desc[] usage. )

v2: according to Eric, change get_irq_desc() to irq_desc()

Signed-off-by: default avatarYinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent bfea1238
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -105,3 +105,7 @@ config HAVE_CLK

config HAVE_DYN_ARRAY
	def_bool n

config HAVE_SPARSE_IRQ
	def_bool n
+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ config X86
	select HAVE_GENERIC_DMA_COHERENT if X86_32
	select HAVE_EFFICIENT_UNALIGNED_ACCESS
	select HAVE_DYN_ARRAY
	select HAVE_SPARSE_IRQ if X86_64

config ARCH_DEFCONFIG
	string
+34 −12
Original line number Diff line number Diff line
@@ -345,6 +345,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
	struct irq_pin_list *entry = irq_2_pin + irq;
	unsigned int apicid_value;
	cpumask_t tmp;
	struct irq_desc *desc;

	cpus_and(tmp, cpumask, cpu_online_map);
	if (cpus_empty(tmp))
@@ -365,7 +366,8 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
			break;
		entry = irq_2_pin + entry->next;
	}
	irq_desc[irq].affinity = cpumask;
	desc = irq_to_desc(irq);
	desc->affinity = cpumask;
	spin_unlock_irqrestore(&ioapic_lock, flags);
}

@@ -475,10 +477,12 @@ static inline void balance_irq(int cpu, int irq)
static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold)
{
	int i, j;
	struct irq_desc *desc;

	for_each_online_cpu(i) {
		for (j = 0; j < nr_irqs; j++) {
			if (!irq_desc[j].action)
			desc = irq_to_desc(j);
			if (!desc->action)
				continue;
			/* Is it a significant load ?  */
			if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i), j) <
@@ -505,6 +509,7 @@ static void do_irq_balance(void)
	unsigned long tmp_cpu_irq;
	unsigned long imbalance = 0;
	cpumask_t allowed_mask, target_cpu_mask, tmp;
	struct irq_desc *desc;

	for_each_possible_cpu(i) {
		int package_index;
@@ -515,7 +520,8 @@ static void do_irq_balance(void)
		for (j = 0; j < nr_irqs; j++) {
			unsigned long value_now, delta;
			/* Is this an active IRQ or balancing disabled ? */
			if (!irq_desc[j].action || irq_balancing_disabled(j))
			desc = irq_to_desc(j);
			if (!desc->action || irq_balancing_disabled(j))
				continue;
			if (package_index == i)
				IRQ_DELTA(package_index, j) = 0;
@@ -609,7 +615,8 @@ static void do_irq_balance(void)
	selected_irq = -1;
	for (j = 0; j < nr_irqs; j++) {
		/* Is this an active IRQ? */
		if (!irq_desc[j].action)
		desc = irq_to_desc(j);
		if (!desc->action)
			continue;
		if (imbalance <= IRQ_DELTA(max_loaded, j))
			continue;
@@ -682,10 +689,12 @@ static int balanced_irq(void *unused)
	int i;
	unsigned long prev_balance_time = jiffies;
	long time_remaining = balanced_irq_interval;
	struct irq_desc *desc;

	/* push everything to CPU 0 to give us a starting point.  */
	for (i = 0 ; i < nr_irqs ; i++) {
		irq_desc[i].pending_mask = cpumask_of_cpu(0);
		desc = irq_to_desc(i);
		desc->pending_mask = cpumask_of_cpu(0);
		set_pending_irq(i, cpumask_of_cpu(0));
	}

@@ -1254,13 +1263,16 @@ static struct irq_chip ioapic_chip;

static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
{
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
	    trigger == IOAPIC_LEVEL) {
		irq_desc[irq].status |= IRQ_LEVEL;
		desc->status |= IRQ_LEVEL;
		set_irq_chip_and_handler_name(irq, &ioapic_chip,
					 handle_fasteoi_irq, "fasteoi");
	} else {
		irq_desc[irq].status &= ~IRQ_LEVEL;
		desc->status &= ~IRQ_LEVEL;
		set_irq_chip_and_handler_name(irq, &ioapic_chip,
					 handle_edge_irq, "edge");
	}
@@ -2027,6 +2039,7 @@ static struct irq_chip ioapic_chip __read_mostly = {
static inline void init_IO_APIC_traps(void)
{
	int irq;
	struct irq_desc *desc;

	/*
	 * NOTE! The local APIC isn't very good at handling
@@ -2048,9 +2061,11 @@ static inline void init_IO_APIC_traps(void)
			 */
			if (irq < 16)
				make_8259A_irq(irq);
			else
			else {
				desc = irq_to_desc(irq);
				/* Strange. Oh, well.. */
				irq_desc[irq].chip = &no_irq_chip;
				desc->chip = &no_irq_chip;
			}
		}
	}
}
@@ -2089,7 +2104,10 @@ static struct irq_chip lapic_chip __read_mostly = {

static void lapic_register_intr(int irq, int vector)
{
	irq_desc[irq].status &= ~IRQ_LEVEL;
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	desc->status &= ~IRQ_LEVEL;
	set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
				      "edge");
	set_intr_gate(vector, interrupt[irq]);
@@ -2556,6 +2574,7 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
	unsigned int dest;
	cpumask_t tmp;
	int vector;
	struct irq_desc *desc;

	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
@@ -2575,7 +2594,8 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
	msg.address_lo |= MSI_ADDR_DEST_ID(dest);

	write_msi_msg(irq, &msg);
	irq_desc[irq].affinity = mask;
	desc = irq_to_desc(irq);
	desc->affinity = mask;
}
#endif /* CONFIG_SMP */

@@ -2649,6 +2669,7 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
{
	unsigned int dest;
	cpumask_t tmp;
	struct irq_desc *desc;

	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
@@ -2659,7 +2680,8 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
	dest = cpu_mask_to_apicid(mask);

	target_ht_irq(irq, dest);
	irq_desc[irq].affinity = mask;
	desc = irq_to_desc(irq);
	desc->affinity = mask;
}
#endif

+49 −26
Original line number Diff line number Diff line
@@ -345,6 +345,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
	unsigned long flags;
	unsigned int dest;
	cpumask_t tmp;
	struct irq_desc *desc;

	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
@@ -361,9 +362,10 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
	 */
	dest = SET_APIC_LOGICAL_ID(dest);

	desc = irq_to_desc(irq);
	spin_lock_irqsave(&ioapic_lock, flags);
	__target_IO_APIC_irq(irq, dest, cfg->vector);
	irq_desc[irq].affinity = mask;
	desc->affinity = mask;
	spin_unlock_irqrestore(&ioapic_lock, flags);
}
#endif
@@ -933,14 +935,17 @@ static struct irq_chip ir_ioapic_chip;

static void ioapic_register_intr(int irq, unsigned long trigger)
{
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	if (trigger)
		irq_desc[irq].status |= IRQ_LEVEL;
		desc->status |= IRQ_LEVEL;
	else
		irq_desc[irq].status &= ~IRQ_LEVEL;
		desc->status &= ~IRQ_LEVEL;

#ifdef CONFIG_INTR_REMAP
	if (irq_remapped(irq)) {
		irq_desc[irq].status |= IRQ_MOVE_PCNTXT;
		desc->status |= IRQ_MOVE_PCNTXT;
		if (trigger)
			set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
						      handle_fasteoi_irq,
@@ -1596,10 +1601,10 @@ static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration);
static void migrate_ioapic_irq(int irq, cpumask_t mask)
{
	struct irq_cfg *cfg = irq_cfg + irq;
	struct irq_desc *desc = irq_desc + irq;
	struct irq_desc *desc;
	cpumask_t tmp, cleanup_mask;
	struct irte irte;
	int modify_ioapic_rte = desc->status & IRQ_LEVEL;
	int modify_ioapic_rte;
	unsigned int dest;
	unsigned long flags;

@@ -1616,6 +1621,8 @@ static void migrate_ioapic_irq(int irq, cpumask_t mask)
	cpus_and(tmp, cfg->domain, mask);
	dest = cpu_mask_to_apicid(tmp);

	desc = irq_to_desc(irq);
	modify_ioapic_rte = desc->status & IRQ_LEVEL;
	if (modify_ioapic_rte) {
		spin_lock_irqsave(&ioapic_lock, flags);
		__target_IO_APIC_irq(irq, dest, cfg->vector);
@@ -1637,12 +1644,13 @@ static void migrate_ioapic_irq(int irq, cpumask_t mask)
		cfg->move_in_progress = 0;
	}

	irq_desc[irq].affinity = mask;
	desc->affinity = mask;
}

static int migrate_irq_remapped_level(int irq)
{
	int ret = -1;
	struct irq_desc *desc = irq_to_desc(irq);

	mask_IO_APIC_irq(irq);

@@ -1658,11 +1666,11 @@ static int migrate_irq_remapped_level(int irq)
	}

	/* everthing is clear. we have right of way */
	migrate_ioapic_irq(irq, irq_desc[irq].pending_mask);
	migrate_ioapic_irq(irq, desc->pending_mask);

	ret = 0;
	irq_desc[irq].status &= ~IRQ_MOVE_PENDING;
	cpus_clear(irq_desc[irq].pending_mask);
	desc->status &= ~IRQ_MOVE_PENDING;
	cpus_clear(desc->pending_mask);

unmask:
	unmask_IO_APIC_irq(irq);
@@ -1674,7 +1682,7 @@ static void ir_irq_migration(struct work_struct *work)
	int irq;

	for (irq = 0; irq < nr_irqs; irq++) {
		struct irq_desc *desc = irq_desc + irq;
		struct irq_desc *desc = irq_to_desc(irq);
		if (desc->status & IRQ_MOVE_PENDING) {
			unsigned long flags;

@@ -1686,8 +1694,7 @@ static void ir_irq_migration(struct work_struct *work)
				continue;
			}

			desc->chip->set_affinity(irq,
					         irq_desc[irq].pending_mask);
			desc->chip->set_affinity(irq, desc->pending_mask);
			spin_unlock_irqrestore(&desc->lock, flags);
		}
	}
@@ -1698,9 +1705,11 @@ static void ir_irq_migration(struct work_struct *work)
 */
static void set_ir_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
{
	if (irq_desc[irq].status & IRQ_LEVEL) {
		irq_desc[irq].status |= IRQ_MOVE_PENDING;
		irq_desc[irq].pending_mask = mask;
	struct irq_desc *desc = irq_to_desc(irq);

	if (desc->status & IRQ_LEVEL) {
		desc->status |= IRQ_MOVE_PENDING;
		desc->pending_mask = mask;
		migrate_irq_remapped_level(irq);
		return;
	}
@@ -1725,7 +1734,7 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
		if (irq >= nr_irqs)
			continue;

		desc = irq_desc + irq;
		desc = irq_to_desc(irq);
		cfg = irq_cfg + irq;
		spin_lock(&desc->lock);
		if (!cfg->move_cleanup_count)
@@ -1791,7 +1800,7 @@ static void ack_apic_level(unsigned int irq)
	irq_complete_move(irq);
#ifdef CONFIG_GENERIC_PENDING_IRQ
	/* If we are moving the irq we need to mask it */
	if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
	if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) {
		do_unmask_irq = 1;
		mask_IO_APIC_irq(irq);
	}
@@ -1868,6 +1877,7 @@ static struct irq_chip ir_ioapic_chip __read_mostly = {
static inline void init_IO_APIC_traps(void)
{
	int irq;
	struct irq_desc *desc;

	/*
	 * NOTE! The local APIC isn't very good at handling
@@ -1889,9 +1899,11 @@ static inline void init_IO_APIC_traps(void)
			 */
			if (irq < 16)
				make_8259A_irq(irq);
			else
			else {
				desc = irq_to_desc(irq);
				/* Strange. Oh, well.. */
				irq_desc[irq].chip = &no_irq_chip;
				desc->chip = &no_irq_chip;
			}
		}
	}
}
@@ -1926,7 +1938,10 @@ static struct irq_chip lapic_chip __read_mostly = {

static void lapic_register_intr(int irq)
{
	irq_desc[irq].status &= ~IRQ_LEVEL;
	struct irq_desc *desc;

	desc = irq_to_desc(irq);
	desc->status &= ~IRQ_LEVEL;
	set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
				      "edge");
}
@@ -2402,6 +2417,7 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
	struct msi_msg msg;
	unsigned int dest;
	cpumask_t tmp;
	struct irq_desc *desc;

	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
@@ -2421,7 +2437,8 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
	msg.address_lo |= MSI_ADDR_DEST_ID(dest);

	write_msi_msg(irq, &msg);
	irq_desc[irq].affinity = mask;
	desc = irq_to_desc(irq);
	desc->affinity = mask;
}

#ifdef CONFIG_INTR_REMAP
@@ -2435,6 +2452,7 @@ static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
	unsigned int dest;
	cpumask_t tmp, cleanup_mask;
	struct irte irte;
	struct irq_desc *desc;

	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
@@ -2469,7 +2487,8 @@ static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
		cfg->move_in_progress = 0;
	}

	irq_desc[irq].affinity = mask;
	desc = irq_to_desc(irq);
	desc->affinity = mask;
}
#endif
#endif /* CONFIG_SMP */
@@ -2543,7 +2562,7 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq)

#ifdef CONFIG_INTR_REMAP
	if (irq_remapped(irq)) {
		struct irq_desc *desc = irq_desc + irq;
		struct irq_desc *desc = irq_to_desc(irq);
		/*
		 * irq migration in process context
		 */
@@ -2655,6 +2674,7 @@ static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
	struct msi_msg msg;
	unsigned int dest;
	cpumask_t tmp;
	struct irq_desc *desc;

	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
@@ -2674,7 +2694,8 @@ static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
	msg.address_lo |= MSI_ADDR_DEST_ID(dest);

	dmar_msi_write(irq, &msg);
	irq_desc[irq].affinity = mask;
	desc = irq_to_desc(irq);
	desc->affinity = mask;
}
#endif /* CONFIG_SMP */

@@ -2731,6 +2752,7 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
	struct irq_cfg *cfg = irq_cfg + irq;
	unsigned int dest;
	cpumask_t tmp;
	struct irq_desc *desc;

	cpus_and(tmp, mask, cpu_online_map);
	if (cpus_empty(tmp))
@@ -2743,7 +2765,8 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
	dest = cpu_mask_to_apicid(tmp);

	target_ht_irq(irq, dest, cfg->vector);
	irq_desc[irq].affinity = mask;
	desc = irq_to_desc(irq);
	desc->affinity = mask;
}
#endif

+14 −10
Original line number Diff line number Diff line
@@ -224,7 +224,7 @@ unsigned int do_IRQ(struct pt_regs *regs)
	struct pt_regs *old_regs;
	/* high bit used in ret_from_ code */
	int overflow, irq = ~regs->orig_ax;
	struct irq_desc *desc = irq_desc + irq;
	struct irq_desc *desc = irq_to_desc(irq);

	if (unlikely((unsigned)irq >= nr_irqs)) {
		printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
@@ -273,15 +273,16 @@ int show_interrupts(struct seq_file *p, void *v)

	if (i < nr_irqs) {
		unsigned any_count = 0;
		struct irq_desc *desc = irq_to_desc(i);

		spin_lock_irqsave(&irq_desc[i].lock, flags);
		spin_lock_irqsave(&desc->lock, flags);
#ifndef CONFIG_SMP
		any_count = kstat_irqs(i);
#else
		for_each_online_cpu(j)
			any_count |= kstat_cpu(j).irqs[i];
#endif
		action = irq_desc[i].action;
		action = desc->action;
		if (!action && !any_count)
			goto skip;
		seq_printf(p, "%3d: ",i);
@@ -291,8 +292,8 @@ int show_interrupts(struct seq_file *p, void *v)
		for_each_online_cpu(j)
			seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
		seq_printf(p, " %8s", irq_desc[i].chip->name);
		seq_printf(p, "-%-8s", irq_desc[i].name);
		seq_printf(p, " %8s", desc->chip->name);
		seq_printf(p, "-%-8s", desc->name);

		if (action) {
			seq_printf(p, "  %s", action->name);
@@ -302,7 +303,7 @@ int show_interrupts(struct seq_file *p, void *v)

		seq_putc(p, '\n');
skip:
		spin_unlock_irqrestore(&irq_desc[i].lock, flags);
		spin_unlock_irqrestore(&desc->lock, flags);
	} else if (i == nr_irqs) {
		seq_printf(p, "NMI: ");
		for_each_online_cpu(j)
@@ -398,17 +399,20 @@ void fixup_irqs(cpumask_t map)

	for (irq = 0; irq < nr_irqs; irq++) {
		cpumask_t mask;
		struct irq_desc *desc;

		if (irq == 2)
			continue;

		cpus_and(mask, irq_desc[irq].affinity, map);
		desc = irq_to_desc(irq);
		cpus_and(mask, desc->affinity, map);
		if (any_online_cpu(mask) == NR_CPUS) {
			printk("Breaking affinity for irq %i\n", irq);
			mask = map;
		}
		if (irq_desc[irq].chip->set_affinity)
			irq_desc[irq].chip->set_affinity(irq, mask);
		else if (irq_desc[irq].action && !(warned++))
		if (desc->chip->set_affinity)
			desc->chip->set_affinity(irq, mask);
		else if (desc->action && !(warned++))
			printk("Cannot set affinity for irq %i\n", irq);
	}

Loading