Skip to content

Commit 2bc79ff

Browse files
mikeympe
authored andcommitted
cxl: Poll for outstanding IRQs when detaching a context
When detaching contexts, we may still have interrupts in the system which are yet to be delivered to any CPU and be acked in the PSL. This can result in a subsequent unrelated process getting an spurious IRQ or an interrupt for a non-existent context. This polls the PSL to ensure that the PSL is clear of IRQs for the detached context, before removing the context from the idr. Signed-off-by: Michael Neuling <[email protected]> Tested-by: Andrew Donnellan <[email protected]> Acked-by: Ian Munsie <[email protected]> Tested-by: Vaibhav Jain <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent d6776bb commit 2bc79ff

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

drivers/misc/cxl/context.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,13 @@ int __detach_context(struct cxl_context *ctx)
223223
cxl_ops->link_ok(ctx->afu->adapter, ctx->afu));
224224
flush_work(&ctx->fault_work); /* Only needed for dedicated process */
225225

226+
/*
227+
* Wait until no further interrupts are presented by the PSL
228+
* for this context.
229+
*/
230+
if (cxl_ops->irq_wait)
231+
cxl_ops->irq_wait(ctx);
232+
226233
/* release the reference to the group leader and mm handling pid */
227234
put_pid(ctx->pid);
228235
put_pid(ctx->glpid);

drivers/misc/cxl/cxl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0};
274274
#define CXL_PSL_DSISR_An_PE (1ull << (63-4)) /* PSL Error (implementation specific) */
275275
#define CXL_PSL_DSISR_An_AE (1ull << (63-5)) /* AFU Error */
276276
#define CXL_PSL_DSISR_An_OC (1ull << (63-6)) /* OS Context Warning */
277+
#define CXL_PSL_DSISR_PENDING (CXL_PSL_DSISR_TRANS | CXL_PSL_DSISR_An_PE | CXL_PSL_DSISR_An_AE | CXL_PSL_DSISR_An_OC)
277278
/* NOTE: Bits 32:63 are undefined if DSISR[DS] = 1 */
278279
#define CXL_PSL_DSISR_An_M DSISR_NOHPTE /* PTE not found */
279280
#define CXL_PSL_DSISR_An_P DSISR_PROTFAULT /* Storage protection violation */
@@ -855,6 +856,7 @@ struct cxl_backend_ops {
855856
u64 dsisr, u64 errstat);
856857
irqreturn_t (*psl_interrupt)(int irq, void *data);
857858
int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
859+
void (*irq_wait)(struct cxl_context *ctx);
858860
int (*attach_process)(struct cxl_context *ctx, bool kernel,
859861
u64 wed, u64 amr);
860862
int (*detach_process)(struct cxl_context *ctx);

drivers/misc/cxl/native.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/mutex.h>
1515
#include <linux/mm.h>
1616
#include <linux/uaccess.h>
17+
#include <linux/delay.h>
1718
#include <asm/synch.h>
1819
#include <misc/cxl-base.h>
1920

@@ -797,6 +798,35 @@ static irqreturn_t native_irq_multiplexed(int irq, void *data)
797798
return fail_psl_irq(afu, &irq_info);
798799
}
799800

801+
void native_irq_wait(struct cxl_context *ctx)
802+
{
803+
u64 dsisr;
804+
int timeout = 1000;
805+
int ph;
806+
807+
/*
808+
* Wait until no further interrupts are presented by the PSL
809+
* for this context.
810+
*/
811+
while (timeout--) {
812+
ph = cxl_p2n_read(ctx->afu, CXL_PSL_PEHandle_An) & 0xffff;
813+
if (ph != ctx->pe)
814+
return;
815+
dsisr = cxl_p2n_read(ctx->afu, CXL_PSL_DSISR_An);
816+
if ((dsisr & CXL_PSL_DSISR_PENDING) == 0)
817+
return;
818+
/*
819+
* We are waiting for the workqueue to process our
820+
* irq, so need to let that run here.
821+
*/
822+
msleep(1);
823+
}
824+
825+
dev_warn(&ctx->afu->dev, "WARNING: waiting on DSI for PE %i"
826+
" DSISR %016llx!\n", ph, dsisr);
827+
return;
828+
}
829+
800830
static irqreturn_t native_slice_irq_err(int irq, void *data)
801831
{
802832
struct cxl_afu *afu = data;
@@ -1076,6 +1106,7 @@ const struct cxl_backend_ops cxl_native_ops = {
10761106
.handle_psl_slice_error = native_handle_psl_slice_error,
10771107
.psl_interrupt = NULL,
10781108
.ack_irq = native_ack_irq,
1109+
.irq_wait = native_irq_wait,
10791110
.attach_process = native_attach_process,
10801111
.detach_process = native_detach_process,
10811112
.support_attributes = native_support_attributes,

0 commit comments

Comments
 (0)