All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: Nicholas Piggin <npiggin@gmail.com>
Subject: [RFC PATCH 8/8] powerpc/64s: inline local_irq_enable/restore
Date: Thu, 21 Dec 2017 00:52:06 +1000	[thread overview]
Message-ID: <20171220145206.12234-9-npiggin@gmail.com> (raw)
In-Reply-To: <20171220145206.12234-1-npiggin@gmail.com>

This does increase kernel text size by about 0.4%, but code is often
improved by putting the interrupt-replay call out of line, and gcc
function "shrink wrapping" can more often avoid setting up a stack
frame, e.g., _raw_spin_unlock_irqrestore fastpath before:

	<_raw_spin_unlock_irqrestore>:
	addis   r2,r12,63
	addi    r2,r2,24688
	mflr    r0
	andi.   r9,r14,256
	mr      r9,r3
	std     r0,16(r1)
	stdu    r1,-32(r1)
	bne     c0000000009fd1e0 <_raw_spin_unlock_irqrestore+0x50>
	lwsync
	li      r10,0
	mr      r3,r4
	stw     r10,0(r9)
	bl      c000000000013f98 <arch_local_irq_restore+0x8>

		<arch_local_irq_restore>:
		addis   r2,r12,222
		addi    r2,r2,-3472
		rldimi  r14,r3,0,62
		cmpdi   cr7,r3,0
		bnelr   cr7
		andi.   r9,r14,252
		beqlr

	nop
	addi    r1,r1,32
	ld      r0,16(r1)
	mtlr    r0
	blr

And after:

	<_raw_spin_unlock_irqrestore>:
	addis   r2,r12,64
	addi    r2,r2,-15200
	andi.   r9,r14,256
	bne     c000000000a06dd0 <_raw_spin_unlock_irqrestore+0x70>
	lwsync
	li      r9,0
	stw     r9,0(r3)
	rldimi  r14,r4,0,62
	cmpdi   cr7,r4,0
	bne     cr7,c000000000a06d90 <_raw_spin_unlock_irqrestore+0x30>
	andi.   r9,r14,252
	bne     c000000000a06da0 <_raw_spin_unlock_irqrestore+0x40>
	blr

GCC can still improve code size for the slow paths by avoiding aligning
branch targets too, so there is room to reduce the text size cost there.
---
 arch/powerpc/include/asm/hw_irq.h | 15 +++++++++++++--
 arch/powerpc/kernel/irq.c         | 28 ++++++----------------------
 2 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index f492a7779ea3..8690e0d5605d 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -132,11 +132,22 @@ static inline void arch_local_irq_disable(void)
 	irq_soft_mask_set(IRQ_SOFT_MASK_STD);
 }
 
-extern void arch_local_irq_restore(unsigned long);
+extern void __arch_local_irq_enable(void);
 
 static inline void arch_local_irq_enable(void)
 {
-	arch_local_irq_restore(0);
+	__irq_soft_mask_clear(IRQ_SOFT_MASK_ALL);
+	if (unlikely(local_r14 & R14_BIT_IRQ_HAPPENED_MASK))
+		__arch_local_irq_enable();
+}
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+	__irq_soft_mask_insert(flags);
+	if (!flags) {
+		if (unlikely(local_r14 & R14_BIT_IRQ_HAPPENED_MASK))
+			__arch_local_irq_enable();
+	}
 }
 
 static inline unsigned long arch_local_irq_save(void)
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index ebaf210a7406..e2ff0210477e 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -97,11 +97,6 @@ extern int tau_interrupts(int);
 
 int distribute_irqs = 1;
 
-static inline notrace unsigned long get_irq_happened(void)
-{
-	return local_r14 & R14_BIT_IRQ_HAPPENED_MASK;
-}
-
 static inline notrace int decrementer_check_overflow(void)
 {
  	u64 now = get_tb_or_rtc();
@@ -210,19 +205,10 @@ notrace unsigned int __check_irq_replay(void)
 	return 0;
 }
 
