Re: [PATCH v2 3/4] powerpc/64s/interrupt: Don't enable MSR[EE] in irq handlers unless perf is in use

2021-08-26 Thread Nicholas Piggin
Excerpts from kernel test robot's message of August 27, 2021 1:04 am:
> Hi Nicholas,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on powerpc/next]
> [also build test ERROR on v5.14-rc7 next-20210826]
> [cannot apply to scottwood/next]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:
> https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-64s-interrupt-speedups/20210825-204209
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
> config: powerpc-allnoconfig (attached as .config)

Fix for 32-bit:

diff --git a/arch/powerpc/include/asm/hw_irq.h 
b/arch/powerpc/include/asm/hw_irq.h
index 8c78c40c006e..55e3fa44f280 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -437,7 +437,7 @@ static inline bool arch_irq_disabled_regs(struct pt_regs 
*regs)
return !(regs->msr & MSR_EE);
 }
 
-static inline bool may_hard_irq_enable(void)
+static inline bool should_hard_irq_enable(void)
 {
return false;
 }




Re: [PATCH v2 3/4] powerpc/64s/interrupt: Don't enable MSR[EE] in irq handlers unless perf is in use

2021-08-26 Thread kernel test robot
Hi Nicholas,

I love your patch! Yet something to improve:

[auto build test ERROR on powerpc/next]
[also build test ERROR on v5.14-rc7 next-20210826]
[cannot apply to scottwood/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-64s-interrupt-speedups/20210825-204209
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-allnoconfig (attached as .config)
compiler: powerpc-linux-gcc (GCC) 11.2.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/a0eb195f49a01ed45b3f97815470f9c8acaa4991
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Nicholas-Piggin/powerpc-64s-interrupt-speedups/20210825-204209
git checkout a0eb195f49a01ed45b3f97815470f9c8acaa4991
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross 
ARCH=powerpc 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

   arch/powerpc/kernel/irq.c: In function '__do_irq':
>> arch/powerpc/kernel/irq.c:742:13: error: implicit declaration of function 
>> 'should_hard_irq_enable'; did you mean 'do_hard_irq_enable'? 
>> [-Werror=implicit-function-declaration]
 742 | if (should_hard_irq_enable())
 | ^~
 | do_hard_irq_enable
   In file included from :
   In function 'do_hard_irq_enable',
   inlined from '__do_irq' at arch/powerpc/kernel/irq.c:743:3:
>> include/linux/compiler_types.h:328:45: error: call to 
>> '__compiletime_assert_34' declared with attribute error: BUILD_BUG failed
 328 | _compiletime_assert(condition, msg, __compiletime_assert_, 
__COUNTER__)
 | ^
   include/linux/compiler_types.h:309:25: note: in definition of macro 
'__compiletime_assert'
 309 | prefix ## suffix();  
   \
 | ^~
   include/linux/compiler_types.h:328:9: note: in expansion of macro 
'_compiletime_assert'
 328 | _compiletime_assert(condition, msg, __compiletime_assert_, 
__COUNTER__)
 | ^~~
   include/linux/build_bug.h:39:37: note: in expansion of macro 
'compiletime_assert'
  39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
 | ^~
   include/linux/build_bug.h:59:21: note: in expansion of macro 
'BUILD_BUG_ON_MSG'
  59 | #define BUILD_BUG() BUILD_BUG_ON_MSG(1, "BUILD_BUG failed")
 | ^~~~
   arch/powerpc/include/asm/hw_irq.h:447:9: note: in expansion of macro 
'BUILD_BUG'
 447 | BUILD_BUG();
 | ^
   cc1: all warnings being treated as errors
--
   arch/powerpc/kernel/time.c: In function 'timer_interrupt':
>> arch/powerpc/kernel/time.c:570:13: error: implicit declaration of function 
>> 'should_hard_irq_enable'; did you mean 'do_hard_irq_enable'? 
>> [-Werror=implicit-function-declaration]
 570 | if (should_hard_irq_enable()) {
 | ^~
 | do_hard_irq_enable
   In file included from :
   In function 'do_hard_irq_enable',
   inlined from 'timer_interrupt' at arch/powerpc/kernel/time.c:584:3,
   inlined from 'timer_interrupt' at arch/powerpc/kernel/time.c:553:1:
>> include/linux/compiler_types.h:328:45: error: call to 
>> '__compiletime_assert_34' declared with attribute error: BUILD_BUG failed
 328 | _compiletime_assert(condition, msg, __compiletime_assert_, 
__COUNTER__)
 | ^
   include/linux/compiler_types.h:309:25: note: in definition of macro 
'__compiletime_assert'
 309 | prefix ## suffix();  
   \
 | ^~
   include/linux/compiler_types.h:328:9: note: in expansion of macro 
'_compiletime_assert'
 328 | _compiletime_assert(condition, msg, __compiletime_assert_, 
__COUNTER__)
 | ^~~
   include/linux/build_bug.h:39:37: note: in expansion of macro 
'compiletime_assert'
  39 | #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
 | ^~
   include/linux/build_bug.h:59:21: note: in expansion of macro 
'BUILD_BUG_ON_MSG'
  59 | #define BUILD_BUG() 

[PATCH v2 3/4] powerpc/64s/interrupt: Don't enable MSR[EE] in irq handlers unless perf is in use

2021-08-25 Thread Nicholas Piggin
Enabling MSR[EE] in interrupt handlers while interrupts are still soft
masked allows PMIs to profile interrupt handlers to some degree, beyond
what SIAR latching allows.

When perf is not being used, this is almost useless work. It requires an
extra mtmsrd in the irq handler, and it also opens the door to masked
interrupts hitting and requiring replay, which is more expensive than
just taking them directly. This effect can be noticable in high IRQ
workloads.

Avoid enabling MSR[EE] unless perf is currently in use. This saves about
60 cycles (or 8%) on a simple decrementer interrupt microbenchmark.
Replayed interrupts drop from 1.4% of interrupts to 0.003%.

This does prevent the soft-nmi interrupt being taken in these handlers,
but that's not too reliable anyway. The SMP watchdog will continue to be
the reliable way to catch lockups.

Signed-off-by: Nicholas Piggin 
---
 arch/powerpc/include/asm/hw_irq.h | 55 ++-
 arch/powerpc/kernel/dbell.c   |  3 +-
 arch/powerpc/kernel/irq.c |  3 +-
 arch/powerpc/kernel/time.c| 31 -
 4 files changed, 66 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/include/asm/hw_irq.h 
b/arch/powerpc/include/asm/hw_irq.h
index b987822e552e..8c78c40c006e 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -309,17 +309,54 @@ static inline bool lazy_irq_pending_nocheck(void)
 bool power_pmu_wants_prompt_pmi(void);
 
 /*
- * This is called by asynchronous interrupts to conditionally
- * re-enable hard interrupts after having cleared the source
- * of the interrupt. They are kept disabled if there is a different
- * soft-masked interrupt pending that requires hard masking.
+ * This is called by asynchronous interrupts to check whether to
+ * conditionally re-enable hard interrupts after having cleared
+ * the source of the interrupt. They are kept disabled if there
+ * is a different soft-masked interrupt pending that requires hard
+ * masking.
  */
-static inline void may_hard_irq_enable(void)
+static inline bool should_hard_irq_enable(void)
 {
-   if (!(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK)) {
-   get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
-   __hard_irq_enable();
-   }
+#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
+   WARN_ON(irq_soft_mask_return() == IRQS_ENABLED);
+   WARN_ON(mfmsr() & MSR_EE);
+#endif
+#ifdef CONFIG_PERF_EVENTS
+   /*
+* If the PMU is not running, there is not much reason to enable
+* MSR[EE] in irq handlers because any interrupts would just be
+* soft-masked.
+*
+* TODO: Add test for 64e
+*/
+   if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !power_pmu_wants_prompt_pmi())
+   return false;
+
+   if (get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK)
+   return false;
+
+   return true;
+#else
+   return false;
+#endif
+}
+
+/*
+ * Do the hard enabling, only call this if should_hard_irq_enable is true.
+ */
+static inline void do_hard_irq_enable(void)
+{
+#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
+   WARN_ON(irq_soft_mask_return() == IRQS_ENABLED);
+   WARN_ON(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK);
+   WARN_ON(mfmsr() & MSR_EE);
+#endif
+   /*
+* This allows PMI interrupts (and watchdog soft-NMIs) through.
+* There is no other reason to enable this way.
+*/
+   get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
+   __hard_irq_enable();
 }
 
 static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index 5545c9cd17c1..f55c6fb34a3a 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -27,7 +27,8 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)
 
ppc_msgsync();
 
-   may_hard_irq_enable();
+   if (should_hard_irq_enable())
+   do_hard_irq_enable();
 
kvmppc_clear_host_ipi(smp_processor_id());
__this_cpu_inc(irq_stat.doorbell_irqs);
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 551b653228c4..f658aa22a21e 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -739,7 +739,8 @@ void __do_irq(struct pt_regs *regs)
irq = ppc_md.get_irq();
 
/* We can hard enable interrupts now to allow perf interrupts */
-   may_hard_irq_enable();
+   if (should_hard_irq_enable())
+   do_hard_irq_enable();
 
/* And finally process it */
if (unlikely(!irq))
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index c487ba5a6e11..e7aab5540d09 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -567,22 +567,23 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt)
return;
}
 
-   /* Ensure a positive value is written to the decrementer, or else
-* some CPUs will continue to take