* [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation
@ 2016-07-25 14:52 Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags Madhavan Srinivasan
` (9 more replies)
0 siblings, 10 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
Local atomic operations are fast and highly reentrant per CPU counters.
Used for percpu variable updates. Local atomic operations only guarantee
variable modification atomicity wrt the CPU which owns the data and
these needs to be executed in a preemption safe way.
Here is the design of the patchset. Since local_* operations
are only need to be atomic to interrupts (IIUC), we have two options.
Either replay the "op" if interrupted or replay the interrupt after
the "op". Initial patchset posted was based on implementing local_* operation
based on CR5 which replay's the "op". Patchset had issues in case of
rewinding the address pointor from an array. This make the slow patch
really slow. Since CR5 based implementation proposed using __ex_table to find
the rewind addressr, this rasied concerns about size of __ex_table and vmlinux.
https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-December/123115.html
But this patchset uses Benjamin Herrenschmidt suggestion of using
arch_local_irq_disable_var() to soft_disable interrupts (including PMIs).
After finishing the "op", arch_local_irq_restore() called and correspondingly
interrupts are replayed if any occured.
patch re-write the current local_* functions to use arch_local_irq_disbale.
Base flow for each function is
{
arch_local_irq_disable_var(2)
load
..
store
arch_local_irq_restore()
}
Currently only asm/local.h has been rewrite, and also
the entire change is tested only in PPC64 (pseries guest)
Reason for the approach is that, currently l[w/d]arx/st[w/d]cx.
instruction pair is used for local_* operations, which are heavy
on cycle count and they dont support a local variant. So to
see whether the new implementation helps, used a modified
version of Rusty's benchmark code on local_t.
https://lkml.org/lkml/2008/12/16/450
Modifications to Rusty's benchmark code:
- Executed only local_t test
Here are the values with the patch.
Time in ns per iteration
Local_t Without Patch With Patch
_inc 28 8
_add 28 8
_read 3 3
_add_return 28 7
First four are the clean up patches which lays the foundation
to make things easier. Fifth patch in the patchset reverse the
current soft_enabled logic and commit message details the reason and
need for this change. Sixth patch holds the changes needed
for reversing logic. Rest of the patches are to add support
for maskable PMI and implementation of local_t using arch_local_disable_*().
Since the patchset is experimental, changes made are focused on pseries and
powernv platforms only. Would really like to know comments for
this approach before extending to other powerpc platforms.
Tested the patchset in a
- pSeries LPAR (with perf record).
- Ran kernbench with perf record for 24 hours.
- More testing needed.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Madhavan Srinivasan (9):
Add #defs for paca->soft_enabled flags
Cleanup to use LAZY_INTERRUPT_* macros for paca->soft_enabled update
powerpc: move set_soft_enabled()
powerpc: Use set_soft_enabled api to update paca->soft_enabled
powerpc: reverse the soft_enable logic
powerpc: modify __SOFTEN_TEST to support tri-state soft_enabled flag
powerpc: Add support to mask perf interrupts
powerpc: Support to replay PMIs
powerpc: rewrite local_t using soft_irq
arch/powerpc/include/asm/exception-64s.h | 24 +++++++--
arch/powerpc/include/asm/hw_irq.h | 43 ++++++++++++---
arch/powerpc/include/asm/irqflags.h | 8 +--
arch/powerpc/include/asm/kvm_ppc.h | 2 +-
arch/powerpc/include/asm/local.h | 91 ++++++++++++++++++++++----------
arch/powerpc/kernel/entry_64.S | 16 +++---
arch/powerpc/kernel/exceptions-64s.S | 27 ++++++++--
arch/powerpc/kernel/head_64.S | 3 +-
arch/powerpc/kernel/idle_power4.S | 3 +-
arch/powerpc/kernel/irq.c | 24 +++++----
arch/powerpc/kernel/process.c | 3 +-
arch/powerpc/kernel/setup_64.c | 4 ++
arch/powerpc/kernel/time.c | 4 +-
arch/powerpc/mm/hugetlbpage.c | 2 +-
arch/powerpc/perf/core-book3s.c | 2 +-
15 files changed, 184 insertions(+), 72 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 31+ messages in thread
* [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
@ 2016-07-25 14:52 ` Madhavan Srinivasan
2016-07-26 5:27 ` Nicholas Piggin
2016-07-25 14:52 ` [RFC PATCH 2/9] Cleanup to use LAZY_INTERRUPT_* macros for paca->soft_enabled update Madhavan Srinivasan
` (8 subsequent siblings)
9 siblings, 1 reply; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
Two #defs LAZY_INTERRUPT_ENABLED and
LAZY_INTERRUPT_DISABLED are added to be used
when updating paca->soft_enabled.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
-If the macro names looks not right, kindly suggest
arch/powerpc/include/asm/hw_irq.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index b59ac27a6b7d..e58c9d95050a 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -27,6 +27,13 @@
#define PACA_IRQ_EE_EDGE 0x10 /* BookE only */
#define PACA_IRQ_HMI 0x20
+/*
+ * flags for paca->soft_enabled
+ */
+#define LAZY_INTERRUPT_ENABLED 1
+#define LAZY_INTERRUPT_DISABLED 0
+
+
#endif /* CONFIG_PPC64 */
#ifndef __ASSEMBLY__
--
2.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [RFC PATCH 2/9] Cleanup to use LAZY_INTERRUPT_* macros for paca->soft_enabled update
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags Madhavan Srinivasan
@ 2016-07-25 14:52 ` Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 3/9] powerpc: move set_soft_enabled() Madhavan Srinivasan
` (7 subsequent siblings)
9 siblings, 0 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
Replace the hardcoded values used when updating
paca->soft_enabled with LAZY_INTERRUPT_* #def.
No logic change.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/exception-64s.h | 2 +-
arch/powerpc/include/asm/hw_irq.h | 15 ++++++++-------
arch/powerpc/include/asm/irqflags.h | 6 +++---
arch/powerpc/include/asm/kvm_ppc.h | 2 +-
arch/powerpc/kernel/entry_64.S | 14 +++++++-------
arch/powerpc/kernel/head_64.S | 3 ++-
arch/powerpc/kernel/idle_power4.S | 3 ++-
arch/powerpc/kernel/irq.c | 9 +++++----
arch/powerpc/kernel/process.c | 3 ++-
arch/powerpc/kernel/setup_64.c | 3 +++
arch/powerpc/kernel/time.c | 2 +-
arch/powerpc/mm/hugetlbpage.c | 2 +-
arch/powerpc/perf/core-book3s.c | 2 +-
13 files changed, 37 insertions(+), 29 deletions(-)
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 93ae809fe5ea..e24e63d216c4 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -406,7 +406,7 @@ label##_relon_hv: \
#define __SOFTEN_TEST(h, vec) \
lbz r10,PACASOFTIRQEN(r13); \
- cmpwi r10,0; \
+ cmpwi r10,LAZY_INTERRUPT_DISABLED; \
li r10,SOFTEN_VALUE_##vec; \
beq masked_##h##interrupt
#define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec)
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index e58c9d95050a..433fe60cf428 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -65,9 +65,10 @@ static inline unsigned long arch_local_irq_disable(void)
unsigned long flags, zero;
asm volatile(
- "li %1,0; lbz %0,%2(13); stb %1,%2(13)"
+ "li %1,%3; lbz %0,%2(13); stb %1,%2(13)"
: "=r" (flags), "=&r" (zero)
- : "i" (offsetof(struct paca_struct, soft_enabled))
+ : "i" (offsetof(struct paca_struct, soft_enabled)),\
+ "i" (LAZY_INTERRUPT_DISABLED)
: "memory");
return flags;
@@ -77,7 +78,7 @@ extern void arch_local_irq_restore(unsigned long);
static inline void arch_local_irq_enable(void)
{
- arch_local_irq_restore(1);
+ arch_local_irq_restore(LAZY_INTERRUPT_ENABLED);
}
static inline unsigned long arch_local_irq_save(void)
@@ -87,7 +88,7 @@ static inline unsigned long arch_local_irq_save(void)
static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
- return flags == 0;
+ return flags == LAZY_INTERRUPT_DISABLED;
}
static inline bool arch_irqs_disabled(void)
@@ -107,9 +108,9 @@ static inline bool arch_irqs_disabled(void)
u8 _was_enabled; \
__hard_irq_disable(); \
_was_enabled = local_paca->soft_enabled; \
- local_paca->soft_enabled = 0; \
+ local_paca->soft_enabled = LAZY_INTERRUPT_DISABLED;\
local_paca->irq_happened |= PACA_IRQ_HARD_DIS; \
- if (_was_enabled) \
+ if (_was_enabled == LAZY_INTERRUPT_ENABLED) \
trace_hardirqs_off(); \
} while(0)
@@ -132,7 +133,7 @@ static inline void may_hard_irq_enable(void)
static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
{
- return !regs->softe;
+ return (regs->softe == LAZY_INTERRUPT_DISABLED);
}
extern bool prep_irq_for_idle(void);
diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h
index f2149066fe5d..6091e46f2455 100644
--- a/arch/powerpc/include/asm/irqflags.h
+++ b/arch/powerpc/include/asm/irqflags.h
@@ -48,8 +48,8 @@
#define RECONCILE_IRQ_STATE(__rA, __rB) \
lbz __rA,PACASOFTIRQEN(r13); \
lbz __rB,PACAIRQHAPPENED(r13); \
- cmpwi cr0,__rA,0; \
- li __rA,0; \
+ cmpwi cr0,__rA,LAZY_INTERRUPT_DISABLED;\
+ li __rA,LAZY_INTERRUPT_DISABLED; \
ori __rB,__rB,PACA_IRQ_HARD_DIS; \
stb __rB,PACAIRQHAPPENED(r13); \
beq 44f; \
@@ -63,7 +63,7 @@
#define RECONCILE_IRQ_STATE(__rA, __rB) \
lbz __rA,PACAIRQHAPPENED(r13); \
- li __rB,0; \
+ li __rB,LAZY_INTERRUPT_DISABLED; \
ori __rA,__rA,PACA_IRQ_HARD_DIS; \
stb __rB,PACASOFTIRQEN(r13); \
stb __rA,PACAIRQHAPPENED(r13)
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index 2544edabe7f3..e790b8a6bf0b 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -707,7 +707,7 @@ static inline void kvmppc_fix_ee_before_entry(void)
/* Only need to enable IRQs by hard enabling them after this */
local_paca->irq_happened = 0;
- local_paca->soft_enabled = 1;
+ local_paca->soft_enabled = LAZY_INTERRUPT_ENABLED;
#endif
}
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 73e461a3dfbb..cade169a7517 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -147,7 +147,7 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
/* We do need to set SOFTE in the stack frame or the return
* from interrupt will be painful
*/
- li r10,1
+ li r10,LAZY_INTERRUPT_ENABLED
std r10,SOFTE(r1)
CURRENT_THREAD_INFO(r11, r1)
@@ -725,7 +725,7 @@ resume_kernel:
lwz r8,TI_PREEMPT(r9)
cmpwi cr1,r8,0
ld r0,SOFTE(r1)
- cmpdi r0,0
+ cmpdi r0,LAZY_INTERRUPT_DISABLED
crandc eq,cr1*4+eq,eq
bne restore
@@ -765,11 +765,11 @@ restore:
*/
ld r5,SOFTE(r1)
lbz r6,PACASOFTIRQEN(r13)
- cmpwi cr0,r5,0
+ cmpwi cr0,r5,LAZY_INTERRUPT_DISABLED
beq restore_irq_off
/* We are enabling, were we already enabled ? Yes, just return */
- cmpwi cr0,r6,1
+ cmpwi cr0,r6,LAZY_INTERRUPT_ENABLED
beq cr0,do_restore
/*
@@ -788,7 +788,7 @@ restore:
*/
restore_no_replay:
TRACE_ENABLE_INTS
- li r0,1
+ li r0,LAZY_INTERRUPT_ENABLED
stb r0,PACASOFTIRQEN(r13);
/*
@@ -894,7 +894,7 @@ restore_irq_off:
beq 1f
rlwinm r7,r7,0,~PACA_IRQ_HARD_DIS
stb r7,PACAIRQHAPPENED(r13)
-1: li r0,0
+1: li r0,LAZY_INTERRUPT_DISABLED
stb r0,PACASOFTIRQEN(r13);
TRACE_DISABLE_INTS
b do_restore
@@ -1012,7 +1012,7 @@ _GLOBAL(enter_rtas)
* check it with the asm equivalent of WARN_ON
*/
lbz r0,PACASOFTIRQEN(r13)
-1: tdnei r0,0
+1: tdnei r0,LAZY_INTERRUPT_DISABLED
EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING
#endif
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 2d14774af6b4..bfcb8625671b 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -789,6 +789,7 @@ __secondary_start:
/* Mark interrupts soft and hard disabled (they might be enabled
* in the PACA when doing hotplug)
*/
+ li r7,LAZY_INTERRUPT_DISABLED
stb r7,PACASOFTIRQEN(r13)
li r0,PACA_IRQ_HARD_DIS
stb r0,PACAIRQHAPPENED(r13)
@@ -957,7 +958,7 @@ start_here_common:
/* Mark interrupts soft and hard disabled (they might be enabled
* in the PACA when doing hotplug)
*/
- li r0,0
+ li r0,LAZY_INTERRUPT_DISABLED
stb r0,PACASOFTIRQEN(r13)
li r0,PACA_IRQ_HARD_DIS
stb r0,PACAIRQHAPPENED(r13)
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index f57a19348bdd..3e7fa14a736f 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -14,6 +14,7 @@
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>
+#include <asm/hw_irq.h>
#include <asm/irqflags.h>
#undef DEBUG
@@ -53,7 +54,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
mfmsr r7
#endif /* CONFIG_TRACE_IRQFLAGS */
- li r0,1
+ li r0,LAZY_INTERRUPT_ENABLED
stb r0,PACASOFTIRQEN(r13) /* we'll hard-enable shortly */
BEGIN_FTR_SECTION
DSSALL
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 3cb46a3b1de7..06dff620fcdc 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -67,6 +67,7 @@
#include <asm/smp.h>
#include <asm/debug.h>
#include <asm/livepatch.h>
+#include <asm/hw_irq.h>
#ifdef CONFIG_PPC64
#include <asm/paca.h>
@@ -207,7 +208,7 @@ notrace void arch_local_irq_restore(unsigned long en)
/* Write the new soft-enabled value */
set_soft_enabled(en);
- if (!en)
+ if (en == LAZY_INTERRUPT_DIABLED)
return;
/*
* From this point onward, we can take interrupts, preempt,
@@ -252,7 +253,7 @@ notrace void arch_local_irq_restore(unsigned long en)
}
#endif /* CONFIG_TRACE_IRQFLAG */
- set_soft_enabled(0);
+ set_soft_enabled(LAZY_INTERRUPT_DISABLED);
/*
* Check if anything needs to be re-emitted. We haven't
@@ -262,7 +263,7 @@ notrace void arch_local_irq_restore(unsigned long en)
replay = __check_irq_replay();
/* We can soft-enable now */
- set_soft_enabled(1);
+ set_soft_enabled(LAZY_INTERRUPT_ENABLED);
/*
* And replay if we have to. This will return with interrupts
@@ -336,7 +337,7 @@ bool prep_irq_for_idle(void)
* of entering the low power state.
*/
local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
- local_paca->soft_enabled = 1;
+ local_paca->soft_enabled = LAZY_INTERRUPT_ENABLED;
/* Tell the caller to enter the low power state */
return true;
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 0b93893424f5..eb2d1bc8607c 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -54,6 +54,7 @@
#include <asm/debug.h>
#ifdef CONFIG_PPC64
#include <asm/firmware.h>
+#include <asm/hw_irq.h>
#endif
#include <asm/code-patching.h>
#include <asm/exec.h>
@@ -1418,7 +1419,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
childregs->gpr[14] = ppc_function_entry((void *)usp);
#ifdef CONFIG_PPC64
clear_tsk_thread_flag(p, TIF_32BIT);
- childregs->softe = 1;
+ childregs->softe = LAZY_INTERRUPT_ENABLED;
#endif
childregs->gpr[15] = kthread_arg;
p->thread.regs = NULL; /* no user register state */
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 96d4a2b23d0f..0ca504839550 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -70,6 +70,7 @@
#include <asm/hugetlb.h>
#include <asm/epapr_hcalls.h>
#include <asm/livepatch.h>
+#include <asm/hw_irq.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
@@ -204,6 +205,8 @@ static void fixup_boot_paca(void)
get_paca()->cpu_start = 1;
/* Allow percpu accesses to work until we setup percpu data */
get_paca()->data_offset = 0;
+ /* Mark interrupts disabled in PACA */
+ get_paca()->soft_enabled = LAZY_INTERRUPT_DISABLED;
}
static void cpu_ready_for_interrupts(void)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 3ed9a5a21d77..e46f7ab6cbde 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -258,7 +258,7 @@ void accumulate_stolen_time(void)
* needs to reflect that so various debug stuff doesn't
* complain
*/
- local_paca->soft_enabled = 0;
+ local_paca->soft_enabled = LAZY_INTERRUPT_DISABLED;
sst = scan_dispatch_log(local_paca->starttime_user);
ust = scan_dispatch_log(local_paca->starttime);
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 119d18611500..56ea41da2ea7 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -907,7 +907,7 @@ void flush_dcache_icache_hugepage(struct page *page)
* So long as we atomically load page table pointers we are safe against teardown,
* we can follow the address down to the the page and take a ref on it.
* This function need to be called with interrupts disabled. We use this variant
- * when we have MSR[EE] = 0 but the paca->soft_enabled = 1
+ * when we have MSR[EE] = 0 but the paca->soft_enabled = LAZY_INTERRUPT_ENABLED
*/
pte_t *__find_linux_pte_or_hugepte(pgd_t *pgdir, unsigned long ea,
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 141c289ae492..a5a6b06f3c33 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -313,7 +313,7 @@ static inline void perf_read_regs(struct pt_regs *regs)
*/
static inline int perf_intr_is_nmi(struct pt_regs *regs)
{
- return !regs->softe;
+ return (regs->softe == LAZY_INTERRUPT_DISABLED);
}
/*
--
2.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [RFC PATCH 3/9] powerpc: move set_soft_enabled()
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 2/9] Cleanup to use LAZY_INTERRUPT_* macros for paca->soft_enabled update Madhavan Srinivasan
@ 2016-07-25 14:52 ` Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 4/9] powerpc: Use set_soft_enabled api to update paca->soft_enabled Madhavan Srinivasan
` (6 subsequent siblings)
9 siblings, 0 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
Move set_soft_enabled() from powerpc/kernel/irq.c to
asm/hw_irq.c. this way updation of paca->soft_enabled
can be forced wherever possible.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/hw_irq.h | 6 ++++++
arch/powerpc/kernel/irq.c | 6 ------
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 433fe60cf428..09491417fbf7 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -48,6 +48,12 @@ extern void unknown_exception(struct pt_regs *regs);
#ifdef CONFIG_PPC64
#include <asm/paca.h>
+static inline notrace void set_soft_enabled(unsigned long enable)
+{
+ __asm__ __volatile__("stb %0,%1(13)"
+ : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
+}
+
static inline unsigned long arch_local_save_flags(void)
{
unsigned long flags;
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 06dff620fcdc..88e541daf7b0 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -106,12 +106,6 @@ static inline notrace unsigned long get_irq_happened(void)
return happened;
}
-static inline notrace void set_soft_enabled(unsigned long enable)
-{
- __asm__ __volatile__("stb %0,%1(13)"
- : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
-}
-
static inline notrace int decrementer_check_overflow(void)
{
u64 now = get_tb_or_rtc();
--
2.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [RFC PATCH 4/9] powerpc: Use set_soft_enabled api to update paca->soft_enabled
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
` (2 preceding siblings ...)
2016-07-25 14:52 ` [RFC PATCH 3/9] powerpc: move set_soft_enabled() Madhavan Srinivasan
@ 2016-07-25 14:52 ` Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 5/9] powerpc: reverse the soft_enable logic Madhavan Srinivasan
` (5 subsequent siblings)
9 siblings, 0 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/kvm_ppc.h | 2 +-
arch/powerpc/kernel/irq.c | 4 ++--
arch/powerpc/kernel/setup_64.c | 3 ++-
arch/powerpc/kernel/time.c | 4 ++--
4 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index e790b8a6bf0b..68c2275c3674 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -707,7 +707,7 @@ static inline void kvmppc_fix_ee_before_entry(void)
/* Only need to enable IRQs by hard enabling them after this */
local_paca->irq_happened = 0;
- local_paca->soft_enabled = LAZY_INTERRUPT_ENABLED;
+ set_soft_enabled(LAZY_INTERRUPT_ENABLED);
#endif
}
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 88e541daf7b0..9b9b6df8d83d 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -202,7 +202,7 @@ notrace void arch_local_irq_restore(unsigned long en)
/* Write the new soft-enabled value */
set_soft_enabled(en);
- if (en == LAZY_INTERRUPT_DIABLED)
+ if (en == LAZY_INTERRUPT_DISABLED)
return;
/*
* From this point onward, we can take interrupts, preempt,
@@ -331,7 +331,7 @@ bool prep_irq_for_idle(void)
* of entering the low power state.
*/
local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
- local_paca->soft_enabled = LAZY_INTERRUPT_ENABLED;
+ set_soft_enabled(LAZY_INTERRUPT_ENABLED);
/* Tell the caller to enter the low power state */
return true;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 0ca504839550..2c7f4b23359a 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -206,7 +206,7 @@ static void fixup_boot_paca(void)
/* Allow percpu accesses to work until we setup percpu data */
get_paca()->data_offset = 0;
/* Mark interrupts disabled in PACA */
- get_paca()->soft_enabled = LAZY_INTERRUPT_DISABLED;
+ set_soft_enabled(LAZY_INTERRUPT_DISABLED);
}
static void cpu_ready_for_interrupts(void)
@@ -326,6 +326,7 @@ void early_setup_secondary(void)
{
/* Mark interrupts enabled in PACA */
get_paca()->soft_enabled = 0;
+ set_soft_enabled(LAZY_INTERRUPT_DISABLED);
/* Initialize the hash table or TLB handling */
early_init_mmu_secondary();
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index e46f7ab6cbde..0a1669708a0d 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -258,7 +258,7 @@ void accumulate_stolen_time(void)
* needs to reflect that so various debug stuff doesn't
* complain
*/
- local_paca->soft_enabled = LAZY_INTERRUPT_DISABLED;
+ set_soft_enabled(LAZY_INTERRUPT_DISABLED);
sst = scan_dispatch_log(local_paca->starttime_user);
ust = scan_dispatch_log(local_paca->starttime);
@@ -266,7 +266,7 @@ void accumulate_stolen_time(void)
local_paca->user_time -= ust;
local_paca->stolen_time += ust + sst;
- local_paca->soft_enabled = save_soft_enabled;
+ set_soft_enabled(save_soft_enabled);
}
static inline u64 calculate_stolen_time(u64 stop_tb)
--
2.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [RFC PATCH 5/9] powerpc: reverse the soft_enable logic
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
` (3 preceding siblings ...)
2016-07-25 14:52 ` [RFC PATCH 4/9] powerpc: Use set_soft_enabled api to update paca->soft_enabled Madhavan Srinivasan
@ 2016-07-25 14:52 ` Madhavan Srinivasan
2016-07-26 5:31 ` Nicholas Piggin
2016-07-25 14:52 ` [RFC PATCH 6/9] powerpc: modify __SOFTEN_TEST to support tri-state soft_enabled flag Madhavan Srinivasan
` (4 subsequent siblings)
9 siblings, 1 reply; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
"paca->soft_enabled" is used as a flag to mask some of interrupts.
Currently supported flags values and their details:
soft_enabled MSR[EE]
0 0 Disabled (PMI and HMI not masked)
1 1 Enabled
"paca->soft_enabled" is initialed to 1 to make the interripts as
enabled. arch_local_irq_disable() will toggle the value when interrupts
needs to disbled. At this point, the interrupts are not actually disabled,
instead, interrupt vector has code to check for the flag and mask it when it occurs.
By "mask it", it updated interrupt paca->irq_happened and return.
arch_local_irq_restore() is called to re-enable interrupts, which checks and
replays interrupts if any occured.
Now, as mentioned, current logic doesnot mask "performance monitoring interrupts"
and PMIs are implemented as NMI. But this patchset depends on local_irq_*
for a successful local_* update. Meaning, mask all possible interrupts during
local_* update and replay them after the update.
So the idea here is to reserve the "paca->soft_enabled" logic. New values and
details:
soft_enabled MSR[EE]
1 0 Disabled (PMI and HMI not masked)
0 1 Enabled
Reason for the this change is to create foundation for a third flag value "2"
for "soft_enabled" to add support to mask PMIs. When arch_irq_disable_* is
called with a value "2", PMI interrupts are mask. But when called with a value
of "1", PMI are not mask.
With new flag value for "soft_enabled", states looks like:
soft_enabled MSR[EE]
2 0 Disbaled PMIs also
1 0 Disabled (PMI and HMI not masked)
0 1 Enabled
And interrupt handler code for checking has been modified to check for
for "greater than or equal" to 1 condition instead.
Comment here explains the logic changes that are implemented in the following
patches. But this patch primarly does only reserve the logic. Following patches
will make the corresponding changes.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/hw_irq.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 09491417fbf7..2b87930e0e82 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -30,8 +30,8 @@
/*
* flags for paca->soft_enabled
*/
-#define LAZY_INTERRUPT_ENABLED 1
-#define LAZY_INTERRUPT_DISABLED 0
+#define LAZY_INTERRUPT_ENABLED 0
+#define LAZY_INTERRUPT_DISABLED 1
#endif /* CONFIG_PPC64 */
--
2.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [RFC PATCH 6/9] powerpc: modify __SOFTEN_TEST to support tri-state soft_enabled flag
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
` (4 preceding siblings ...)
2016-07-25 14:52 ` [RFC PATCH 5/9] powerpc: reverse the soft_enable logic Madhavan Srinivasan
@ 2016-07-25 14:52 ` Madhavan Srinivasan
2016-07-26 5:41 ` Nicholas Piggin
2016-07-25 14:52 ` [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts Madhavan Srinivasan
` (3 subsequent siblings)
9 siblings, 1 reply; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
Foundation patch to support checking of new flag for "paca->soft_enabled".
Modify the condition checking for the "soft_enabled" from "equal" to
"greater than or equal to".
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/exception-64s.h | 2 +-
arch/powerpc/include/asm/hw_irq.h | 4 ++--
arch/powerpc/include/asm/irqflags.h | 2 +-
arch/powerpc/kernel/entry_64.S | 4 ++--
arch/powerpc/kernel/irq.c | 4 ++--
5 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index e24e63d216c4..44d3f539d8a5 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -408,7 +408,7 @@ label##_relon_hv: \
lbz r10,PACASOFTIRQEN(r13); \
cmpwi r10,LAZY_INTERRUPT_DISABLED; \
li r10,SOFTEN_VALUE_##vec; \
- beq masked_##h##interrupt
+ bge masked_##h##interrupt
#define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec)
#define SOFTEN_TEST_PR(vec) \
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 2b87930e0e82..b7c7f1c6706f 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -94,7 +94,7 @@ static inline unsigned long arch_local_irq_save(void)
static inline bool arch_irqs_disabled_flags(unsigned long flags)
{
- return flags == LAZY_INTERRUPT_DISABLED;
+ return flags >= LAZY_INTERRUPT_DISABLED;
}
static inline bool arch_irqs_disabled(void)
@@ -139,7 +139,7 @@ static inline void may_hard_irq_enable(void)
static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
{
- return (regs->softe == LAZY_INTERRUPT_DISABLED);
+ return (regs->softe >= LAZY_INTERRUPT_DISABLED);
}
extern bool prep_irq_for_idle(void);
diff --git a/arch/powerpc/include/asm/irqflags.h b/arch/powerpc/include/asm/irqflags.h
index 6091e46f2455..235055fabf65 100644
--- a/arch/powerpc/include/asm/irqflags.h
+++ b/arch/powerpc/include/asm/irqflags.h
@@ -52,7 +52,7 @@
li __rA,LAZY_INTERRUPT_DISABLED; \
ori __rB,__rB,PACA_IRQ_HARD_DIS; \
stb __rB,PACAIRQHAPPENED(r13); \
- beq 44f; \
+ bge 44f; \
stb __rA,PACASOFTIRQEN(r13); \
TRACE_DISABLE_INTS; \
44:
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index cade169a7517..7ab6bfff653e 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -766,7 +766,7 @@ restore:
ld r5,SOFTE(r1)
lbz r6,PACASOFTIRQEN(r13)
cmpwi cr0,r5,LAZY_INTERRUPT_DISABLED
- beq restore_irq_off
+ bge restore_irq_off
/* We are enabling, were we already enabled ? Yes, just return */
cmpwi cr0,r6,LAZY_INTERRUPT_ENABLED
@@ -1012,7 +1012,7 @@ _GLOBAL(enter_rtas)
* check it with the asm equivalent of WARN_ON
*/
lbz r0,PACASOFTIRQEN(r13)
-1: tdnei r0,LAZY_INTERRUPT_DISABLED
+1: tdeqi r0,LAZY_INTERRUPT_ENABLED
EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,BUGFLAG_WARNING
#endif
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 9b9b6df8d83d..597c20d1814c 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -202,7 +202,7 @@ notrace void arch_local_irq_restore(unsigned long en)
/* Write the new soft-enabled value */
set_soft_enabled(en);
- if (en == LAZY_INTERRUPT_DISABLED)
+ if (en >= LAZY_INTERRUPT_DISABLED)
return;
/*
* From this point onward, we can take interrupts, preempt,
@@ -247,7 +247,7 @@ notrace void arch_local_irq_restore(unsigned long en)
}
#endif /* CONFIG_TRACE_IRQFLAG */
- set_soft_enabled(LAZY_INTERRUPT_DISABLED);
+ set_soft_enabled(en);
/*
* Check if anything needs to be re-emitted. We haven't
--
2.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
` (5 preceding siblings ...)
2016-07-25 14:52 ` [RFC PATCH 6/9] powerpc: modify __SOFTEN_TEST to support tri-state soft_enabled flag Madhavan Srinivasan
@ 2016-07-25 14:52 ` Madhavan Srinivasan
2016-07-26 5:46 ` Nicholas Piggin
2016-07-25 14:52 ` [RFC PATCH 8/9] powerpc: Support to replay PMIs Madhavan Srinivasan
` (2 subsequent siblings)
9 siblings, 1 reply; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
To support masking of the PMI interrupts, couple of new interrupt handler
macros are added MASKABLE_EXCEPTION_PSERIES_OOL and
MASKABLE_RELON_EXCEPTION_PSERIES_OOL. These are needed to include the
SOFTEN_TEST and implement the support at both host and guest kernel.
Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*" added to
use in the exception code to check for PMI interrupts.
__SOFTEN_TEST macro is modified to support the PMI interrupt.
Present __SOFTEN_TEST code loads the soft_enabled from paca and check to call
masked_interrupt handler code. To support both current behaviour and PMI
masking, these changes are added,
1) Current LR register content are saved in R11
2) "bge" branch operation is changed to "bgel".
3) restore R11 to LR
Reason:
To retain PMI as NMI behaviour for flag state of 1, we save the LR regsiter
value in R11 and branch to "masked_interrupt" handler with LR update. And in
"masked_interrupt" handler, we check for the "SOFTEN_VALUE_*" value in R10
for PMI and branch back with "blr" if PMI.
To mask PMI for a flag >1 value, masked_interrupt vaoid's the above check
and continue to execute the masked_interrupt code and disabled MSR[EE] and
updated the irq_happend with PMI info.
Finally, saving of R11 is moved before calling SOFTEN_TEST in the
__EXCEPTION_PROLOG_1 macro to support saving of LR values in SOFTEN_TEST.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/exception-64s.h | 22 ++++++++++++++++++++--
arch/powerpc/include/asm/hw_irq.h | 1 +
arch/powerpc/kernel/exceptions-64s.S | 27 ++++++++++++++++++++++++---
3 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 44d3f539d8a5..c951b7ab5108 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -166,8 +166,8 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \
SAVE_CTR(r10, area); \
mfcr r9; \
- extra(vec); \
std r11,area+EX_R11(r13); \
+ extra(vec); \
std r12,area+EX_R12(r13); \
GET_SCRATCH0(r10); \
std r10,area+EX_R13(r13)
@@ -403,12 +403,17 @@ label##_relon_hv: \
#define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL
#define SOFTEN_VALUE_0xe60 PACA_IRQ_HMI
#define SOFTEN_VALUE_0xe62 PACA_IRQ_HMI
+#define SOFTEN_VALUE_0xf01 PACA_IRQ_PMI
+#define SOFTEN_VALUE_0xf00 PACA_IRQ_PMI
#define __SOFTEN_TEST(h, vec) \
lbz r10,PACASOFTIRQEN(r13); \
cmpwi r10,LAZY_INTERRUPT_DISABLED; \
li r10,SOFTEN_VALUE_##vec; \
- bge masked_##h##interrupt
+ mflr r11; \
+ bgel masked_##h##interrupt; \
+ mtlr r11;
+
#define _SOFTEN_TEST(h, vec) __SOFTEN_TEST(h, vec)
#define SOFTEN_TEST_PR(vec) \
@@ -438,6 +443,12 @@ label##_pSeries: \
_MASKABLE_EXCEPTION_PSERIES(vec, label, \
EXC_STD, SOFTEN_TEST_PR)
+#define MASKABLE_EXCEPTION_PSERIES_OOL(vec, label) \
+ .globl label##_pSeries; \
+label##_pSeries: \
+ EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec); \
+ EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD);
+
#define MASKABLE_EXCEPTION_HV(loc, vec, label) \
. = loc; \
.globl label##_hv; \
@@ -466,6 +477,13 @@ label##_relon_pSeries: \
_MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, \
EXC_STD, SOFTEN_NOTEST_PR)
+#define MASKABLE_RELON_EXCEPTION_PSERIES_OOL(vec, label) \
+ .globl label##_relon_pSeries; \
+label##_relon_pSeries: \
+ EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec); \
+ EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD);
+
+
#define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label) \
. = loc; \
.globl label##_relon_hv; \
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index b7c7f1c6706f..cc69dde6eb84 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -26,6 +26,7 @@
#define PACA_IRQ_DEC 0x08 /* Or FIT */
#define PACA_IRQ_EE_EDGE 0x10 /* BookE only */
#define PACA_IRQ_HMI 0x20
+#define PACA_IRQ_PMI 0x40
/*
* flags for paca->soft_enabled
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 8bcc1b457115..479271168bb8 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -360,7 +360,11 @@ hv_doorbell_trampoline:
performance_monitor_pseries_trampoline:
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_0(PACA_EXGEN)
+BEGIN_FTR_SECTION
+ b performance_monitor_hv
+FTR_SECTION_ELSE
b performance_monitor_pSeries
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
. = 0xf20
altivec_unavailable_pseries_trampoline:
@@ -602,8 +606,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xe82)
/* moved from 0xf00 */
- STD_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
+BEGIN_FTR_SECTION
+ MASKABLE_EXCEPTION_HV_OOL(0xf01, performance_monitor)
+ KVM_HANDLER(PACA_EXGEN, EXC_HV, 0xf01)
+FTR_SECTION_ELSE
+ MASKABLE_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf00)
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
STD_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xf20)
STD_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
@@ -625,7 +634,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
*/
#define MASKED_INTERRUPT(_H) \
masked_##_H##interrupt: \
- std r11,PACA_EXGEN+EX_R11(r13); \
+ bgt 3f; \
+ cmpwi r10,PACA_IRQ_PMI; \
+ bne 3f; \
+ blr; \
+3: mtlr r11; \
lbz r11,PACAIRQHAPPENED(r13); \
or r11,r11,r10; \
stb r11,PACAIRQHAPPENED(r13); \
@@ -881,7 +894,11 @@ h_doorbell_relon_trampoline:
performance_monitor_relon_pseries_trampoline:
SET_SCRATCH0(r13)
EXCEPTION_PROLOG_0(PACA_EXGEN)
+BEGIN_FTR_SECTION
+ b performance_monitor_relon_hv
+FTR_SECTION_ELSE
b performance_monitor_relon_pSeries
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
. = 0x4f20
altivec_unavailable_relon_pseries_trampoline:
@@ -1138,7 +1155,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
STD_RELON_EXCEPTION_HV_OOL(0xe40, emulation_assist)
MASKABLE_RELON_EXCEPTION_HV_OOL(0xe80, h_doorbell)
- STD_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
+BEGIN_FTR_SECTION
+ MASKABLE_RELON_EXCEPTION_HV_OOL(0xf01, performance_monitor)
+FTR_SECTION_ELSE
+ MASKABLE_RELON_EXCEPTION_PSERIES_OOL(0xf00, performance_monitor)
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE)
STD_RELON_EXCEPTION_PSERIES_OOL(0xf20, altivec_unavailable)
STD_RELON_EXCEPTION_PSERIES_OOL(0xf40, vsx_unavailable)
STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
--
2.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [RFC PATCH 8/9] powerpc: Support to replay PMIs
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
` (6 preceding siblings ...)
2016-07-25 14:52 ` [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts Madhavan Srinivasan
@ 2016-07-25 14:52 ` Madhavan Srinivasan
2016-07-26 5:50 ` Nicholas Piggin
2016-07-25 14:52 ` [RFC PATCH 9/9] powerpc: rewrite local_t using soft_irq Madhavan Srinivasan
2016-07-26 12:21 ` [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Benjamin Herrenschmidt
9 siblings, 1 reply; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
Code to replay the Performance Monitoring Interrupts(PMI).
In the masked_interrupt handler, for PMIs we reset the MSR[EE]
and return. This is due the fact that PMIs are level triggered.
In the __check_irq_replay(), we enabled the MSR[EE] which will
fire the interrupt for us.
Patch also adds a new arch_local_irq_disable_var() variant. New
variant takes an input value to write to the paca->soft_enabled.
This will be used in following patch to implement the tri-state
value for soft-enabled.
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/hw_irq.h | 14 ++++++++++++++
arch/powerpc/kernel/irq.c | 9 ++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index cc69dde6eb84..863179654452 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -81,6 +81,20 @@ static inline unsigned long arch_local_irq_disable(void)
return flags;
}
+static inline unsigned long arch_local_irq_disable_var(int value)
+{
+ unsigned long flags, zero;
+
+ asm volatile(
+ "li %1,%3; lbz %0,%2(13); stb %1,%2(13)"
+ : "=r" (flags), "=&r" (zero)
+ : "i" (offsetof(struct paca_struct, soft_enabled)),\
+ "i" (value)
+ : "memory");
+
+ return flags;
+}
+
extern void arch_local_irq_restore(unsigned long);
static inline void arch_local_irq_enable(void)
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 597c20d1814c..81fe0da1f86d 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -158,9 +158,16 @@ notrace unsigned int __check_irq_replay(void)
if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow())
return 0x900;
+ /*
+ * In masked_handler() for PMI, we disable MSR[EE] and return.
+ * When replaying it, just enabling the MSR[EE] will do
+ * trick, since the PMI are "level" triggered.
+ */
+ local_paca->irq_happened &= ~PACA_IRQ_PMI;
+
/* Finally check if an external interrupt happened */
local_paca->irq_happened &= ~PACA_IRQ_EE;
- if (happened & PACA_IRQ_EE)
+ if ((happened & PACA_IRQ_EE) || (happened & PACA_IRQ_PMI))
return 0x500;
#ifdef CONFIG_PPC_BOOK3E
--
2.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* [RFC PATCH 9/9] powerpc: rewrite local_t using soft_irq
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
` (7 preceding siblings ...)
2016-07-25 14:52 ` [RFC PATCH 8/9] powerpc: Support to replay PMIs Madhavan Srinivasan
@ 2016-07-25 14:52 ` Madhavan Srinivasan
2016-07-26 5:53 ` Nicholas Piggin
2016-07-26 12:21 ` [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Benjamin Herrenschmidt
9 siblings, 1 reply; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-25 14:52 UTC (permalink / raw)
To: benh, mpe, anton, paulus; +Cc: linuxppc-dev, Madhavan Srinivasan
Local atomic operations are fast and highly reentrant per CPU counters.
Used for percpu variable updates. Local atomic operations only guarantee
variable modification atomicity wrt the CPU which owns the data and
these needs to be executed in a preemption safe way.
Here is the design of this patch. Since local_* operations
are only need to be atomic to interrupts (IIUC), we have two options.
Either replay the "op" if interrupted or replay the interrupt after
the "op". Initial patchset posted was based on implementing local_* operation
based on CR5 which replay's the "op". Patchset had issues in case of
rewinding the address pointor from an array. This make the slow patch
really slow. Since CR5 based implementation proposed using __ex_table to find
the rewind addressr, this rasied concerns about size of __ex_table and vmlinux.
https://lists.ozlabs.org/pipermail/linuxppc-dev/2014-December/123115.html
But this patch uses Benjamin Herrenschmidt suggestion of arch_local_irq_disable_var() to soft_disable
interrupts (including PMIs). After finishing the "op", arch_local_irq_restore()
called and correspondingly interrupts are replayed if any occured.
patch re-write the current local_* functions to use arch_local_irq_disbale.
Base flow for each function is
{
arch_local_irq_disable_var(2)
load
..
store
arch_local_irq_restore()
}
Currently only asm/local.h has been rewrite, and also
the entire change is tested only in PPC64 (pseries guest)
Reason for the approach is that, currently l[w/d]arx/st[w/d]cx.
instruction pair is used for local_* operations, which are heavy
on cycle count and they dont support a local variant. So to
see whether the new implementation helps, used a modified
version of Rusty's benchmark code on local_t.
https://lkml.org/lkml/2008/12/16/450
Modifications to Rusty's benchmark code:
- Executed only local_t test
Here are the values with the patch.
Time in ns per iteration
Local_t Without Patch With Patch
_inc 28 8
_add 28 8
_read 3 3
_add_return 28 7
Tested the patch in a
- pSeries LPAR (with perf record)
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/local.h | 91 +++++++++++++++++++++++++++-------------
1 file changed, 63 insertions(+), 28 deletions(-)
diff --git a/arch/powerpc/include/asm/local.h b/arch/powerpc/include/asm/local.h
index b8da91363864..afd3dabd92cb 100644
--- a/arch/powerpc/include/asm/local.h
+++ b/arch/powerpc/include/asm/local.h
@@ -14,24 +14,50 @@ typedef struct
#define local_read(l) atomic_long_read(&(l)->a)
#define local_set(l,i) atomic_long_set(&(l)->a, (i))
-#define local_add(i,l) atomic_long_add((i),(&(l)->a))
-#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
-#define local_inc(l) atomic_long_inc(&(l)->a)
-#define local_dec(l) atomic_long_dec(&(l)->a)
+static __inline__ void local_add(long i, local_t *l)
+{
+ long t;
+ unsigned long flags;
+
+ flags = arch_local_irq_disable_var(2);
+ __asm__ __volatile__(
+ PPC_LL" %0,0(%2)\n\
+ add %0,%1,%0\n"
+ PPC_STL" %0,0(%2)\n"
+ : "=&r" (t)
+ : "r" (i), "r" (&(l->a.counter)));
+ arch_local_irq_restore(flags);
+}
+
+static __inline__ void local_sub(long i, local_t *l)
+{
+ long t;
+ unsigned long flags;
+
+ flags = arch_local_irq_disable_var(2);
+ __asm__ __volatile__(
+ PPC_LL" %0,0(%2)\n\
+ subf %0,%1,%0\n"
+ PPC_STL" %0,0(%2)\n"
+ : "=&r" (t)
+ : "r" (i), "r" (&(l->a.counter)));
+ arch_local_irq_restore(flags);
+}
static __inline__ long local_add_return(long a, local_t *l)
{
long t;
+ unsigned long flags;
+ flags = arch_local_irq_disable_var(2);
__asm__ __volatile__(
-"1:" PPC_LLARX(%0,0,%2,0) " # local_add_return\n\
+ PPC_LL" %0,0(%2)\n\
add %0,%1,%0\n"
- PPC405_ERR77(0,%2)
- PPC_STLCX "%0,0,%2 \n\
- bne- 1b"
+ PPC_STL "%0,0(%2)\n"
: "=&r" (t)
: "r" (a), "r" (&(l->a.counter))
: "cc", "memory");
+ arch_local_irq_restore(flags);
return t;
}
@@ -41,16 +67,18 @@ static __inline__ long local_add_return(long a, local_t *l)
static __inline__ long local_sub_return(long a, local_t *l)
{
long t;
+ unsigned long flags;
+
+ flags = arch_local_irq_disable_var(2);
__asm__ __volatile__(
-"1:" PPC_LLARX(%0,0,%2,0) " # local_sub_return\n\
+"1:" PPC_LL" %0,0(%2)\n\
subf %0,%1,%0\n"
- PPC405_ERR77(0,%2)
- PPC_STLCX "%0,0,%2 \n\
- bne- 1b"
+ PPC_STL "%0,0(%2)\n"
: "=&r" (t)
: "r" (a), "r" (&(l->a.counter))
: "cc", "memory");
+ arch_local_irq_restore(flags);
return t;
}
@@ -58,16 +86,17 @@ static __inline__ long local_sub_return(long a, local_t *l)
static __inline__ long local_inc_return(local_t *l)
{
long t;
+ unsigned long flags;
+ flags = arch_local_irq_disable_var(2);
__asm__ __volatile__(
-"1:" PPC_LLARX(%0,0,%1,0) " # local_inc_return\n\
+"1:" PPC_LL" %0,0(%1)\n\
addic %0,%0,1\n"
- PPC405_ERR77(0,%1)
- PPC_STLCX "%0,0,%1 \n\
- bne- 1b"
+ PPC_STL "%0,0(%1)\n"
: "=&r" (t)
: "r" (&(l->a.counter))
: "cc", "xer", "memory");
+ arch_local_irq_restore(flags);
return t;
}
@@ -85,20 +114,24 @@ static __inline__ long local_inc_return(local_t *l)
static __inline__ long local_dec_return(local_t *l)
{
long t;
+ unsigned long flags;
+ flags = arch_local_irq_disable_var(2);
__asm__ __volatile__(
-"1:" PPC_LLARX(%0,0,%1,0) " # local_dec_return\n\
+ PPC_LL" %0,0(%1)\n\
addic %0,%0,-1\n"
- PPC405_ERR77(0,%1)
- PPC_STLCX "%0,0,%1\n\
- bne- 1b"
+ PPC_STL "%0,0(%1)\n"
: "=&r" (t)
: "r" (&(l->a.counter))
: "cc", "xer", "memory");
+ arch_local_irq_restore(flags);
return t;
}
+#define local_inc(l) local_inc_return(l)
+#define local_dec(l) local_dec_return(l)
+
#define local_cmpxchg(l, o, n) \
(cmpxchg_local(&((l)->a.counter), (o), (n)))
#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n)))
@@ -115,20 +148,21 @@ static __inline__ long local_dec_return(local_t *l)
static __inline__ int local_add_unless(local_t *l, long a, long u)
{
long t;
+ unsigned long flags;
+ flags = arch_local_irq_disable_var(2);
__asm__ __volatile__ (
-"1:" PPC_LLARX(%0,0,%1,0) " # local_add_unless\n\
+ PPC_LL" %0,0(%1)\n\
cmpw 0,%0,%3 \n\
beq- 2f \n\
add %0,%2,%0 \n"
- PPC405_ERR77(0,%2)
- PPC_STLCX "%0,0,%1 \n\
- bne- 1b \n"
+ PPC_STL" %0,0(%1) \n"
" subf %0,%2,%0 \n\
2:"
: "=&r" (t)
: "r" (&(l->a.counter)), "r" (a), "r" (u)
: "cc", "memory");
+ arch_local_irq_restore(flags);
return t != u;
}
@@ -145,19 +179,20 @@ static __inline__ int local_add_unless(local_t *l, long a, long u)
static __inline__ long local_dec_if_positive(local_t *l)
{
long t;
+ unsigned long flags;
+ flags = arch_local_irq_disable_var(2);
__asm__ __volatile__(
-"1:" PPC_LLARX(%0,0,%1,0) " # local_dec_if_positive\n\
+ PPC_LL" %0,0(%1)\n\
cmpwi %0,1\n\
addi %0,%0,-1\n\
blt- 2f\n"
- PPC405_ERR77(0,%1)
- PPC_STLCX "%0,0,%1\n\
- bne- 1b"
+ PPC_STL "%0,0(%1)\n"
"\n\
2:" : "=&b" (t)
: "r" (&(l->a.counter))
: "cc", "memory");
+ arch_local_irq_restore(flags);
return t;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags
2016-07-25 14:52 ` [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags Madhavan Srinivasan
@ 2016-07-26 5:27 ` Nicholas Piggin
2016-07-26 6:05 ` Madhavan Srinivasan
0 siblings, 1 reply; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 5:27 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Mon, 25 Jul 2016 20:22:14 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> Two #defs LAZY_INTERRUPT_ENABLED and
> LAZY_INTERRUPT_DISABLED are added to be used
> when updating paca->soft_enabled.
This is a very nice patchset, but can this not be a new name?
We use "soft enabled/disabled" everywhere for it. I think lazy
is an implementation detail anyway because some interrupts don't
cause a hard disable at all.
Thanks,
Nick
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 5/9] powerpc: reverse the soft_enable logic
2016-07-25 14:52 ` [RFC PATCH 5/9] powerpc: reverse the soft_enable logic Madhavan Srinivasan
@ 2016-07-26 5:31 ` Nicholas Piggin
2016-07-26 6:07 ` Madhavan Srinivasan
0 siblings, 1 reply; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 5:31 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Mon, 25 Jul 2016 20:22:18 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> "paca->soft_enabled" is used as a flag to mask some of interrupts.
> Currently supported flags values and their details:
>
> soft_enabled MSR[EE]
>
> 0 0 Disabled (PMI and HMI not masked)
> 1 1 Enabled
>
> "paca->soft_enabled" is initialed to 1 to make the interripts as
> enabled. arch_local_irq_disable() will toggle the value when
> interrupts needs to disbled. At this point, the interrupts are not
> actually disabled, instead, interrupt vector has code to check for
> the flag and mask it when it occurs. By "mask it", it updated
> interrupt paca->irq_happened and return. arch_local_irq_restore() is
> called to re-enable interrupts, which checks and replays interrupts
> if any occured.
>
> Now, as mentioned, current logic doesnot mask "performance monitoring
> interrupts" and PMIs are implemented as NMI. But this patchset
> depends on local_irq_* for a successful local_* update. Meaning, mask
> all possible interrupts during local_* update and replay them after
> the update.
>
> So the idea here is to reserve the "paca->soft_enabled" logic. New
> values and details:
>
> soft_enabled MSR[EE]
>
> 1 0 Disabled (PMI and HMI not masked)
> 0 1 Enabled
>
> Reason for the this change is to create foundation for a third flag
> value "2" for "soft_enabled" to add support to mask PMIs. When
> arch_irq_disable_* is called with a value "2", PMI interrupts are
> mask. But when called with a value of "1", PMI are not mask.
>
> With new flag value for "soft_enabled", states looks like:
>
> soft_enabled MSR[EE]
>
> 2 0 Disbaled PMIs also
> 1 0 Disabled (PMI and HMI not masked)
> 0 1 Enabled
>
> And interrupt handler code for checking has been modified to check for
> for "greater than or equal" to 1 condition instead.
This bit of the patch seems to have been moved into other part
of the series. Ideally (unless there is a good reason), it is nice
to have each individual patch result in a working kernel before
and after.
Nice way to avoid adding more branches though.
Thanks,
Nick
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 6/9] powerpc: modify __SOFTEN_TEST to support tri-state soft_enabled flag
2016-07-25 14:52 ` [RFC PATCH 6/9] powerpc: modify __SOFTEN_TEST to support tri-state soft_enabled flag Madhavan Srinivasan
@ 2016-07-26 5:41 ` Nicholas Piggin
2016-07-26 6:12 ` Madhavan Srinivasan
0 siblings, 1 reply; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 5:41 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Mon, 25 Jul 2016 20:22:19 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> Foundation patch to support checking of new flag for
> "paca->soft_enabled". Modify the condition checking for the
> "soft_enabled" from "equal" to "greater than or equal to".
Rather than a "tri-state" and the mystery "2" state, can you
make a #define for that guy, and use levels.
0-> all enabled
1-> "linux" interrupts disabled
2-> PMU also disabled
etc.
Thanks,
Nick
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts
2016-07-25 14:52 ` [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts Madhavan Srinivasan
@ 2016-07-26 5:46 ` Nicholas Piggin
2016-07-26 6:25 ` Madhavan Srinivasan
0 siblings, 1 reply; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 5:46 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Mon, 25 Jul 2016 20:22:20 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> To support masking of the PMI interrupts, couple of new interrupt
> handler macros are added MASKABLE_EXCEPTION_PSERIES_OOL and
> MASKABLE_RELON_EXCEPTION_PSERIES_OOL. These are needed to include the
> SOFTEN_TEST and implement the support at both host and guest kernel.
>
> Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*" added
> to use in the exception code to check for PMI interrupts.
>
> __SOFTEN_TEST macro is modified to support the PMI interrupt.
> Present __SOFTEN_TEST code loads the soft_enabled from paca and check
> to call masked_interrupt handler code. To support both current
> behaviour and PMI masking, these changes are added,
>
> 1) Current LR register content are saved in R11
> 2) "bge" branch operation is changed to "bgel".
> 3) restore R11 to LR
>
> Reason:
>
> To retain PMI as NMI behaviour for flag state of 1, we save the LR
> regsiter value in R11 and branch to "masked_interrupt" handler with
> LR update. And in "masked_interrupt" handler, we check for the
> "SOFTEN_VALUE_*" value in R10 for PMI and branch back with "blr" if
> PMI.
>
> To mask PMI for a flag >1 value, masked_interrupt vaoid's the above
> check and continue to execute the masked_interrupt code and disabled
> MSR[EE] and updated the irq_happend with PMI info.
>
> Finally, saving of R11 is moved before calling SOFTEN_TEST in the
> __EXCEPTION_PROLOG_1 macro to support saving of LR values in
> SOFTEN_TEST.
>
> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/exception-64s.h | 22 ++++++++++++++++++++--
> arch/powerpc/include/asm/hw_irq.h | 1 +
> arch/powerpc/kernel/exceptions-64s.S | 27
> ++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 5
> deletions(-)
>
> diff --git a/arch/powerpc/include/asm/exception-64s.h
> b/arch/powerpc/include/asm/exception-64s.h index
> 44d3f539d8a5..c951b7ab5108 100644 ---
> a/arch/powerpc/include/asm/exception-64s.h +++
> b/arch/powerpc/include/asm/exception-64s.h @@ -166,8 +166,8 @@
> END_FTR_SECTION_NESTED(ftr,ftr,943)
> OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);
> \ SAVE_CTR(r10, area);
> \ mfcr
> r9; \
> -
> extra(vec); \
> std
> r11,area+EX_R11(r13); \
> +
> extra(vec); \
> std
> r12,area+EX_R12(r13); \
> GET_SCRATCH0(r10); \
> std r10,area+EX_R13(r13) @@ -403,12 +403,17 @@
> label##_relon_hv: \
> #define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL #define
> SOFTEN_VALUE_0xe60 PACA_IRQ_HMI #define
> SOFTEN_VALUE_0xe62 PACA_IRQ_HMI +#define
> SOFTEN_VALUE_0xf01 PACA_IRQ_PMI +#define
> SOFTEN_VALUE_0xf00 PACA_IRQ_PMI
#define __SOFTEN_TEST(h,
> vec) \ lbz
> r10,PACASOFTIRQEN(r13); \
> cmpwi
> r10,LAZY_INTERRUPT_DISABLED; \
> li
> r10,SOFTEN_VALUE_##vec; \
> - bge masked_##h##interrupt
At which point, can't we pass in the interrupt level we want to mask
for to SOFTEN_TEST, and avoid all this extra code changes?
PMU masked interrupt will compare with SOFTEN_LEVEL_PMU, existing
interrupts will compare with SOFTEN_LEVEL_EE (or whatever suitable
names there are).
> + mflr
> r11; \
> + bgel
> masked_##h##interrupt; \
> + mtlr r11;
This might corrupt return prediction when masked_interrupt does not
return. I guess that's uncommon case though. But I think we can avoid
this if we do the above, no?
Thanks,
Nick
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 8/9] powerpc: Support to replay PMIs
2016-07-25 14:52 ` [RFC PATCH 8/9] powerpc: Support to replay PMIs Madhavan Srinivasan
@ 2016-07-26 5:50 ` Nicholas Piggin
2016-07-26 6:40 ` Madhavan Srinivasan
0 siblings, 1 reply; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 5:50 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Mon, 25 Jul 2016 20:22:21 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> Code to replay the Performance Monitoring Interrupts(PMI).
> In the masked_interrupt handler, for PMIs we reset the MSR[EE]
> and return. This is due the fact that PMIs are level triggered.
> In the __check_irq_replay(), we enabled the MSR[EE] which will
> fire the interrupt for us.
>
> Patch also adds a new arch_local_irq_disable_var() variant. New
> variant takes an input value to write to the paca->soft_enabled.
> This will be used in following patch to implement the tri-state
> value for soft-enabled.
Same comment also applies about patches being standalone
transformations that work before and after. Some of these
can be squashed together I think.
> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/hw_irq.h | 14 ++++++++++++++
> arch/powerpc/kernel/irq.c | 9 ++++++++-
> 2 files changed, 22 insertions(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/include/asm/hw_irq.h
> b/arch/powerpc/include/asm/hw_irq.h index cc69dde6eb84..863179654452
> 100644 --- a/arch/powerpc/include/asm/hw_irq.h
> +++ b/arch/powerpc/include/asm/hw_irq.h
> @@ -81,6 +81,20 @@ static inline unsigned long
> arch_local_irq_disable(void) return flags;
> }
>
> +static inline unsigned long arch_local_irq_disable_var(int value)
> +{
> + unsigned long flags, zero;
> +
> + asm volatile(
> + "li %1,%3; lbz %0,%2(13); stb %1,%2(13)"
> + : "=r" (flags), "=&r" (zero)
> + : "i" (offsetof(struct paca_struct, soft_enabled)),\
> + "i" (value)
> + : "memory");
> +
> + return flags;
> +}
arch_ function suggests it is arch implementation of a generic
kernel function or something. I think our soft interrupt levels
are just used in powerpc specific code.
The name could also be a little more descriptive.
I would have our internal function be something like
soft_irq_set_level(), and then the arch disable just sets to
the appropriate level as it does today.
The PMU disable level could be implemented in powerpc specific
header with local_irq_and_pmu_disable() or something like that.
Thanks,
Nick
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 9/9] powerpc: rewrite local_t using soft_irq
2016-07-25 14:52 ` [RFC PATCH 9/9] powerpc: rewrite local_t using soft_irq Madhavan Srinivasan
@ 2016-07-26 5:53 ` Nicholas Piggin
2016-07-26 6:41 ` Madhavan Srinivasan
0 siblings, 1 reply; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 5:53 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Mon, 25 Jul 2016 20:22:22 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> https://lkml.org/lkml/2008/12/16/450
>
> Modifications to Rusty's benchmark code:
> - Executed only local_t test
>
> Here are the values with the patch.
>
> Time in ns per iteration
>
> Local_t Without Patch With Patch
>
> _inc 28 8
> _add 28 8
> _read 3 3
> _add_return 28 7
>
> Tested the patch in a
> - pSeries LPAR (with perf record)
Very nice. I'd like to see these patches get in. We can
probably use the feature in other places too.
Thanks,
Nick
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags
2016-07-26 5:27 ` Nicholas Piggin
@ 2016-07-26 6:05 ` Madhavan Srinivasan
2016-07-26 6:13 ` Nicholas Piggin
2016-07-28 13:54 ` Nicholas Piggin
0 siblings, 2 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-26 6:05 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tuesday 26 July 2016 10:57 AM, Nicholas Piggin wrote:
> On Mon, 25 Jul 2016 20:22:14 +0530
> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>
>> Two #defs LAZY_INTERRUPT_ENABLED and
>> LAZY_INTERRUPT_DISABLED are added to be used
>> when updating paca->soft_enabled.
> This is a very nice patchset, but can this not be a new name?
Thanks, but idea is from ben :)
Regarding the name, I looked at the initial patchset posted by
paul and took the name from it :).
But will work on that, any suggestion for the name?
Maddy
> We use "soft enabled/disabled" everywhere for it. I think lazy
> is an implementation detail anyway because some interrupts don't
> cause a hard disable at all.
>
> Thanks,
> Nick
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 5/9] powerpc: reverse the soft_enable logic
2016-07-26 5:31 ` Nicholas Piggin
@ 2016-07-26 6:07 ` Madhavan Srinivasan
0 siblings, 0 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-26 6:07 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tuesday 26 July 2016 11:01 AM, Nicholas Piggin wrote:
> On Mon, 25 Jul 2016 20:22:18 +0530
> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>
>> "paca->soft_enabled" is used as a flag to mask some of interrupts.
>> Currently supported flags values and their details:
>>
>> soft_enabled MSR[EE]
>>
>> 0 0 Disabled (PMI and HMI not masked)
>> 1 1 Enabled
>>
>> "paca->soft_enabled" is initialed to 1 to make the interripts as
>> enabled. arch_local_irq_disable() will toggle the value when
>> interrupts needs to disbled. At this point, the interrupts are not
>> actually disabled, instead, interrupt vector has code to check for
>> the flag and mask it when it occurs. By "mask it", it updated
>> interrupt paca->irq_happened and return. arch_local_irq_restore() is
>> called to re-enable interrupts, which checks and replays interrupts
>> if any occured.
>>
>> Now, as mentioned, current logic doesnot mask "performance monitoring
>> interrupts" and PMIs are implemented as NMI. But this patchset
>> depends on local_irq_* for a successful local_* update. Meaning, mask
>> all possible interrupts during local_* update and replay them after
>> the update.
>>
>> So the idea here is to reserve the "paca->soft_enabled" logic. New
>> values and details:
>>
>> soft_enabled MSR[EE]
>>
>> 1 0 Disabled (PMI and HMI not masked)
>> 0 1 Enabled
>>
>> Reason for the this change is to create foundation for a third flag
>> value "2" for "soft_enabled" to add support to mask PMIs. When
>> arch_irq_disable_* is called with a value "2", PMI interrupts are
>> mask. But when called with a value of "1", PMI are not mask.
>>
>> With new flag value for "soft_enabled", states looks like:
>>
>> soft_enabled MSR[EE]
>>
>> 2 0 Disbaled PMIs also
>> 1 0 Disabled (PMI and HMI not masked)
>> 0 1 Enabled
>>
>> And interrupt handler code for checking has been modified to check for
>> for "greater than or equal" to 1 condition instead.
> This bit of the patch seems to have been moved into other part
> of the series. Ideally (unless there is a good reason), it is nice
> to have each individual patch result in a working kernel before
> and after.
Agreed. But I need to reason out the change and hence add
all info here. But will edit the info in the next version.
Maddy
>
> Nice way to avoid adding more branches though.
>
> Thanks,
> Nick
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 6/9] powerpc: modify __SOFTEN_TEST to support tri-state soft_enabled flag
2016-07-26 5:41 ` Nicholas Piggin
@ 2016-07-26 6:12 ` Madhavan Srinivasan
0 siblings, 0 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-26 6:12 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tuesday 26 July 2016 11:11 AM, Nicholas Piggin wrote:
> On Mon, 25 Jul 2016 20:22:19 +0530
> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>
>> Foundation patch to support checking of new flag for
>> "paca->soft_enabled". Modify the condition checking for the
>> "soft_enabled" from "equal" to "greater than or equal to".
> Rather than a "tri-state" and the mystery "2" state, can you
> make a #define for that guy, and use levels.
Yes. Will do. Will wait for any feedback on the macro name
for the patch 1 of this series.
Maddy
> 0-> all enabled
> 1-> "linux" interrupts disabled
> 2-> PMU also disabled
> etc.
>
> Thanks,
> Nick
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags
2016-07-26 6:05 ` Madhavan Srinivasan
@ 2016-07-26 6:13 ` Nicholas Piggin
2016-07-28 13:54 ` Nicholas Piggin
1 sibling, 0 replies; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 6:13 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tue, 26 Jul 2016 11:35:16 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> On Tuesday 26 July 2016 10:57 AM, Nicholas Piggin wrote:
> > On Mon, 25 Jul 2016 20:22:14 +0530
> > Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> >
> >> Two #defs LAZY_INTERRUPT_ENABLED and
> >> LAZY_INTERRUPT_DISABLED are added to be used
> >> when updating paca->soft_enabled.
> > This is a very nice patchset, but can this not be a new name?
>
> Thanks, but idea is from ben :)
> Regarding the name, I looked at the initial patchset posted by
> paul and took the name from it :).
>
> But will work on that, any suggestion for the name?
I don't have a strong preference. LAZY_* is not horrible itself,
it's just that softe variant is used elsewhere. I don't mind if
you rename softe to something else completely (although Ben might).
Allow me to apply the first coat of paint to the bikeshed:
irq_disable_level
IRQ_DISABLE_LEVEL_NONE
IRQ_DISABLE_LEVEL_LINUX
IRQ_DISABLE_LEVEL_PMU
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts
2016-07-26 5:46 ` Nicholas Piggin
@ 2016-07-26 6:25 ` Madhavan Srinivasan
2016-07-26 6:30 ` Nicholas Piggin
0 siblings, 1 reply; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-26 6:25 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tuesday 26 July 2016 11:16 AM, Nicholas Piggin wrote:
> On Mon, 25 Jul 2016 20:22:20 +0530
> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>
>> To support masking of the PMI interrupts, couple of new interrupt
>> handler macros are added MASKABLE_EXCEPTION_PSERIES_OOL and
>> MASKABLE_RELON_EXCEPTION_PSERIES_OOL. These are needed to include the
>> SOFTEN_TEST and implement the support at both host and guest kernel.
>>
>> Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*" added
>> to use in the exception code to check for PMI interrupts.
>>
>> __SOFTEN_TEST macro is modified to support the PMI interrupt.
>> Present __SOFTEN_TEST code loads the soft_enabled from paca and check
>> to call masked_interrupt handler code. To support both current
>> behaviour and PMI masking, these changes are added,
>>
>> 1) Current LR register content are saved in R11
>> 2) "bge" branch operation is changed to "bgel".
>> 3) restore R11 to LR
>>
>> Reason:
>>
>> To retain PMI as NMI behaviour for flag state of 1, we save the LR
>> regsiter value in R11 and branch to "masked_interrupt" handler with
>> LR update. And in "masked_interrupt" handler, we check for the
>> "SOFTEN_VALUE_*" value in R10 for PMI and branch back with "blr" if
>> PMI.
>>
>> To mask PMI for a flag >1 value, masked_interrupt vaoid's the above
>> check and continue to execute the masked_interrupt code and disabled
>> MSR[EE] and updated the irq_happend with PMI info.
>>
>> Finally, saving of R11 is moved before calling SOFTEN_TEST in the
>> __EXCEPTION_PROLOG_1 macro to support saving of LR values in
>> SOFTEN_TEST.
>>
>> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
>> ---
>> arch/powerpc/include/asm/exception-64s.h | 22 ++++++++++++++++++++--
>> arch/powerpc/include/asm/hw_irq.h | 1 +
>> arch/powerpc/kernel/exceptions-64s.S | 27
>> ++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 5
>> deletions(-)
>>
>> diff --git a/arch/powerpc/include/asm/exception-64s.h
>> b/arch/powerpc/include/asm/exception-64s.h index
>> 44d3f539d8a5..c951b7ab5108 100644 ---
>> a/arch/powerpc/include/asm/exception-64s.h +++
>> b/arch/powerpc/include/asm/exception-64s.h @@ -166,8 +166,8 @@
>> END_FTR_SECTION_NESTED(ftr,ftr,943)
>> OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);
>> \ SAVE_CTR(r10, area);
>> \ mfcr
>> r9; \
>> -
>> extra(vec); \
>> std
>> r11,area+EX_R11(r13); \
>> +
>> extra(vec); \
>> std
>> r12,area+EX_R12(r13); \
>> GET_SCRATCH0(r10); \
>> std r10,area+EX_R13(r13) @@ -403,12 +403,17 @@
>> label##_relon_hv: \
>> #define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL #define
>> SOFTEN_VALUE_0xe60 PACA_IRQ_HMI #define
>> SOFTEN_VALUE_0xe62 PACA_IRQ_HMI +#define
>> SOFTEN_VALUE_0xf01 PACA_IRQ_PMI +#define
>> SOFTEN_VALUE_0xf00 PACA_IRQ_PMI
> #define __SOFTEN_TEST(h,
>> vec) \ lbz
>> r10,PACASOFTIRQEN(r13); \
>> cmpwi
>> r10,LAZY_INTERRUPT_DISABLED; \
>> li
>> r10,SOFTEN_VALUE_##vec; \
>> - bge masked_##h##interrupt
> At which point, can't we pass in the interrupt level we want to mask
> for to SOFTEN_TEST, and avoid all this extra code changes?
IIUC, we do pass the interrupt info to SOFTEN_TEST. Incase of
PMU interrupt we will have the value as PACA_IRQ_PMI.
>
>
> PMU masked interrupt will compare with SOFTEN_LEVEL_PMU, existing
> interrupts will compare with SOFTEN_LEVEL_EE (or whatever suitable
> names there are).
>
>
>> + mflr
>> r11; \
>> + bgel
>> masked_##h##interrupt; \
>> + mtlr r11;
> This might corrupt return prediction when masked_interrupt does not
Hmm this is a valid point.
> return. I guess that's uncommon case though.
No, it is. kernel mostly use irq_disable with (1) today and only in
specific case
we disable all the interrupts. So we are going to return almost always
when irqs are
soft diabled.
Since we need to support the PMIs as NMI when irq disable level is 1,
we need to skip masked_interrupt.
As you mentioned if we have a separate macro (SOFTEN_TEST_PMU),
these can be avoided, but then it is code replication and we may need
to change some more macros. But this interesting, let me work on this.
Maddy
> But I think we can avoid
> this if we do the above, no?
>
> Thanks,
> Nick
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts
2016-07-26 6:25 ` Madhavan Srinivasan
@ 2016-07-26 6:30 ` Nicholas Piggin
2016-07-26 6:46 ` Madhavan Srinivasan
0 siblings, 1 reply; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 6:30 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tue, 26 Jul 2016 11:55:51 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> On Tuesday 26 July 2016 11:16 AM, Nicholas Piggin wrote:
> > On Mon, 25 Jul 2016 20:22:20 +0530
> > Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> >
> >> To support masking of the PMI interrupts, couple of new interrupt
> >> handler macros are added MASKABLE_EXCEPTION_PSERIES_OOL and
> >> MASKABLE_RELON_EXCEPTION_PSERIES_OOL. These are needed to include
> >> the SOFTEN_TEST and implement the support at both host and guest
> >> kernel.
> >>
> >> Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*"
> >> added to use in the exception code to check for PMI interrupts.
> >>
> >> __SOFTEN_TEST macro is modified to support the PMI interrupt.
> >> Present __SOFTEN_TEST code loads the soft_enabled from paca and
> >> check to call masked_interrupt handler code. To support both
> >> current behaviour and PMI masking, these changes are added,
> >>
> >> 1) Current LR register content are saved in R11
> >> 2) "bge" branch operation is changed to "bgel".
> >> 3) restore R11 to LR
> >>
> >> Reason:
> >>
> >> To retain PMI as NMI behaviour for flag state of 1, we save the LR
> >> regsiter value in R11 and branch to "masked_interrupt" handler with
> >> LR update. And in "masked_interrupt" handler, we check for the
> >> "SOFTEN_VALUE_*" value in R10 for PMI and branch back with "blr" if
> >> PMI.
> >>
> >> To mask PMI for a flag >1 value, masked_interrupt vaoid's the above
> >> check and continue to execute the masked_interrupt code and
> >> disabled MSR[EE] and updated the irq_happend with PMI info.
> >>
> >> Finally, saving of R11 is moved before calling SOFTEN_TEST in the
> >> __EXCEPTION_PROLOG_1 macro to support saving of LR values in
> >> SOFTEN_TEST.
> >>
> >> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> >> ---
> >> arch/powerpc/include/asm/exception-64s.h | 22
> >> ++++++++++++++++++++-- arch/powerpc/include/asm/hw_irq.h |
> >> 1 + arch/powerpc/kernel/exceptions-64s.S | 27
> >> ++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 5
> >> deletions(-)
> >>
> >> diff --git a/arch/powerpc/include/asm/exception-64s.h
> >> b/arch/powerpc/include/asm/exception-64s.h index
> >> 44d3f539d8a5..c951b7ab5108 100644 ---
> >> a/arch/powerpc/include/asm/exception-64s.h +++
> >> b/arch/powerpc/include/asm/exception-64s.h @@ -166,8 +166,8 @@
> >> END_FTR_SECTION_NESTED(ftr,ftr,943)
> >> OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);
> >> \ SAVE_CTR(r10, area);
> >> \ mfcr
> >> r9; \
> >> -
> >> extra(vec);
> >> \ std
> >> r11,area+EX_R11(r13); \
> >> +
> >> extra(vec);
> >> \ std
> >> r12,area+EX_R12(r13); \
> >> GET_SCRATCH0(r10); \
> >> std r10,area+EX_R13(r13) @@ -403,12 +403,17 @@
> >> label##_relon_hv: \
> >> #define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL #define
> >> SOFTEN_VALUE_0xe60 PACA_IRQ_HMI #define
> >> SOFTEN_VALUE_0xe62 PACA_IRQ_HMI +#define
> >> SOFTEN_VALUE_0xf01 PACA_IRQ_PMI +#define
> >> SOFTEN_VALUE_0xf00 PACA_IRQ_PMI
> > #define __SOFTEN_TEST(h,
> >> vec) \ lbz
> >> r10,PACASOFTIRQEN(r13); \
> >> cmpwi
> >> r10,LAZY_INTERRUPT_DISABLED; \
> >> li
> >> r10,SOFTEN_VALUE_##vec; \
> >> - bge masked_##h##interrupt
> > At which point, can't we pass in the interrupt level we want to mask
> > for to SOFTEN_TEST, and avoid all this extra code changes?
> IIUC, we do pass the interrupt info to SOFTEN_TEST. Incase of
> PMU interrupt we will have the value as PACA_IRQ_PMI.
>
>
> >
> >
> > PMU masked interrupt will compare with SOFTEN_LEVEL_PMU, existing
> > interrupts will compare with SOFTEN_LEVEL_EE (or whatever suitable
> > names there are).
> >
> >
> >> + mflr
> >> r11; \
> >> + bgel
> >> masked_##h##interrupt; \
> >> + mtlr r11;
> > This might corrupt return prediction when masked_interrupt does
> > not
> Hmm this is a valid point.
>
> > return. I guess that's uncommon case though.
>
> No, it is. kernel mostly use irq_disable with (1) today and only in
> specific case
> we disable all the interrupts. So we are going to return almost
> always when irqs are
> soft diabled.
>
> Since we need to support the PMIs as NMI when irq disable level is 1,
> we need to skip masked_interrupt.
>
> As you mentioned if we have a separate macro (SOFTEN_TEST_PMU),
> these can be avoided, but then it is code replication and we may need
> to change some more macros. But this interesting, let me work on this.
I would really prefer to do that, even if it means a little more code.
Another option is to give an additional parameter to the MASKABLE
variants of the exception handlers, which you can pass in the
"mask level" into. I think it's not a bad idea to make it explicit
even for the existing ones so it's clear which level they are masked
at.
Thanks,
Nick
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 8/9] powerpc: Support to replay PMIs
2016-07-26 5:50 ` Nicholas Piggin
@ 2016-07-26 6:40 ` Madhavan Srinivasan
0 siblings, 0 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-26 6:40 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tuesday 26 July 2016 11:20 AM, Nicholas Piggin wrote:
> On Mon, 25 Jul 2016 20:22:21 +0530
> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>
>> Code to replay the Performance Monitoring Interrupts(PMI).
>> In the masked_interrupt handler, for PMIs we reset the MSR[EE]
>> and return. This is due the fact that PMIs are level triggered.
>> In the __check_irq_replay(), we enabled the MSR[EE] which will
>> fire the interrupt for us.
>>
>> Patch also adds a new arch_local_irq_disable_var() variant. New
>> variant takes an input value to write to the paca->soft_enabled.
>> This will be used in following patch to implement the tri-state
>> value for soft-enabled.
> Same comment also applies about patches being standalone
> transformations that work before and after. Some of these
> can be squashed together I think.
Sure.
>
>
>> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
>> ---
>> arch/powerpc/include/asm/hw_irq.h | 14 ++++++++++++++
>> arch/powerpc/kernel/irq.c | 9 ++++++++-
>> 2 files changed, 22 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/powerpc/include/asm/hw_irq.h
>> b/arch/powerpc/include/asm/hw_irq.h index cc69dde6eb84..863179654452
>> 100644 --- a/arch/powerpc/include/asm/hw_irq.h
>> +++ b/arch/powerpc/include/asm/hw_irq.h
>> @@ -81,6 +81,20 @@ static inline unsigned long
>> arch_local_irq_disable(void) return flags;
>> }
>>
>> +static inline unsigned long arch_local_irq_disable_var(int value)
>> +{
>> + unsigned long flags, zero;
>> +
>> + asm volatile(
>> + "li %1,%3; lbz %0,%2(13); stb %1,%2(13)"
>> + : "=r" (flags), "=&r" (zero)
>> + : "i" (offsetof(struct paca_struct, soft_enabled)),\
>> + "i" (value)
>> + : "memory");
>> +
>> + return flags;
>> +}
> arch_ function suggests it is arch implementation of a generic
> kernel function or something. I think our soft interrupt levels
> are just used in powerpc specific code.
>
> The name could also be a little more descriptive.
>
> I would have our internal function be something like
>
> soft_irq_set_level(), and then the arch disable just sets to
> the appropriate level as it does today.
>
> The PMU disable level could be implemented in powerpc specific
> header with local_irq_and_pmu_disable() or something like that.
Yes. will do.
>
> Thanks,
> Nick
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 9/9] powerpc: rewrite local_t using soft_irq
2016-07-26 5:53 ` Nicholas Piggin
@ 2016-07-26 6:41 ` Madhavan Srinivasan
0 siblings, 0 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-26 6:41 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tuesday 26 July 2016 11:23 AM, Nicholas Piggin wrote:
> On Mon, 25 Jul 2016 20:22:22 +0530
> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>
>> https://lkml.org/lkml/2008/12/16/450
>>
>> Modifications to Rusty's benchmark code:
>> - Executed only local_t test
>>
>> Here are the values with the patch.
>>
>> Time in ns per iteration
>>
>> Local_t Without Patch With Patch
>>
>> _inc 28 8
>> _add 28 8
>> _read 3 3
>> _add_return 28 7
>>
>> Tested the patch in a
>> - pSeries LPAR (with perf record)
> Very nice. I'd like to see these patches get in. We can
> probably use the feature in other places too.
Thanks for review.
Maddy
> Thanks,
> Nick
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts
2016-07-26 6:30 ` Nicholas Piggin
@ 2016-07-26 6:46 ` Madhavan Srinivasan
2016-07-26 7:10 ` Nicholas Piggin
0 siblings, 1 reply; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-26 6:46 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tuesday 26 July 2016 12:00 PM, Nicholas Piggin wrote:
> On Tue, 26 Jul 2016 11:55:51 +0530
> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>
>> On Tuesday 26 July 2016 11:16 AM, Nicholas Piggin wrote:
>>> On Mon, 25 Jul 2016 20:22:20 +0530
>>> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>>>
>>>> To support masking of the PMI interrupts, couple of new interrupt
>>>> handler macros are added MASKABLE_EXCEPTION_PSERIES_OOL and
>>>> MASKABLE_RELON_EXCEPTION_PSERIES_OOL. These are needed to include
>>>> the SOFTEN_TEST and implement the support at both host and guest
>>>> kernel.
>>>>
>>>> Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*"
>>>> added to use in the exception code to check for PMI interrupts.
>>>>
>>>> __SOFTEN_TEST macro is modified to support the PMI interrupt.
>>>> Present __SOFTEN_TEST code loads the soft_enabled from paca and
>>>> check to call masked_interrupt handler code. To support both
>>>> current behaviour and PMI masking, these changes are added,
>>>>
>>>> 1) Current LR register content are saved in R11
>>>> 2) "bge" branch operation is changed to "bgel".
>>>> 3) restore R11 to LR
>>>>
>>>> Reason:
>>>>
>>>> To retain PMI as NMI behaviour for flag state of 1, we save the LR
>>>> regsiter value in R11 and branch to "masked_interrupt" handler with
>>>> LR update. And in "masked_interrupt" handler, we check for the
>>>> "SOFTEN_VALUE_*" value in R10 for PMI and branch back with "blr" if
>>>> PMI.
>>>>
>>>> To mask PMI for a flag >1 value, masked_interrupt vaoid's the above
>>>> check and continue to execute the masked_interrupt code and
>>>> disabled MSR[EE] and updated the irq_happend with PMI info.
>>>>
>>>> Finally, saving of R11 is moved before calling SOFTEN_TEST in the
>>>> __EXCEPTION_PROLOG_1 macro to support saving of LR values in
>>>> SOFTEN_TEST.
>>>>
>>>> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
>>>> ---
>>>> arch/powerpc/include/asm/exception-64s.h | 22
>>>> ++++++++++++++++++++-- arch/powerpc/include/asm/hw_irq.h |
>>>> 1 + arch/powerpc/kernel/exceptions-64s.S | 27
>>>> ++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 5
>>>> deletions(-)
>>>>
>>>> diff --git a/arch/powerpc/include/asm/exception-64s.h
>>>> b/arch/powerpc/include/asm/exception-64s.h index
>>>> 44d3f539d8a5..c951b7ab5108 100644 ---
>>>> a/arch/powerpc/include/asm/exception-64s.h +++
>>>> b/arch/powerpc/include/asm/exception-64s.h @@ -166,8 +166,8 @@
>>>> END_FTR_SECTION_NESTED(ftr,ftr,943)
>>>> OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);
>>>> \ SAVE_CTR(r10, area);
>>>> \ mfcr
>>>> r9; \
>>>> -
>>>> extra(vec);
>>>> \ std
>>>> r11,area+EX_R11(r13); \
>>>> +
>>>> extra(vec);
>>>> \ std
>>>> r12,area+EX_R12(r13); \
>>>> GET_SCRATCH0(r10); \
>>>> std r10,area+EX_R13(r13) @@ -403,12 +403,17 @@
>>>> label##_relon_hv: \
>>>> #define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL #define
>>>> SOFTEN_VALUE_0xe60 PACA_IRQ_HMI #define
>>>> SOFTEN_VALUE_0xe62 PACA_IRQ_HMI +#define
>>>> SOFTEN_VALUE_0xf01 PACA_IRQ_PMI +#define
>>>> SOFTEN_VALUE_0xf00 PACA_IRQ_PMI
>>> #define __SOFTEN_TEST(h,
>>>> vec) \ lbz
>>>> r10,PACASOFTIRQEN(r13); \
>>>> cmpwi
>>>> r10,LAZY_INTERRUPT_DISABLED; \
>>>> li
>>>> r10,SOFTEN_VALUE_##vec; \
>>>> - bge masked_##h##interrupt
>>> At which point, can't we pass in the interrupt level we want to mask
>>> for to SOFTEN_TEST, and avoid all this extra code changes?
>> IIUC, we do pass the interrupt info to SOFTEN_TEST. Incase of
>> PMU interrupt we will have the value as PACA_IRQ_PMI.
>>
>>
>>>
>>> PMU masked interrupt will compare with SOFTEN_LEVEL_PMU, existing
>>> interrupts will compare with SOFTEN_LEVEL_EE (or whatever suitable
>>> names there are).
>>>
>>>
>>>> + mflr
>>>> r11; \
>>>> + bgel
>>>> masked_##h##interrupt; \
>>>> + mtlr r11;
>>> This might corrupt return prediction when masked_interrupt does
>>> not
>> Hmm this is a valid point.
>>
>>> return. I guess that's uncommon case though.
>> No, it is. kernel mostly use irq_disable with (1) today and only in
>> specific case
>> we disable all the interrupts. So we are going to return almost
>> always when irqs are
>> soft diabled.
>>
>> Since we need to support the PMIs as NMI when irq disable level is 1,
>> we need to skip masked_interrupt.
>>
>> As you mentioned if we have a separate macro (SOFTEN_TEST_PMU),
>> these can be avoided, but then it is code replication and we may need
>> to change some more macros. But this interesting, let me work on this.
> I would really prefer to do that, even if it means a little more code.
>
> Another option is to give an additional parameter to the MASKABLE
> variants of the exception handlers, which you can pass in the
> "mask level" into. I think it's not a bad idea to make it explicit
> even for the existing ones so it's clear which level they are masked
> at.
Issue here is that mask_interrupt function is not part of the
interrupt vector code (__EXCEPTION_PROLOG_1). So incase of PMI,
if we enter the mask_interrupt function, we need to know where
to return to continue incase of NMI.
Maddy
>
> Thanks,
> Nick
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts
2016-07-26 6:46 ` Madhavan Srinivasan
@ 2016-07-26 7:10 ` Nicholas Piggin
2016-07-26 7:22 ` Madhavan Srinivasan
0 siblings, 1 reply; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 7:10 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tue, 26 Jul 2016 12:16:32 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> On Tuesday 26 July 2016 12:00 PM, Nicholas Piggin wrote:
> > On Tue, 26 Jul 2016 11:55:51 +0530
> > Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> >
> >> On Tuesday 26 July 2016 11:16 AM, Nicholas Piggin wrote:
> >>> On Mon, 25 Jul 2016 20:22:20 +0530
> >>> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> >>>
> >>>> To support masking of the PMI interrupts, couple of new interrupt
> >>>> handler macros are added MASKABLE_EXCEPTION_PSERIES_OOL and
> >>>> MASKABLE_RELON_EXCEPTION_PSERIES_OOL. These are needed to include
> >>>> the SOFTEN_TEST and implement the support at both host and guest
> >>>> kernel.
> >>>>
> >>>> Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*"
> >>>> added to use in the exception code to check for PMI interrupts.
> >>>>
> >>>> __SOFTEN_TEST macro is modified to support the PMI interrupt.
> >>>> Present __SOFTEN_TEST code loads the soft_enabled from paca and
> >>>> check to call masked_interrupt handler code. To support both
> >>>> current behaviour and PMI masking, these changes are added,
> >>>>
> >>>> 1) Current LR register content are saved in R11
> >>>> 2) "bge" branch operation is changed to "bgel".
> >>>> 3) restore R11 to LR
> >>>>
> >>>> Reason:
> >>>>
> >>>> To retain PMI as NMI behaviour for flag state of 1, we save the
> >>>> LR regsiter value in R11 and branch to "masked_interrupt"
> >>>> handler with LR update. And in "masked_interrupt" handler, we
> >>>> check for the "SOFTEN_VALUE_*" value in R10 for PMI and branch
> >>>> back with "blr" if PMI.
> >>>>
> >>>> To mask PMI for a flag >1 value, masked_interrupt vaoid's the
> >>>> above check and continue to execute the masked_interrupt code and
> >>>> disabled MSR[EE] and updated the irq_happend with PMI info.
> >>>>
> >>>> Finally, saving of R11 is moved before calling SOFTEN_TEST in the
> >>>> __EXCEPTION_PROLOG_1 macro to support saving of LR values in
> >>>> SOFTEN_TEST.
> >>>>
> >>>> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> >>>> ---
> >>>> arch/powerpc/include/asm/exception-64s.h | 22
> >>>> ++++++++++++++++++++-- arch/powerpc/include/asm/hw_irq.h |
> >>>> 1 + arch/powerpc/kernel/exceptions-64s.S | 27
> >>>> ++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 5
> >>>> deletions(-)
> >>>>
> >>>> diff --git a/arch/powerpc/include/asm/exception-64s.h
> >>>> b/arch/powerpc/include/asm/exception-64s.h index
> >>>> 44d3f539d8a5..c951b7ab5108 100644 ---
> >>>> a/arch/powerpc/include/asm/exception-64s.h +++
> >>>> b/arch/powerpc/include/asm/exception-64s.h @@ -166,8 +166,8 @@
> >>>> END_FTR_SECTION_NESTED(ftr,ftr,943)
> >>>> OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);
> >>>> \ SAVE_CTR(r10, area);
> >>>> \ mfcr
> >>>> r9; \
> >>>> -
> >>>> extra(vec);
> >>>> \ std
> >>>> r11,area+EX_R11(r13); \
> >>>> +
> >>>> extra(vec);
> >>>> \ std
> >>>> r12,area+EX_R12(r13); \
> >>>> GET_SCRATCH0(r10);
> >>>> \ std r10,area+EX_R13(r13) @@ -403,12 +403,17 @@
> >>>> label##_relon_hv:
> >>>> \ #define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL #define
> >>>> SOFTEN_VALUE_0xe60 PACA_IRQ_HMI #define
> >>>> SOFTEN_VALUE_0xe62 PACA_IRQ_HMI +#define
> >>>> SOFTEN_VALUE_0xf01 PACA_IRQ_PMI +#define
> >>>> SOFTEN_VALUE_0xf00 PACA_IRQ_PMI
> >>> #define __SOFTEN_TEST(h,
> >>>> vec) \ lbz
> >>>> r10,PACASOFTIRQEN(r13); \
> >>>> cmpwi
> >>>> r10,LAZY_INTERRUPT_DISABLED; \
> >>>> li
> >>>> r10,SOFTEN_VALUE_##vec; \
> >>>> - bge masked_##h##interrupt
> >>> At which point, can't we pass in the interrupt level we want to
> >>> mask for to SOFTEN_TEST, and avoid all this extra code changes?
> >> IIUC, we do pass the interrupt info to SOFTEN_TEST. Incase of
> >> PMU interrupt we will have the value as PACA_IRQ_PMI.
> >>
> >>
> >>>
> >>> PMU masked interrupt will compare with SOFTEN_LEVEL_PMU, existing
> >>> interrupts will compare with SOFTEN_LEVEL_EE (or whatever suitable
> >>> names there are).
> >>>
> >>>
> >>>> + mflr
> >>>> r11; \
> >>>> + bgel
> >>>> masked_##h##interrupt; \
> >>>> + mtlr r11;
> >>> This might corrupt return prediction when masked_interrupt does
> >>> not
> >> Hmm this is a valid point.
> >>
> >>> return. I guess that's uncommon case though.
> >> No, it is. kernel mostly use irq_disable with (1) today and only in
> >> specific case
> >> we disable all the interrupts. So we are going to return almost
> >> always when irqs are
> >> soft diabled.
> >>
> >> Since we need to support the PMIs as NMI when irq disable level is
> >> 1, we need to skip masked_interrupt.
> >>
> >> As you mentioned if we have a separate macro (SOFTEN_TEST_PMU),
> >> these can be avoided, but then it is code replication and we may
> >> need to change some more macros. But this interesting, let me work
> >> on this.
> > I would really prefer to do that, even if it means a little more
> > code.
> >
> > Another option is to give an additional parameter to the MASKABLE
> > variants of the exception handlers, which you can pass in the
> > "mask level" into. I think it's not a bad idea to make it explicit
> > even for the existing ones so it's clear which level they are masked
> > at.
>
> Issue here is that mask_interrupt function is not part of the
> interrupt vector code (__EXCEPTION_PROLOG_1). So incase of PMI,
> if we enter the mask_interrupt function, we need to know where
> to return to continue incase of NMI.
But if you test against the PMU disabled level, then you should
not even branch to masked_interrupt handler at all if regular
interrupts are soft disabled but PMU is enabled, no?
Thanks,
Nick
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts
2016-07-26 7:10 ` Nicholas Piggin
@ 2016-07-26 7:22 ` Madhavan Srinivasan
2016-07-26 7:34 ` Nicholas Piggin
0 siblings, 1 reply; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-26 7:22 UTC (permalink / raw)
To: Nicholas Piggin; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tuesday 26 July 2016 12:40 PM, Nicholas Piggin wrote:
> On Tue, 26 Jul 2016 12:16:32 +0530
> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>
>> On Tuesday 26 July 2016 12:00 PM, Nicholas Piggin wrote:
>>> On Tue, 26 Jul 2016 11:55:51 +0530
>>> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>>>
>>>> On Tuesday 26 July 2016 11:16 AM, Nicholas Piggin wrote:
>>>>> On Mon, 25 Jul 2016 20:22:20 +0530
>>>>> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
>>>>>
>>>>>> To support masking of the PMI interrupts, couple of new interrupt
>>>>>> handler macros are added MASKABLE_EXCEPTION_PSERIES_OOL and
>>>>>> MASKABLE_RELON_EXCEPTION_PSERIES_OOL. These are needed to include
>>>>>> the SOFTEN_TEST and implement the support at both host and guest
>>>>>> kernel.
>>>>>>
>>>>>> Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*"
>>>>>> added to use in the exception code to check for PMI interrupts.
>>>>>>
>>>>>> __SOFTEN_TEST macro is modified to support the PMI interrupt.
>>>>>> Present __SOFTEN_TEST code loads the soft_enabled from paca and
>>>>>> check to call masked_interrupt handler code. To support both
>>>>>> current behaviour and PMI masking, these changes are added,
>>>>>>
>>>>>> 1) Current LR register content are saved in R11
>>>>>> 2) "bge" branch operation is changed to "bgel".
>>>>>> 3) restore R11 to LR
>>>>>>
>>>>>> Reason:
>>>>>>
>>>>>> To retain PMI as NMI behaviour for flag state of 1, we save the
>>>>>> LR regsiter value in R11 and branch to "masked_interrupt"
>>>>>> handler with LR update. And in "masked_interrupt" handler, we
>>>>>> check for the "SOFTEN_VALUE_*" value in R10 for PMI and branch
>>>>>> back with "blr" if PMI.
>>>>>>
>>>>>> To mask PMI for a flag >1 value, masked_interrupt vaoid's the
>>>>>> above check and continue to execute the masked_interrupt code and
>>>>>> disabled MSR[EE] and updated the irq_happend with PMI info.
>>>>>>
>>>>>> Finally, saving of R11 is moved before calling SOFTEN_TEST in the
>>>>>> __EXCEPTION_PROLOG_1 macro to support saving of LR values in
>>>>>> SOFTEN_TEST.
>>>>>>
>>>>>> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
>>>>>> ---
>>>>>> arch/powerpc/include/asm/exception-64s.h | 22
>>>>>> ++++++++++++++++++++-- arch/powerpc/include/asm/hw_irq.h |
>>>>>> 1 + arch/powerpc/kernel/exceptions-64s.S | 27
>>>>>> ++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 5
>>>>>> deletions(-)
>>>>>>
>>>>>> diff --git a/arch/powerpc/include/asm/exception-64s.h
>>>>>> b/arch/powerpc/include/asm/exception-64s.h index
>>>>>> 44d3f539d8a5..c951b7ab5108 100644 ---
>>>>>> a/arch/powerpc/include/asm/exception-64s.h +++
>>>>>> b/arch/powerpc/include/asm/exception-64s.h @@ -166,8 +166,8 @@
>>>>>> END_FTR_SECTION_NESTED(ftr,ftr,943)
>>>>>> OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);
>>>>>> \ SAVE_CTR(r10, area);
>>>>>> \ mfcr
>>>>>> r9; \
>>>>>> -
>>>>>> extra(vec);
>>>>>> \ std
>>>>>> r11,area+EX_R11(r13); \
>>>>>> +
>>>>>> extra(vec);
>>>>>> \ std
>>>>>> r12,area+EX_R12(r13); \
>>>>>> GET_SCRATCH0(r10);
>>>>>> \ std r10,area+EX_R13(r13) @@ -403,12 +403,17 @@
>>>>>> label##_relon_hv:
>>>>>> \ #define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL #define
>>>>>> SOFTEN_VALUE_0xe60 PACA_IRQ_HMI #define
>>>>>> SOFTEN_VALUE_0xe62 PACA_IRQ_HMI +#define
>>>>>> SOFTEN_VALUE_0xf01 PACA_IRQ_PMI +#define
>>>>>> SOFTEN_VALUE_0xf00 PACA_IRQ_PMI
>>>>> #define __SOFTEN_TEST(h,
>>>>>> vec) \ lbz
>>>>>> r10,PACASOFTIRQEN(r13); \
>>>>>> cmpwi
>>>>>> r10,LAZY_INTERRUPT_DISABLED; \
>>>>>> li
>>>>>> r10,SOFTEN_VALUE_##vec; \
>>>>>> - bge masked_##h##interrupt
>>>>> At which point, can't we pass in the interrupt level we want to
>>>>> mask for to SOFTEN_TEST, and avoid all this extra code changes?
>>>> IIUC, we do pass the interrupt info to SOFTEN_TEST. Incase of
>>>> PMU interrupt we will have the value as PACA_IRQ_PMI.
>>>>
>>>>
>>>>> PMU masked interrupt will compare with SOFTEN_LEVEL_PMU, existing
>>>>> interrupts will compare with SOFTEN_LEVEL_EE (or whatever suitable
>>>>> names there are).
>>>>>
>>>>>
>>>>>> + mflr
>>>>>> r11; \
>>>>>> + bgel
>>>>>> masked_##h##interrupt; \
>>>>>> + mtlr r11;
>>>>> This might corrupt return prediction when masked_interrupt does
>>>>> not
>>>> Hmm this is a valid point.
>>>>
>>>>> return. I guess that's uncommon case though.
>>>> No, it is. kernel mostly use irq_disable with (1) today and only in
>>>> specific case
>>>> we disable all the interrupts. So we are going to return almost
>>>> always when irqs are
>>>> soft diabled.
>>>>
>>>> Since we need to support the PMIs as NMI when irq disable level is
>>>> 1, we need to skip masked_interrupt.
>>>>
>>>> As you mentioned if we have a separate macro (SOFTEN_TEST_PMU),
>>>> these can be avoided, but then it is code replication and we may
>>>> need to change some more macros. But this interesting, let me work
>>>> on this.
>>> I would really prefer to do that, even if it means a little more
>>> code.
>>>
>>> Another option is to give an additional parameter to the MASKABLE
>>> variants of the exception handlers, which you can pass in the
>>> "mask level" into. I think it's not a bad idea to make it explicit
>>> even for the existing ones so it's clear which level they are masked
>>> at.
>> Issue here is that mask_interrupt function is not part of the
>> interrupt vector code (__EXCEPTION_PROLOG_1). So incase of PMI,
>> if we enter the mask_interrupt function, we need to know where
>> to return to continue incase of NMI.
> But if you test against the PMU disabled level, then you should
> not even branch to masked_interrupt handler at all if regular
> interrupts are soft disabled but PMU is enabled, no?
Yes true. We can do this in SOFTEN_ itself and I did try that,
but then we have issue of space in the vector code. I will
try it again.
Maddy
>
> Thanks,
> Nick
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts
2016-07-26 7:22 ` Madhavan Srinivasan
@ 2016-07-26 7:34 ` Nicholas Piggin
0 siblings, 0 replies; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-26 7:34 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tue, 26 Jul 2016 12:52:02 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> On Tuesday 26 July 2016 12:40 PM, Nicholas Piggin wrote:
> > On Tue, 26 Jul 2016 12:16:32 +0530
> > Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> >
> >> On Tuesday 26 July 2016 12:00 PM, Nicholas Piggin wrote:
> >>> On Tue, 26 Jul 2016 11:55:51 +0530
> >>> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> >>>
> >>>> On Tuesday 26 July 2016 11:16 AM, Nicholas Piggin wrote:
> >>>>> On Mon, 25 Jul 2016 20:22:20 +0530
> >>>>> Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> >>>>>
> >>>>>> To support masking of the PMI interrupts, couple of new
> >>>>>> interrupt handler macros are added
> >>>>>> MASKABLE_EXCEPTION_PSERIES_OOL and
> >>>>>> MASKABLE_RELON_EXCEPTION_PSERIES_OOL. These are needed to
> >>>>>> include the SOFTEN_TEST and implement the support at both host
> >>>>>> and guest kernel.
> >>>>>>
> >>>>>> Couple of new irq #defs "PACA_IRQ_PMI" and "SOFTEN_VALUE_0xf0*"
> >>>>>> added to use in the exception code to check for PMI interrupts.
> >>>>>>
> >>>>>> __SOFTEN_TEST macro is modified to support the PMI interrupt.
> >>>>>> Present __SOFTEN_TEST code loads the soft_enabled from paca and
> >>>>>> check to call masked_interrupt handler code. To support both
> >>>>>> current behaviour and PMI masking, these changes are added,
> >>>>>>
> >>>>>> 1) Current LR register content are saved in R11
> >>>>>> 2) "bge" branch operation is changed to "bgel".
> >>>>>> 3) restore R11 to LR
> >>>>>>
> >>>>>> Reason:
> >>>>>>
> >>>>>> To retain PMI as NMI behaviour for flag state of 1, we save the
> >>>>>> LR regsiter value in R11 and branch to "masked_interrupt"
> >>>>>> handler with LR update. And in "masked_interrupt" handler, we
> >>>>>> check for the "SOFTEN_VALUE_*" value in R10 for PMI and branch
> >>>>>> back with "blr" if PMI.
> >>>>>>
> >>>>>> To mask PMI for a flag >1 value, masked_interrupt vaoid's the
> >>>>>> above check and continue to execute the masked_interrupt code
> >>>>>> and disabled MSR[EE] and updated the irq_happend with PMI info.
> >>>>>>
> >>>>>> Finally, saving of R11 is moved before calling SOFTEN_TEST in
> >>>>>> the __EXCEPTION_PROLOG_1 macro to support saving of LR values
> >>>>>> in SOFTEN_TEST.
> >>>>>>
> >>>>>> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> >>>>>> ---
> >>>>>> arch/powerpc/include/asm/exception-64s.h | 22
> >>>>>> ++++++++++++++++++++--
> >>>>>> arch/powerpc/include/asm/hw_irq.h | 1 +
> >>>>>> arch/powerpc/kernel/exceptions-64s.S | 27
> >>>>>> ++++++++++++++++++++++++--- 3 files changed, 45 insertions(+),
> >>>>>> 5 deletions(-)
> >>>>>>
> >>>>>> diff --git a/arch/powerpc/include/asm/exception-64s.h
> >>>>>> b/arch/powerpc/include/asm/exception-64s.h index
> >>>>>> 44d3f539d8a5..c951b7ab5108 100644 ---
> >>>>>> a/arch/powerpc/include/asm/exception-64s.h +++
> >>>>>> b/arch/powerpc/include/asm/exception-64s.h @@ -166,8 +166,8 @@
> >>>>>> END_FTR_SECTION_NESTED(ftr,ftr,943)
> >>>>>> OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);
> >>>>>> \ SAVE_CTR(r10, area);
> >>>>>> \ mfcr
> >>>>>> r9; \
> >>>>>> -
> >>>>>> extra(vec);
> >>>>>> \ std
> >>>>>> r11,area+EX_R11(r13); \
> >>>>>> +
> >>>>>> extra(vec);
> >>>>>> \ std
> >>>>>> r12,area+EX_R12(r13); \
> >>>>>> GET_SCRATCH0(r10);
> >>>>>> \ std r10,area+EX_R13(r13) @@ -403,12 +403,17 @@
> >>>>>> label##_relon_hv:
> >>>>>> \ #define SOFTEN_VALUE_0xe82 PACA_IRQ_DBELL #define
> >>>>>> SOFTEN_VALUE_0xe60 PACA_IRQ_HMI #define
> >>>>>> SOFTEN_VALUE_0xe62 PACA_IRQ_HMI +#define
> >>>>>> SOFTEN_VALUE_0xf01 PACA_IRQ_PMI +#define
> >>>>>> SOFTEN_VALUE_0xf00 PACA_IRQ_PMI
> >>>>> #define __SOFTEN_TEST(h,
> >>>>>> vec) \ lbz
> >>>>>> r10,PACASOFTIRQEN(r13);
> >>>>>> \ cmpwi
> >>>>>> r10,LAZY_INTERRUPT_DISABLED; \
> >>>>>> li
> >>>>>> r10,SOFTEN_VALUE_##vec;
> >>>>>> \
> >>>>>> - bge masked_##h##interrupt
> >>>>> At which point, can't we pass in the interrupt level we want to
> >>>>> mask for to SOFTEN_TEST, and avoid all this extra code
> >>>>> changes?
> >>>> IIUC, we do pass the interrupt info to SOFTEN_TEST. Incase of
> >>>> PMU interrupt we will have the value as PACA_IRQ_PMI.
> >>>>
> >>>>
> >>>>> PMU masked interrupt will compare with SOFTEN_LEVEL_PMU,
> >>>>> existing interrupts will compare with SOFTEN_LEVEL_EE (or
> >>>>> whatever suitable names there are).
> >>>>>
> >>>>>
> >>>>>> + mflr
> >>>>>> r11; \
> >>>>>> + bgel
> >>>>>> masked_##h##interrupt; \
> >>>>>> + mtlr r11;
> >>>>> This might corrupt return prediction when masked_interrupt does
> >>>>> not
> >>>> Hmm this is a valid point.
> >>>>
> >>>>> return. I guess that's uncommon case though.
> >>>> No, it is. kernel mostly use irq_disable with (1) today and only
> >>>> in specific case
> >>>> we disable all the interrupts. So we are going to return almost
> >>>> always when irqs are
> >>>> soft diabled.
> >>>>
> >>>> Since we need to support the PMIs as NMI when irq disable level
> >>>> is 1, we need to skip masked_interrupt.
> >>>>
> >>>> As you mentioned if we have a separate macro (SOFTEN_TEST_PMU),
> >>>> these can be avoided, but then it is code replication and we may
> >>>> need to change some more macros. But this interesting, let me
> >>>> work on this.
> >>> I would really prefer to do that, even if it means a little more
> >>> code.
> >>>
> >>> Another option is to give an additional parameter to the MASKABLE
> >>> variants of the exception handlers, which you can pass in the
> >>> "mask level" into. I think it's not a bad idea to make it explicit
> >>> even for the existing ones so it's clear which level they are
> >>> masked at.
> >> Issue here is that mask_interrupt function is not part of the
> >> interrupt vector code (__EXCEPTION_PROLOG_1). So incase of PMI,
> >> if we enter the mask_interrupt function, we need to know where
> >> to return to continue incase of NMI.
> > But if you test against the PMU disabled level, then you should
> > not even branch to masked_interrupt handler at all if regular
> > interrupts are soft disabled but PMU is enabled, no?
>
> Yes true. We can do this in SOFTEN_ itself and I did try that,
This would be ideal I think.
> but then we have issue of space in the vector code. I will
> try it again.
If you just test against the desired level to mask, then I don't
think it should add any more instructions, because you already
have structured it so you can branch on inequality.
As I said, maybe pass the desired mask level in to the MASKABLE
interrupt macros, rather than add a new SOFTEN_TEST case. That
makes it clear what level an exception is masked at, and avoids
I think a combinatorial explosion particularly if we want to add
other levels.
See how you go. If you can't do it without more instructions in
the exception vector, send me what you come up with and I'd like
to check.
Thanks,
Nick
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
` (8 preceding siblings ...)
2016-07-25 14:52 ` [RFC PATCH 9/9] powerpc: rewrite local_t using soft_irq Madhavan Srinivasan
@ 2016-07-26 12:21 ` Benjamin Herrenschmidt
2016-07-26 13:42 ` Madhavan Srinivasan
9 siblings, 1 reply; 31+ messages in thread
From: Benjamin Herrenschmidt @ 2016-07-26 12:21 UTC (permalink / raw)
To: Madhavan Srinivasan, mpe, anton, paulus; +Cc: linuxppc-dev
On Mon, 2016-07-25 at 20:22 +0530, Madhavan Srinivasan wrote:
> But this patchset uses Benjamin Herrenschmidt suggestion of using
> arch_local_irq_disable_var() to soft_disable interrupts (including PMIs).
> After finishing the "op", arch_local_irq_restore() called and correspondingly
> interrupts are replayed if any occured.
I am not fan of "var", we probably want "level".
Also be careful, you might be already soft-disabled at level 1, you
must restore to level 1, not level 0 in that case. Might want to
actually return the level in "flags" and restore that.
Cheers,
Ben.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation
2016-07-26 12:21 ` [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Benjamin Herrenschmidt
@ 2016-07-26 13:42 ` Madhavan Srinivasan
0 siblings, 0 replies; 31+ messages in thread
From: Madhavan Srinivasan @ 2016-07-26 13:42 UTC (permalink / raw)
To: Benjamin Herrenschmidt, mpe, anton, paulus; +Cc: linuxppc-dev
On Tuesday 26 July 2016 05:51 PM, Benjamin Herrenschmidt wrote:
> On Mon, 2016-07-25 at 20:22 +0530, Madhavan Srinivasan wrote:
>> But this patchset uses Benjamin Herrenschmidt suggestion of using
>> arch_local_irq_disable_var() to soft_disable interrupts (including PMIs).
>> After finishing the "op", arch_local_irq_restore() called and correspondingly
>> interrupts are replayed if any occured.
> I am not fan of "var", we probably want "level".
Sure. Will do
>
> Also be careful, you might be already soft-disabled at level 1, you
> must restore to level 1, not level 0 in that case. Might want to
> actually return the level in "flags" and restore that.
Yes. Thats correct. I return the current flag value.
Maddy
>
> Cheers,
> Ben.
>
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags
2016-07-26 6:05 ` Madhavan Srinivasan
2016-07-26 6:13 ` Nicholas Piggin
@ 2016-07-28 13:54 ` Nicholas Piggin
1 sibling, 0 replies; 31+ messages in thread
From: Nicholas Piggin @ 2016-07-28 13:54 UTC (permalink / raw)
To: Madhavan Srinivasan; +Cc: benh, mpe, anton, paulus, linuxppc-dev
On Tue, 26 Jul 2016 11:35:16 +0530
Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> On Tuesday 26 July 2016 10:57 AM, Nicholas Piggin wrote:
> > On Mon, 25 Jul 2016 20:22:14 +0530
> > Madhavan Srinivasan <maddy@linux.vnet.ibm.com> wrote:
> >
> >> Two #defs LAZY_INTERRUPT_ENABLED and
> >> LAZY_INTERRUPT_DISABLED are added to be used
> >> when updating paca->soft_enabled.
> > This is a very nice patchset, but can this not be a new name?
>
> Thanks, but idea is from ben :)
> Regarding the name, I looked at the initial patchset posted by
> paul and took the name from it :).
I did this quick hack for doing nmi watchdog using masked
decrementer interrupts instead of perf.
I think it should allow us to trip on hangs in
local_irq_and_pmu_disable() regions where the existing
one would not. Of course local atomics will not be usable
in the watchdog code, but that's more tractable than PMU
interrupts (or we just do our own private NMI watchdog
like other arch's do so we control everything -- sparc's
implementation is only 270 lines).
Let me know if you find it useful.
Thanks,
Nick
diff --git a/arch/Kconfig b/arch/Kconfig
index d794384..a307407 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -35,7 +35,7 @@ config HAVE_OPROFILE
config OPROFILE_NMI_TIMER
def_bool y
- depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !PPC64
+ depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI
config KPROBES
bool "Kprobes"
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 01f7464..87a0816 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -130,6 +130,7 @@ config PPC
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_CBPF_JIT
select HAVE_ARCH_JUMP_LABEL
+ select HAVE_NMI
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_HAS_GCOV_PROFILE_ALL
select GENERIC_SMP_IDLE_THREAD
@@ -154,8 +155,6 @@ config PPC
select DCACHE_WORD_ACCESS if PPC64 && CPU_LITTLE_ENDIAN
select NO_BOOTMEM
select HAVE_GENERIC_RCU_GUP
- select HAVE_PERF_EVENTS_NMI if PPC64
- select HAVE_NMI if PERF_EVENTS
select EDAC_SUPPORT
select EDAC_ATOMIC_SCRUB
select ARCH_HAS_DMA_SET_COHERENT_MASK
diff --git a/arch/powerpc/include/asm/nmi.h b/arch/powerpc/include/asm/nmi.h
index ff1ccb3..90ab2bb 100644
--- a/arch/powerpc/include/asm/nmi.h
+++ b/arch/powerpc/include/asm/nmi.h
@@ -1,4 +1,8 @@
#ifndef _ASM_NMI_H
#define _ASM_NMI_H
+extern int nmi_enable(u64 period);
+extern void nmi_disable(void);
+extern void nmi_interrupt(struct pt_regs *regs);
+
#endif /* _ASM_NMI_H */
diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index 546540b..6b3b041 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -153,6 +153,9 @@ struct paca_struct {
u64 saved_msr; /* MSR saved here by enter_rtas */
u16 trap_save; /* Used when bad stack is encountered */
u8 soft_enabled; /* irq soft-enable flag */
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
+ u8 nmi_enabled; /* generate nmis when soft-disabled */
+#endif
u8 irq_happened; /* irq happened while soft-disabled */
u8 io_sync; /* writel() needs spin_unlock sync */
u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 9ea0955..4bf327d 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -190,6 +190,9 @@ int main(void)
DEFINE(PACAKBASE, offsetof(struct paca_struct, kernelbase));
DEFINE(PACAKMSR, offsetof(struct paca_struct, kernel_msr));
DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
+#ifdef CONFIG_HARDLOCKUP_DETECTOR
+ DEFINE(PACANMIENABLED, offsetof(struct paca_struct, nmi_enabled));
+#endif
DEFINE(PACAIRQHAPPENED, offsetof(struct paca_struct, irq_happened));
#ifdef CONFIG_PPC_BOOK3S
DEFINE(PACACONTEXTID, offsetof(struct paca_struct, mm_ctx_id));
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 4c94406..972f368 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -634,6 +634,8 @@ masked_##_H##interrupt: \
lis r10,0x7fff; \
ori r10,r10,0xffff; \
mtspr SPRN_DEC,r10; \
+ /* XXX: test nmi enabled and depend CONFIG_HARDLOCKUP_DETECTOR */ \
+ b masked_decrementer_##_H##interrupt; \
b 2f; \
1: cmpwi r10,PACA_IRQ_DBELL; \
beq 2f; \
@@ -650,9 +652,21 @@ masked_##_H##interrupt: \
GET_SCRATCH0(r13); \
##_H##rfid; \
b .
-
+
+#define MASKED_NMI(_H) \
+masked_decrementer_##_H##interrupt: \
+ std r12,PACA_EXGEN+EX_R12(r13); \
+ GET_SCRATCH0(r10); \
+ std r10,PACA_EXGEN+EX_R13(r13); \
+ EXCEPTION_PROLOG_PSERIES_1(nmi_common, _H)
+
MASKED_INTERRUPT()
+ MASKED_NMI()
MASKED_INTERRUPT(H)
+ MASKED_NMI(H)
+
+
+STD_EXCEPTION_COMMON_ASYNC(0x900, nmi, nmi_interrupt)
/*
* Called from arch_local_irq_enable when an interrupt needs
diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c
index 9ad37f8..bedc975 100644
--- a/arch/powerpc/kernel/kvm.c
+++ b/arch/powerpc/kernel/kvm.c
@@ -25,6 +25,7 @@
#include <linux/kvm_para.h>
#include <linux/slab.h>
#include <linux/of.h>
+#include <linux/nmi.h>
#include <asm/reg.h>
#include <asm/sections.h>
@@ -718,6 +719,8 @@ static __init void kvm_free_tmp(void)
static int __init kvm_guest_init(void)
{
+ hardlockup_detector_disable();
+
if (!kvm_para_available())
goto free_tmp;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 96d4a2b..cfa03db 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -808,21 +808,3 @@ struct ppc_pci_io ppc_pci_io;
EXPORT_SYMBOL(ppc_pci_io);
#endif
-#ifdef CONFIG_HARDLOCKUP_DETECTOR
-u64 hw_nmi_get_sample_period(int watchdog_thresh)
-{
- return ppc_proc_freq * watchdog_thresh;
-}
-
-/*
- * The hardlockup detector breaks PMU event based branches and is likely
- * to get false positives in KVM guests, so disable it by default.
- */
-static int __init disable_hardlockup_detector(void)
-{
- hardlockup_detector_disable();
-
- return 0;
-}
-early_initcall(disable_hardlockup_detector);
-#endif
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 3ed9a5a..633fdca 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -52,6 +52,7 @@
#include <linux/jiffies.h>
#include <linux/posix-timers.h>
#include <linux/irq.h>
+#include <linux/nmi.h>
#include <linux/delay.h>
#include <linux/irq_work.h>
#include <linux/clk-provider.h>
@@ -65,6 +66,7 @@
#include <asm/machdep.h>
#include <asm/uaccess.h>
#include <asm/time.h>
+#include <asm/nmi.h>
#include <asm/prom.h>
#include <asm/irq.h>
#include <asm/div64.h>
@@ -523,11 +525,78 @@ static void __timer_interrupt(void)
trace_timer_interrupt_exit(regs);
}
+int watchdog_nmi_enable(unsigned int cpu, int period)
+{
+ /* Migration should be disabled and running on same CPU as local */
+ if (cpu != smp_processor_id()) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ return nmi_enable(ppc_tb_freq * period);
+}
+
+void watchdog_nmi_disable(unsigned int cpu)
+{
+ if (cpu != smp_processor_id()) {
+ WARN_ON(1);
+ return;
+ }
+
+ nmi_disable();
+}
+
+static DEFINE_PER_CPU(u64, nmi_period);
+static DEFINE_PER_CPU(u64, nmi_last_tb);
+
+/*
+ * nmi interrupts only occur when linux irqs are disabled (but
+ * powerpc hardware irqs are enabled), so they can not be relied
+ * upon to be timely or delivered at all. Their only real use is
+ * the nmi watchdog.
+ */
+int nmi_enable(u64 period)
+{
+ if (__this_cpu_read(nmi_period))
+ return -EINVAL;
+
+ __this_cpu_write(nmi_period, period);
+ __this_cpu_write(nmi_last_tb, get_tb());
+ barrier();
+ get_paca()->nmi_enabled = 1;
+
+ return 0;
+}
+
+void nmi_disable(void)
+{
+ get_paca()->nmi_enabled = 0;
+ barrier();
+ __this_cpu_write(nmi_period, 0);
+}
+
+void nmi_interrupt(struct pt_regs *regs)
+{
+ u64 tb;
+
+ if (!__this_cpu_read(nmi_period))
+ return;
+
+ tb = get_tb();
+ if (tb - __this_cpu_read(nmi_last_tb) < __this_cpu_read(nmi_period))
+ return;
+ __this_cpu_write(nmi_last_tb, tb);
+
+ nmi_enter();
+ watchdog_nmi_interrupt(regs);
+ nmi_exit();
+}
+
/*
* timer_interrupt - gets called when the decrementer overflows,
* with interrupts disabled.
*/
-void timer_interrupt(struct pt_regs * regs)
+void timer_interrupt(struct pt_regs *regs)
{
struct pt_regs *old_regs;
u64 *next_tb = this_cpu_ptr(&decrementers_next_tb);
diff --git a/include/linux/nmi.h b/include/linux/nmi.h
index 4630eea..5d6bdca 100644
--- a/include/linux/nmi.h
+++ b/include/linux/nmi.h
@@ -6,6 +6,9 @@
#include <linux/sched.h>
#include <asm/irq.h>
+#ifdef CONFIG_HAVE_NMI
+#include <asm/nmi.h>
+#endif
/**
* touch_nmi_watchdog - restart NMI watchdog timeout.
@@ -15,7 +18,7 @@
* disables interrupts for a long time. This call is stateless.
*/
#if defined(CONFIG_HAVE_NMI_WATCHDOG) || defined(CONFIG_HARDLOCKUP_DETECTOR)
-#include <asm/nmi.h>
+extern void watchdog_nmi_interrupt(struct pt_regs *regs);
extern void touch_nmi_watchdog(void);
#else
static inline void touch_nmi_watchdog(void)
@@ -26,6 +29,15 @@ static inline void touch_nmi_watchdog(void)
#if defined(CONFIG_HARDLOCKUP_DETECTOR)
extern void hardlockup_detector_disable(void);
+
+#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF
+u64 hw_nmi_get_sample_period(int watchdog_thresh);
+#else
+extern int watchdog_nmi_enable(unsigned int cpu, int thresh);
+extern void watchdog_nmi_disable(unsigned int cpu);
+extern void watchdog_nmi_interrupt(struct pt_regs *regs);
+#endif
+
#else
static inline void hardlockup_detector_disable(void) {}
#endif
@@ -65,7 +77,6 @@ static inline bool trigger_allbutself_cpu_backtrace(void)
#endif
#ifdef CONFIG_LOCKUP_DETECTOR
-u64 hw_nmi_get_sample_period(int watchdog_thresh);
extern int nmi_watchdog_enabled;
extern int soft_watchdog_enabled;
extern int watchdog_user_enabled;
@@ -97,8 +108,4 @@ static inline void lockup_detector_resume(void)
}
#endif
-#ifdef CONFIG_HAVE_ACPI_APEI_NMI
-#include <asm/nmi.h>
-#endif
-
#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 6e42ada..f397d0b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -395,6 +395,7 @@ extern int proc_dowatchdog_thresh(struct ctl_table *table, int write,
size_t *lenp, loff_t *ppos);
extern unsigned int softlockup_panic;
extern unsigned int hardlockup_panic;
+void lockup_detector_init_early(void);
void lockup_detector_init(void);
#else
static inline void touch_softlockup_watchdog_sched(void)
@@ -409,6 +410,9 @@ static inline void touch_softlockup_watchdog_sync(void)
static inline void touch_all_softlockup_watchdogs(void)
{
}
+static inline void lockup_detector_init_early(void)
+{
+}
static inline void lockup_detector_init(void)
{
}
diff --git a/init/main.c b/init/main.c
index 4c17fda..7b6671d 100644
--- a/init/main.c
+++ b/init/main.c
@@ -570,6 +570,7 @@ asmlinkage __visible void __init start_kernel(void)
time_init();
sched_clock_postinit();
printk_nmi_init();
+ lockup_detector_init_early();
perf_event_init();
profile_init();
call_function_init();
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 9acb29f..a06376d 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -23,6 +23,7 @@
#include <linux/workqueue.h>
#include <asm/irq_regs.h>
+#include <asm/nmi.h>
#include <linux/kvm_para.h>
#include <linux/perf_event.h>
#include <linux/kthread.h>
@@ -104,8 +105,10 @@ static DEFINE_PER_CPU(struct task_struct *, softlockup_task_ptr_saved);
static DEFINE_PER_CPU(bool, hard_watchdog_warn);
static DEFINE_PER_CPU(bool, watchdog_nmi_touch);
static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved);
+#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF
static DEFINE_PER_CPU(struct perf_event *, watchdog_ev);
#endif
+#endif
static unsigned long soft_lockup_nmi_warn;
/* boot commands */
@@ -314,23 +317,8 @@ static int is_softlockup(unsigned long touch_ts)
}
#ifdef CONFIG_HARDLOCKUP_DETECTOR
-
-static struct perf_event_attr wd_hw_attr = {
- .type = PERF_TYPE_HARDWARE,
- .config = PERF_COUNT_HW_CPU_CYCLES,
- .size = sizeof(struct perf_event_attr),
- .pinned = 1,
- .disabled = 1,
-};
-
-/* Callback function for perf event subsystem */
-static void watchdog_overflow_callback(struct perf_event *event,
- struct perf_sample_data *data,
- struct pt_regs *regs)
+void watchdog_nmi_interrupt(struct pt_regs *regs)
{
- /* Ensure the watchdog never gets throttled */
- event->hw.interrupts = 0;
-
if (__this_cpu_read(watchdog_nmi_touch) == true) {
__this_cpu_write(watchdog_nmi_touch, false);
return;
@@ -374,18 +362,40 @@ static void watchdog_overflow_callback(struct perf_event *event,
}
__this_cpu_write(hard_watchdog_warn, false);
- return;
}
#endif /* CONFIG_HARDLOCKUP_DETECTOR */
+#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF
+static struct perf_event_attr wd_hw_attr = {
+ .type = PERF_TYPE_HARDWARE,
+ .config = PERF_COUNT_HW_CPU_CYCLES,
+ .size = sizeof(struct perf_event_attr),
+ .pinned = 1,
+ .disabled = 1,
+};
+
+/* Callback function for perf event subsystem */
+static void watchdog_overflow_callback(struct perf_event *event,
+ struct perf_sample_data *data,
+ struct pt_regs *regs)
+{
+ /* Ensure the watchdog never gets throttled */
+ event->hw.interrupts = 0;
+
+ watchdog_nmi_interrupt(regs);
+
+ return;
+}
+static int watchdog_nmi_enable(unsigned int cpu, int period);
+static void watchdog_nmi_disable(unsigned int cpu);
+
+#endif /* CONFIG_HARDLOCKUP_DETECTOR_PERF */
+
static void watchdog_interrupt_count(void)
{
__this_cpu_inc(hrtimer_interrupts);
}
-static int watchdog_nmi_enable(unsigned int cpu);
-static void watchdog_nmi_disable(unsigned int cpu);
-
static int watchdog_enable_all_cpus(void);
static void watchdog_disable_all_cpus(void);
@@ -514,8 +524,8 @@ static void watchdog_enable(unsigned int cpu)
hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hrtimer->function = watchdog_timer_fn;
- /* Enable the perf event */
- watchdog_nmi_enable(cpu);
+ /* Enable the nmi */
+ watchdog_nmi_enable(cpu, watchdog_thresh);
/* done here because hrtimer_start can only pin to smp_processor_id() */
hrtimer_start(hrtimer, ns_to_ktime(sample_period),
@@ -532,7 +542,7 @@ static void watchdog_disable(unsigned int cpu)
watchdog_set_prio(SCHED_NORMAL, 0);
hrtimer_cancel(hrtimer);
- /* disable the perf event */
+ /* disable the nmi */
watchdog_nmi_disable(cpu);
}
@@ -565,7 +575,7 @@ static void watchdog(unsigned int cpu)
* watchdog_nmi_enable() clears the NMI_WATCHDOG_ENABLED bit in the
* failure path. Check for failures that can occur asynchronously -
* for example, when CPUs are on-lined - and shut down the hardware
- * perf event on each CPU accordingly.
+ * nmi mechanism on each CPU accordingly.
*
* The only non-obvious place this bit can be cleared is through
* watchdog_nmi_enable(), so a pr_info() is placed there. Placing a
@@ -578,6 +588,7 @@ static void watchdog(unsigned int cpu)
}
#ifdef CONFIG_HARDLOCKUP_DETECTOR
+#ifdef CONFIG_HARDLOCKUP_DETECTOR_PERF
/*
* People like the simple clean cpu node info on boot.
* Reduce the watchdog noise by only printing messages
@@ -585,7 +596,7 @@ static void watchdog(unsigned int cpu)
*/
static unsigned long cpu0_err;
-static int watchdog_nmi_enable(unsigned int cpu)
+static int watchdog_nmi_enable(unsigned int cpu, int period)
{
struct perf_event_attr *wd_attr;
struct perf_event *event = per_cpu(watchdog_ev, cpu);
@@ -603,7 +614,7 @@ static int watchdog_nmi_enable(unsigned int cpu)
goto out_enable;
wd_attr = &wd_hw_attr;
- wd_attr->sample_period = hw_nmi_get_sample_period(watchdog_thresh);
+ wd_attr->sample_period = hw_nmi_get_sample_period(period);
/* Try to register using hardware perf events */
event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL);
@@ -674,9 +685,9 @@ static void watchdog_nmi_disable(unsigned int cpu)
cpu0_err = 0;
}
}
-
+#endif /* CONFIG_HARDLOCKUP_DETECTOR_PERF */
#else
-static int watchdog_nmi_enable(unsigned int cpu) { return 0; }
+static int watchdog_nmi_enable(unsigned int cpu, int period) { return 0; }
static void watchdog_nmi_disable(unsigned int cpu) { return; }
#endif /* CONFIG_HARDLOCKUP_DETECTOR */
@@ -1000,6 +1011,7 @@ int proc_watchdog_thresh(struct ctl_table *table, int write,
watchdog_thresh = old;
set_sample_period();
}
+
out:
mutex_unlock(&watchdog_proc_mutex);
put_online_cpus();
@@ -1051,9 +1063,15 @@ out:
#endif /* CONFIG_SYSCTL */
-void __init lockup_detector_init(void)
+void __init lockup_detector_init_early(void)
{
set_sample_period();
+ watchdog_nmi_enable(raw_smp_processor_id(), watchdog_thresh);
+}
+
+void __init lockup_detector_init(void)
+{
+ watchdog_nmi_disable(raw_smp_processor_id());
#ifdef CONFIG_NO_HZ_FULL
if (tick_nohz_full_enabled()) {
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index b9cfdbf..ea35036 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -755,8 +755,11 @@ config LOCKUP_DETECTOR
config HARDLOCKUP_DETECTOR
def_bool y
- depends on LOCKUP_DETECTOR && !HAVE_NMI_WATCHDOG
- depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI
+ depends on LOCKUP_DETECTOR
+
+config HARDLOCKUP_DETECTOR_PERF
+ def_bool y
+ depends on HARDLOCKUP_DETECTOR && PERF_EVENTS && HAVE_PERF_EVENTS_NMI
config BOOTPARAM_HARDLOCKUP_PANIC
bool "Panic (Reboot) On Hard Lockups"
^ permalink raw reply related [flat|nested] 31+ messages in thread
end of thread, other threads:[~2016-07-28 13:54 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-25 14:52 [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 1/9] Add #defs for paca->soft_enabled flags Madhavan Srinivasan
2016-07-26 5:27 ` Nicholas Piggin
2016-07-26 6:05 ` Madhavan Srinivasan
2016-07-26 6:13 ` Nicholas Piggin
2016-07-28 13:54 ` Nicholas Piggin
2016-07-25 14:52 ` [RFC PATCH 2/9] Cleanup to use LAZY_INTERRUPT_* macros for paca->soft_enabled update Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 3/9] powerpc: move set_soft_enabled() Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 4/9] powerpc: Use set_soft_enabled api to update paca->soft_enabled Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 5/9] powerpc: reverse the soft_enable logic Madhavan Srinivasan
2016-07-26 5:31 ` Nicholas Piggin
2016-07-26 6:07 ` Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 6/9] powerpc: modify __SOFTEN_TEST to support tri-state soft_enabled flag Madhavan Srinivasan
2016-07-26 5:41 ` Nicholas Piggin
2016-07-26 6:12 ` Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 7/9] powerpc: Add support to mask perf interrupts Madhavan Srinivasan
2016-07-26 5:46 ` Nicholas Piggin
2016-07-26 6:25 ` Madhavan Srinivasan
2016-07-26 6:30 ` Nicholas Piggin
2016-07-26 6:46 ` Madhavan Srinivasan
2016-07-26 7:10 ` Nicholas Piggin
2016-07-26 7:22 ` Madhavan Srinivasan
2016-07-26 7:34 ` Nicholas Piggin
2016-07-25 14:52 ` [RFC PATCH 8/9] powerpc: Support to replay PMIs Madhavan Srinivasan
2016-07-26 5:50 ` Nicholas Piggin
2016-07-26 6:40 ` Madhavan Srinivasan
2016-07-25 14:52 ` [RFC PATCH 9/9] powerpc: rewrite local_t using soft_irq Madhavan Srinivasan
2016-07-26 5:53 ` Nicholas Piggin
2016-07-26 6:41 ` Madhavan Srinivasan
2016-07-26 12:21 ` [RFC PATCH 0/9]powerpc: "paca->soft_enabled" based local atomic operation implementation Benjamin Herrenschmidt
2016-07-26 13:42 ` Madhavan Srinivasan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).