summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRakesh Naidu Bhaviripudi <quic_rakeshb@quicinc.com>2024-06-10 12:20:24 +0530
committerRaviteja Narayanam <quic_ravnar@quicinc.com>2024-07-08 19:03:04 +0530
commitdc9abd24dd0943d1afb3a349bbacc19baa0f071d (patch)
tree21c4d64d24b5715395ce9d3ff8e0011c3fcd6260
parentdaec7e0637ee2c6d5a05460d1afa36b22e97b418 (diff)
msm: kgsl: Fix error handling during drawctxt switch
Currently, separate submissions are made for page table switch and context switch to the ring buffer. However, if the page table switch succeeds but the context switch fails, it can lead to use of wrong page table for drawctxt. To address this issue, rollback the pagetable to current pagetable. Also,correctly put the refcount of adreno context during error cleanup. Change-Id: I1bb4ee3ebb0ce6ea32f0b6799cfb7fa89c0d09c7 Signed-off-by: Rakesh Naidu Bhaviripudi <quic_rakeshb@quicinc.com>
-rw-r--r--drivers/gpu/msm/adreno_drawctxt.c12
-rw-r--r--drivers/gpu/msm/adreno_iommu.c13
2 files changed, 22 insertions, 3 deletions
diff --git a/drivers/gpu/msm/adreno_drawctxt.c b/drivers/gpu/msm/adreno_drawctxt.c
index 446df0e98217..94d0e6d6b8dd 100644
--- a/drivers/gpu/msm/adreno_drawctxt.c
+++ b/drivers/gpu/msm/adreno_drawctxt.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2002,2007-2017,2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -609,8 +610,6 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev,
if (drawctxt != NULL && kgsl_context_detached(&drawctxt->base))
return -ENOENT;
- trace_adreno_drawctxt_switch(rb, drawctxt);
-
/* Get a refcount to the new instance */
if (drawctxt) {
if (!_kgsl_context_get(&drawctxt->base))
@@ -623,7 +622,7 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev,
}
ret = adreno_ringbuffer_set_pt_ctx(rb, new_pt, drawctxt, flags);
if (ret)
- return ret;
+ goto err;
if (rb->drawctxt_active) {
/* Wait for the timestamp to expire */
@@ -634,6 +633,13 @@ int adreno_drawctxt_switch(struct adreno_device *adreno_dev,
}
}
+ trace_adreno_drawctxt_switch(rb, drawctxt);
+
rb->drawctxt_active = drawctxt;
+
return 0;
+err:
+ if (drawctxt)
+ kgsl_context_put(&drawctxt->base);
+ return ret;
}
diff --git a/drivers/gpu/msm/adreno_iommu.c b/drivers/gpu/msm/adreno_iommu.c
index 4bb7f6286664..9216d6f07119 100644
--- a/drivers/gpu/msm/adreno_iommu.c
+++ b/drivers/gpu/msm/adreno_iommu.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -890,5 +891,17 @@ int adreno_iommu_set_pt_ctx(struct adreno_ringbuffer *rb,
else
result = _set_ctxt_gpu(rb, drawctxt);
+ /*
+ * In case ctxt switch fails, revert the pagetable back to the
+ * original. Not reverting the pagetable will lead to incorrect
+ * hardware state in the ringbuffer.
+ */
+ if (result && (new_pt != cur_pt)) {
+ if (cpu_path)
+ result = _set_pagetable_cpu(rb, cur_pt);
+ else
+ result = _set_pagetable_gpu(rb, cur_pt);
+ }
+
return result;
}