Skip to content

Commit b1f9be9

Browse files
legoatermpe
authored andcommitted
powerpc/xive: Enforce load-after-store ordering when StoreEOI is active
When an interrupt has been handled, the OS notifies the interrupt controller with a EOI sequence. On a POWER9 system using the XIVE interrupt controller, this can be done with a load or a store operation on the ESB interrupt management page of the interrupt. The StoreEOI operation has less latency and improves interrupt handling performance but it was deactivated during the POWER9 DD2.0 timeframe because of ordering issues. We use the LoadEOI today but we plan to reactivate StoreEOI in future architectures. There is usually no need to enforce ordering between ESB load and store operations as they should lead to the same result. E.g. a store trigger and a load EOI can be executed in any order. Assuming the interrupt state is PQ=10, a store trigger followed by a load EOI will return a Q bit. In the reverse order, it will create a new interrupt trigger from HW. In both cases, the handler processing interrupts is notified. In some cases, the XIVE_ESB_SET_PQ_10 load operation is used to disable temporarily the interrupt source (mask/unmask). When the source is reenabled, the OS can detect if interrupts were received while the source was disabled and reinject them. This process needs special care when StoreEOI is activated. The ESB load and store operations should be correctly ordered because a XIVE_ESB_STORE_EOI operation could leave the source enabled if it has not completed before the loads. For those cases, we enforce Load-after-Store ordering with a special load operation offset. To avoid performance impact, this ordering is only enforced when really needed, that is when interrupt sources are temporarily disabled with the XIVE_ESB_SET_PQ_10 load. It should not be needed for other loads. Signed-off-by: Cédric Le Goater <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 75358ea commit b1f9be9

File tree

5 files changed

+25
-0
lines changed

5 files changed

+25
-0
lines changed

arch/powerpc/include/asm/xive-regs.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,14 @@
3737
#define XIVE_ESB_SET_PQ_10 0xe00 /* Load */
3838
#define XIVE_ESB_SET_PQ_11 0xf00 /* Load */
3939

40+
/*
41+
* Load-after-store ordering
42+
*
43+
* Adding this offset to the load address will enforce
44+
* load-after-store ordering. This is required to use StoreEOI.
45+
*/
46+
#define XIVE_ESB_LD_ST_MO 0x40 /* Load-after-store ordering */
47+
4048
#define XIVE_ESB_VAL_P 0x2
4149
#define XIVE_ESB_VAL_Q 0x1
4250
#define XIVE_ESB_INVALID 0xFF

arch/powerpc/kvm/book3s_hv_rmhandlers.S

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2907,6 +2907,11 @@ kvm_cede_exit:
29072907
beq 4f
29082908
li r0, 0
29092909
stb r0, VCPU_CEDED(r9)
2910+
/*
2911+
* The escalation interrupts are special as we don't EOI them.
2912+
* There is no need to use the load-after-store ordering offset
2913+
* to set PQ to 10 as we won't use StoreEOI.
2914+
*/
29102915
li r6, XIVE_ESB_SET_PQ_10
29112916
b 5f
29122917
4: li r0, 1

arch/powerpc/kvm/book3s_xive_native.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ static u8 xive_vm_esb_load(struct xive_irq_data *xd, u32 offset)
3131
{
3232
u64 val;
3333

34+
/*
35+
* The KVM XIVE native device does not use the XIVE_ESB_SET_PQ_10
36+
* load operation, so there is no need to enforce load-after-store
37+
* ordering.
38+
*/
39+
3440
if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG)
3541
offset |= offset << 4;
3642

arch/powerpc/kvm/book3s_xive_template.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ static u8 GLUE(X_PFX,esb_load)(struct xive_irq_data *xd, u32 offset)
5858
{
5959
u64 val;
6060

61+
if (offset == XIVE_ESB_SET_PQ_10 && xd->flags & XIVE_IRQ_FLAG_STORE_EOI)
62+
offset |= XIVE_ESB_LD_ST_MO;
63+
6164
if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG)
6265
offset |= offset << 4;
6366

arch/powerpc/sysdev/xive/common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ static notrace u8 xive_esb_read(struct xive_irq_data *xd, u32 offset)
196196
{
197197
u64 val;
198198

199+
if (offset == XIVE_ESB_SET_PQ_10 && xd->flags & XIVE_IRQ_FLAG_STORE_EOI)
200+
offset |= XIVE_ESB_LD_ST_MO;
201+
199202
/* Handle HW errata */
200203
if (xd->flags & XIVE_IRQ_FLAG_SHIFT_BUG)
201204
offset |= offset << 4;

0 commit comments

Comments
 (0)