aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2016-04-22 00:57:49 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2016-04-26 22:04:48 -0400
commit2bc79ffcbb817873cc43d63118008ab75181b73d (patch)
tree2f11750e0420af56962e11ef0c7da69f03e24eb3
parentd6776bba44d9752f6cdf640046070e71ee4bba7b (diff)
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 <mikey@neuling.org> Tested-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Acked-by: Ian Munsie <imunsie@au1.ibm.com> Tested-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--drivers/misc/cxl/context.c7
-rw-r--r--drivers/misc/cxl/cxl.h2
-rw-r--r--drivers/misc/cxl/native.c31
3 files changed, 40 insertions, 0 deletions
diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
index 10370f280500..7edea9c19199 100644
--- a/drivers/misc/cxl/context.c
+++ b/drivers/misc/cxl/context.c
@@ -223,6 +223,13 @@ int __detach_context(struct cxl_context *ctx)
223 cxl_ops->link_ok(ctx->afu->adapter, ctx->afu)); 223 cxl_ops->link_ok(ctx->afu->adapter, ctx->afu));
224 flush_work(&ctx->fault_work); /* Only needed for dedicated process */ 224 flush_work(&ctx->fault_work); /* Only needed for dedicated process */
225 225
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
226 /* release the reference to the group leader and mm handling pid */ 233 /* release the reference to the group leader and mm handling pid */
227 put_pid(ctx->pid); 234 put_pid(ctx->pid);
228 put_pid(ctx->glpid); 235 put_pid(ctx->glpid);
diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
index 38e21cf7806e..73dc2a33da74 100644
--- a/drivers/misc/cxl/cxl.h
+++ b/drivers/misc/cxl/cxl.h
@@ -274,6 +274,7 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0};
274#define CXL_PSL_DSISR_An_PE (1ull << (63-4)) /* PSL Error (implementation specific) */ 274#define CXL_PSL_DSISR_An_PE (1ull << (63-4)) /* PSL Error (implementation specific) */
275#define CXL_PSL_DSISR_An_AE (1ull << (63-5)) /* AFU Error */ 275#define CXL_PSL_DSISR_An_AE (1ull << (63-5)) /* AFU Error */
276#define CXL_PSL_DSISR_An_OC (1ull << (63-6)) /* OS Context Warning */ 276#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)
277/* NOTE: Bits 32:63 are undefined if DSISR[DS] = 1 */ 278/* NOTE: Bits 32:63 are undefined if DSISR[DS] = 1 */
278#define CXL_PSL_DSISR_An_M DSISR_NOHPTE /* PTE not found */ 279#define CXL_PSL_DSISR_An_M DSISR_NOHPTE /* PTE not found */
279#define CXL_PSL_DSISR_An_P DSISR_PROTFAULT /* Storage protection violation */ 280#define CXL_PSL_DSISR_An_P DSISR_PROTFAULT /* Storage protection violation */
@@ -855,6 +856,7 @@ struct cxl_backend_ops {
855 u64 dsisr, u64 errstat); 856 u64 dsisr, u64 errstat);
856 irqreturn_t (*psl_interrupt)(int irq, void *data); 857 irqreturn_t (*psl_interrupt)(int irq, void *data);
857 int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask); 858 int (*ack_irq)(struct cxl_context *ctx, u64 tfc, u64 psl_reset_mask);
859 void (*irq_wait)(struct cxl_context *ctx);
858 int (*attach_process)(struct cxl_context *ctx, bool kernel, 860 int (*attach_process)(struct cxl_context *ctx, bool kernel,
859 u64 wed, u64 amr); 861 u64 wed, u64 amr);
860 int (*detach_process)(struct cxl_context *ctx); 862 int (*detach_process)(struct cxl_context *ctx);
diff --git a/drivers/misc/cxl/native.c b/drivers/misc/cxl/native.c
index 387fcbdf9793..ecf7557cd657 100644
--- a/drivers/misc/cxl/native.c
+++ b/drivers/misc/cxl/native.c
@@ -14,6 +14,7 @@
14#include <linux/mutex.h> 14#include <linux/mutex.h>
15#include <linux/mm.h> 15#include <linux/mm.h>
16#include <linux/uaccess.h> 16#include <linux/uaccess.h>
17#include <linux/delay.h>
17#include <asm/synch.h> 18#include <asm/synch.h>
18#include <misc/cxl-base.h> 19#include <misc/cxl-base.h>
19 20
@@ -797,6 +798,35 @@ static irqreturn_t native_irq_multiplexed(int irq, void *data)
797 return fail_psl_irq(afu, &irq_info); 798 return fail_psl_irq(afu, &irq_info);
798} 799}
799 800
801void 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
800static irqreturn_t native_slice_irq_err(int irq, void *data) 830static irqreturn_t native_slice_irq_err(int irq, void *data)
801{ 831{
802 struct cxl_afu *afu = data; 832 struct cxl_afu *afu = data;
@@ -1076,6 +1106,7 @@ const struct cxl_backend_ops cxl_native_ops = {
1076 .handle_psl_slice_error = native_handle_psl_slice_error, 1106 .handle_psl_slice_error = native_handle_psl_slice_error,
1077 .psl_interrupt = NULL, 1107 .psl_interrupt = NULL,
1078 .ack_irq = native_ack_irq, 1108 .ack_irq = native_ack_irq,
1109 .irq_wait = native_irq_wait,
1079 .attach_process = native_attach_process, 1110 .attach_process = native_attach_process,
1080 .detach_process = native_detach_process, 1111 .detach_process = native_detach_process,
1081 .support_attributes = native_support_attributes, 1112 .support_attributes = native_support_attributes,