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

Commit 7d65f4a6 authored by Frederic Weisbecker's avatar Frederic Weisbecker
Browse files

irq: Consolidate do_softirq() arch overriden implementations



All arch overriden implementations of do_softirq() share the following
common code: disable irqs (to avoid races with the pending check),
check if there are softirqs pending, then execute __do_softirq() on
a specific stack.

Consolidate the common parts such that archs only worry about the
stack switch.

Acked-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@au1.ibm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paul Mackerras <paulus@au1.ibm.com>
Cc: James Hogan <james.hogan@imgtec.com>
Cc: James E.J. Bottomley <jejb@parisc-linux.org>
Cc: Helge Deller <deller@gmx.de>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Andrew Morton <akpm@linux-foundation.org>
parent ded79754
Loading
Loading
Loading
Loading
+19 −33
Original line number Diff line number Diff line
@@ -159,19 +159,12 @@ void irq_ctx_exit(int cpu)

extern asmlinkage void __do_softirq(void);

asmlinkage void do_softirq(void)
void do_softirq_own_stack(void)
{
	unsigned long flags;
	struct thread_info *curctx;
	union irq_ctx *irqctx;
	u32 *isp;

	if (in_interrupt())
		return;

	local_irq_save(flags);

	if (local_softirq_pending()) {
	curctx = current_thread_info();
	irqctx = softirq_ctx[smp_processor_id()];
	irqctx->tinfo.task = curctx->task;
@@ -190,13 +183,6 @@ asmlinkage void do_softirq(void)
		  "D1Ar5", "D0Ar6", "D0Re0", "D1Re0", "D0.4", "D1RtP",
		  "D0.5"
		);
		/*
		 * Shouldn't happen, we returned above if in_interrupt():
		 */
		WARN_ON_ONCE(softirq_count());
	}

	local_irq_restore(flags);
}
#endif

+2 −15
Original line number Diff line number Diff line
@@ -499,22 +499,9 @@ static void execute_on_irq_stack(void *func, unsigned long param1)
	*irq_stack_in_use = 1;
}

asmlinkage void do_softirq(void)
void do_softirq_own_stack(void)
{
	__u32 pending;
	unsigned long flags;

	if (in_interrupt())
		return;

	local_irq_save(flags);

	pending = local_softirq_pending();

	if (pending)
	execute_on_irq_stack(__do_softirq, 0);

	local_irq_restore(flags);
}
#endif /* CONFIG_IRQSTACKS */

+1 −16
Original line number Diff line number Diff line
@@ -593,7 +593,7 @@ void irq_ctx_init(void)
	}
}

static inline void do_softirq_onstack(void)
void do_softirq_own_stack(void)
{
	struct thread_info *curtp, *irqtp;

@@ -611,21 +611,6 @@ static inline void do_softirq_onstack(void)
		set_bits(irqtp->flags, &curtp->flags);
}

void do_softirq(void)
{
	unsigned long flags;

	if (in_interrupt())
		return;

	local_irq_save(flags);

	if (local_softirq_pending())
		do_softirq_onstack();

	local_irq_restore(flags);
}

irq_hw_number_t virq_to_hw(unsigned int virq)
{
	struct irq_data *irq_data = irq_get_irq_data(virq);
+21 −31
Original line number Diff line number Diff line
@@ -157,16 +157,10 @@ int arch_show_interrupts(struct seq_file *p, int prec)
/*
 * Switch to the asynchronous interrupt stack for softirq execution.
 */
asmlinkage void do_softirq(void)
void do_softirq_own_stack(void)
{
	unsigned long flags, old, new;
	unsigned long old, new;

	if (in_interrupt())
		return;

	local_irq_save(flags);

	if (local_softirq_pending()) {
	/* Get current stack pointer. */
	asm volatile("la %0,0(15)" : "=a" (old));
	/* Check against async. stack address range. */
@@ -175,7 +169,6 @@ asmlinkage void do_softirq(void)
		/* Need to switch to the async. stack. */
		new -= STACK_FRAME_OVERHEAD;
		((struct stack_frame *) new)->back_chain = old;

		asm volatile("   la    15,0(%0)\n"
			     "   basr  14,%2\n"
			     "   la    15,0(%1)\n"
@@ -189,9 +182,6 @@ asmlinkage void do_softirq(void)
	}
}

	local_irq_restore(flags);
}

/*
 * ext_int_hash[index] is the list head for all external interrupts that hash
 * to this index.
+21 −36
Original line number Diff line number Diff line
@@ -149,19 +149,12 @@ void irq_ctx_exit(int cpu)
	hardirq_ctx[cpu] = NULL;
}

asmlinkage void do_softirq(void)
void do_softirq_own_stack(void)
{
	unsigned long flags;
	struct thread_info *curctx;
	union irq_ctx *irqctx;
	u32 *isp;

	if (in_interrupt())
		return;

	local_irq_save(flags);

	if (local_softirq_pending()) {
	curctx = current_thread_info();
	irqctx = softirq_ctx[smp_processor_id()];
	irqctx->tinfo.task = curctx->task;
@@ -182,14 +175,6 @@ asmlinkage void do_softirq(void)
		: "memory", "r0", "r1", "r2", "r3", "r4",
		  "r5", "r6", "r7", "r8", "r9", "r15", "t", "pr"
	);

		/*
		 * Shouldn't happen, we returned above if in_interrupt():
		 */
		WARN_ON_ONCE(softirq_count());
	}

	local_irq_restore(flags);
}
#else
static inline void handle_one_irq(unsigned int irq)
Loading