-notrace void arch_local_irq_restore(unsigned long mask)
+notrace void __arch_local_irq_enable(void)
 {
-	unsigned char irq_happened;
 	unsigned int replay;
 
-	/* Write the new soft-enabled value */
-	__irq_soft_mask_insert(mask);
-	/* any bits still disabled */
-	if (mask)
-		return;
-
-	barrier();
-
 	/*
 	 * From this point onward, we can take interrupts, preempt,
 	 * etc... unless we got hard-disabled. We check if an event
@@ -236,9 +222,6 @@ notrace void arch_local_irq_restore(unsigned long mask)
 	 * be hard-disabled, so there is no problem, we
 	 * cannot have preempted.
 	 */
-	irq_happened = get_irq_happened();
-	if (!irq_happened)
-		return;
 
 	/*
 	 * We need to hard disable to get a trusted value from
@@ -252,10 +235,11 @@ notrace void arch_local_irq_restore(unsigned long mask)
 	 * (expensive) mtmsrd.
 	 * XXX: why not test & IRQ_HARD_DIS?
 	 */
-	if (unlikely(irq_happened != PACA_IRQ_HARD_DIS))
+	if (unlikely((local_r14 & R14_BIT_IRQ_HAPPENED_MASK) !=
+						PACA_IRQ_HARD_DIS)) {
 		__hard_irq_disable();
 #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
-	else {
+	} else {
 		/*
 		 * We should already be hard disabled here. We had bugs
 		 * where that wasn't the case so let's dbl check it and
@@ -264,8 +248,8 @@ notrace void arch_local_irq_restore(unsigned long mask)
 		 */
 		if (WARN_ON(mfmsr() & MSR_EE))
 			__hard_irq_disable();
-	}
 #endif
+	}
 
 	__irq_soft_mask_set(IRQ_SOFT_MASK_ALL);
 	trace_hardirqs_off();
@@ -293,7 +277,7 @@ notrace void arch_local_irq_restore(unsigned long mask)
 	/* Finally, let's ensure we are hard enabled */
 	__hard_irq_enable();
 }
-EXPORT_SYMBOL(arch_local_irq_restore);
+EXPORT_SYMBOL(__arch_local_irq_enable);
 
 /*
  * This is specifically called by assembly code to re-enable interrupts
-- 
2.15.0

      parent reply	other threads:[~2017-12-20 14:52 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-20 14:51 [RFC PATCH 0/8] use r14 for a per-cpu kernel register Nicholas Piggin
2017-12-20 14:51 ` [RFC PATCH 1/8] powerpc/64s: stop using r14 register Nicholas Piggin
2017-12-20 14:52 ` [RFC PATCH 2/8] powerpc/64s: poison r14 register while in kernel Nicholas Piggin
2017-12-20 14:52 ` [RFC PATCH 3/8] powerpc/64s: put the per-cpu data_offset in r14 Nicholas Piggin
2017-12-20 17:53   ` Gabriel Paubert
2017-12-22 13:50     ` Nicholas Piggin
2017-12-20 14:52 ` [RFC PATCH 4/8] powerpc/64s: put io_sync bit into r14 Nicholas Piggin
2017-12-22 15:08   ` Thiago Jung Bauermann
2017-12-20 14:52 ` [RFC PATCH 5/8] powerpc/64s: put work_pending " Nicholas Piggin
2017-12-20 14:52 ` [RFC PATCH 6/8] powerpc/64s: put irq_soft_mask bits " Nicholas Piggin
2017-12-20 14:52 ` [RFC PATCH 7/8] powerpc/64s: put irq_soft_mask and irq_happened " Nicholas Piggin
2017-12-20 14:52 ` Nicholas Piggin [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171220145206.12234-9-npiggin@gmail.com \
    --to=npiggin@gmail.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.