From: Akhil P Oommen <akhilpo@oss.qualcomm.com>
To: "Rob Clark" <robin.clark@oss.qualcomm.com>,
"Sean Paul" <sean@poorly.run>,
"Konrad Dybcio" <konradybcio@kernel.org>,
"Dmitry Baryshkov" <lumag@kernel.org>,
"Abhinav Kumar" <abhinav.kumar@linux.dev>,
"Jessica Zhang" <jesszhan0024@gmail.com>,
"Marijn Suijten" <marijn.suijten@somainline.org>,
"David Airlie" <airlied@gmail.com>,
"Simona Vetter" <simona@ffwll.ch>,
"Jordan Crouse" <jordan@cosmicpenguin.net>,
"Neil Armstrong" <neil.armstrong@linaro.org>,
"Christian König" <christian.koenig@amd.com>,
"Luben Tuikov" <ltuikov89@gmail.com>,
"Antonino Maniscalco" <antomani103@gmail.com>
Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org,
freedreno@lists.freedesktop.org, linux-kernel@vger.kernel.org,
Akhil P Oommen <akhilpo@oss.qualcomm.com>,
stable@vger.kernel.org
Subject: [PATCH 6/8] drm/msm/a6xx: Reset preemption records across suspend
Date: Sat, 24 Oct 2026 16:00:12 +0530 [thread overview]
Message-ID: <20261024-assorted-fixes-oct-v1-6-2977f974ddb7@oss.qualcomm.com> (raw)
In-Reply-To: <20261024-assorted-fixes-oct-v1-0-2977f974ddb7@oss.qualcomm.com>
The preemption records are initialised only once at probe time. On every
resume, a6xx_preempt_hw_init() and a8xx_preempt_hw_init() refresh only a
subset of the fields (rptr, wptr, rptr_addr, info, data, rbase). Whatever
else the CP wrote into the record before the GPU was power-collapsed
is left in place and gets consumed again by the CP on the next preemption,
now carrying stale context state.
To fix this, zero the whole preemption record on suspend and fully
initialise every field in the hw_init path.
Fixes: e7ae83da4a28 ("drm/msm/a6xx: Implement preemption for a7xx targets")
Cc: stable@vger.kernel.org
Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
---
drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 ++
drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 1 +
drivers/gpu/drm/msm/adreno/a6xx_preempt.c | 37 ++++++++++++++++++-------------
drivers/gpu/drm/msm/adreno/a8xx_preempt.c | 11 ++++++---
4 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
index 92e8c8abb86d..3e4afaa5345f 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
@@ -2248,6 +2248,7 @@ static int a6xx_gmu_pm_suspend(struct msm_gpu *gpu)
for (i = 0; i < gpu->nr_rings; i++)
a6xx_gpu->shadow[i] = 0;
+ a6xx_preempt_record_reset(gpu);
gpu->suspend_count++;
return 0;
@@ -2287,6 +2288,7 @@ static int a6xx_pm_suspend(struct msm_gpu *gpu)
for (i = 0; i < gpu->nr_rings; i++)
a6xx_gpu->shadow[i] = 0;
+ a6xx_preempt_record_reset(gpu);
gpu->suspend_count++;
return 0;
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
index 79912a33e17c..62a19e22e230 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.h
@@ -305,6 +305,7 @@ void a6xx_preempt_hw_init(struct msm_gpu *gpu);
void a6xx_preempt_trigger(struct msm_gpu *gpu);
void a6xx_preempt_irq(struct msm_gpu *gpu);
void a6xx_preempt_fini(struct msm_gpu *gpu);
+void a6xx_preempt_record_reset(struct msm_gpu *gpu);
void a6xx_emit_set_pseudo_reg(struct msm_ringbuffer *ring,
struct a6xx_gpu *a6xx_gpu, struct msm_gpu_submitqueue *queue);
int a6xx_preempt_submitqueue_setup(struct msm_gpu *gpu,
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_preempt.c b/drivers/gpu/drm/msm/adreno/a6xx_preempt.c
index 1e599d4ddea1..df8d4f3e8d4c 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_preempt.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_preempt.c
@@ -140,12 +140,17 @@ void a6xx_preempt_hw_init(struct msm_gpu *gpu)
for (i = 0; i < gpu->nr_rings; i++) {
struct a6xx_preempt_record *record_ptr = a6xx_gpu->preempt[i];
- record_ptr->wptr = 0;
- record_ptr->rptr = 0;
- record_ptr->rptr_addr = shadowptr(a6xx_gpu, gpu->rb[i]);
+ record_ptr->magic = A6XX_PREEMPT_RECORD_MAGIC;
record_ptr->info = 0;
+ record_ptr->errno = 0;
record_ptr->data = 0;
+ record_ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT;
+ record_ptr->rptr = 0;
+ record_ptr->wptr = 0;
+ record_ptr->rptr_addr = shadowptr(a6xx_gpu, gpu->rb[i]);
record_ptr->rbase = gpu->rb[i]->iova;
+ record_ptr->counter = 0;
+ record_ptr->bv_rptr_addr = rbmemptr(gpu->rb[i], bv_rptr);
}
/* Write a 0 to signal that we aren't switching pagetables */
@@ -163,6 +168,19 @@ void a6xx_preempt_hw_init(struct msm_gpu *gpu)
a6xx_gpu->cur_ring = gpu->rb[0];
}
+void a6xx_preempt_record_reset(struct msm_gpu *gpu)
+{
+ struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+ struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
+ int i;
+
+ if (gpu->nr_rings == 1)
+ return;
+
+ for (i = 0; i < gpu->nr_rings; i++)
+ memset(a6xx_gpu->preempt[i], 0, a6xx_gpu->preempt_bo[i]->size);
+}
+
void a6xx_preempt_trigger(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
@@ -302,8 +320,6 @@ static int preempt_init_ring(struct a6xx_gpu *a6xx_gpu,
a6xx_gpu->preempt_iova[ring->id] = iova;
a6xx_gpu->preempt[ring->id] = ptr;
- struct a6xx_preempt_record *record_ptr = ptr;
-
ptr = msm_gem_kernel_new(gpu->dev,
PREEMPT_SMMU_INFO_SIZE,
MSM_BO_WC | MSM_BO_MAP_PRIV | MSM_BO_GPU_READONLY,
@@ -329,17 +345,6 @@ static int preempt_init_ring(struct a6xx_gpu *a6xx_gpu,
smmu_info_ptr->asid = 0xdecafbad;
smmu_info_ptr->context_idr = 0;
- /* Set up the defaults on the preemption record */
- record_ptr->magic = A6XX_PREEMPT_RECORD_MAGIC;
- record_ptr->info = 0;
- record_ptr->data = 0;
- record_ptr->rptr = 0;
- record_ptr->wptr = 0;
- record_ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT;
- record_ptr->rbase = ring->iova;
- record_ptr->counter = 0;
- record_ptr->bv_rptr_addr = rbmemptr(ring, bv_rptr);
-
return 0;
}
diff --git a/drivers/gpu/drm/msm/adreno/a8xx_preempt.c b/drivers/gpu/drm/msm/adreno/a8xx_preempt.c
index 6cb53a071801..0e0503ed54a1 100644
--- a/drivers/gpu/drm/msm/adreno/a8xx_preempt.c
+++ b/drivers/gpu/drm/msm/adreno/a8xx_preempt.c
@@ -121,12 +121,17 @@ void a8xx_preempt_hw_init(struct msm_gpu *gpu)
for (i = 0; i < gpu->nr_rings; i++) {
struct a6xx_preempt_record *record_ptr = a6xx_gpu->preempt[i];
- record_ptr->wptr = 0;
- record_ptr->rptr = 0;
- record_ptr->rptr_addr = shadowptr(a6xx_gpu, gpu->rb[i]);
+ record_ptr->magic = A6XX_PREEMPT_RECORD_MAGIC;
record_ptr->info = 0;
+ record_ptr->errno = 0;
record_ptr->data = 0;
+ record_ptr->cntl = MSM_GPU_RB_CNTL_DEFAULT;
+ record_ptr->rptr = 0;
+ record_ptr->wptr = 0;
+ record_ptr->rptr_addr = shadowptr(a6xx_gpu, gpu->rb[i]);
record_ptr->rbase = gpu->rb[i]->iova;
+ record_ptr->counter = 0;
+ record_ptr->bv_rptr_addr = rbmemptr(gpu->rb[i], bv_rptr);
}
/* Write a 0 to signal that we aren't switching pagetables */
--
2.55.0
next prev parent reply other threads:[~2026-10-24 10:31 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-24 10:30 [PATCH 0/8] drm/msm: Assorted fixes - October Akhil P Oommen
2026-10-24 10:30 ` [PATCH 1/8] drm/msm/a6xx: Check BX dependency vote index Akhil P Oommen
2026-10-24 10:30 ` [PATCH 2/8] drm/msm/a6xx: Fix GMU shutdown idle check Akhil P Oommen
2026-10-24 10:30 ` [PATCH 3/8] drm/msm/a6xx: Fix stale boot up BW vote Akhil P Oommen
2026-10-24 10:30 ` [PATCH 4/8] drm/msm/devfreq: Record idle_time at GPU idle onset Akhil P Oommen
2026-10-24 10:30 ` [PATCH 5/8] drm/msm: Fix sched_prio inversion within a ring Akhil P Oommen
2026-10-24 10:30 ` Akhil P Oommen [this message]
2026-10-24 18:29 ` [PATCH 6/8] drm/msm/a6xx: Reset preemption records across suspend Connor Abbott
2026-10-24 10:30 ` [PATCH 7/8] drm/msm/a6xx: Request CLX enable from secure world Akhil P Oommen
2026-10-24 10:30 ` [PATCH 8/8] drm/msm/a8xx: Add AQE firmware to Adreno X2-90 GPU Akhil P Oommen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261024-assorted-fixes-oct-v1-6-2977f974ddb7@oss.qualcomm.com \
--to=akhilpo@oss.qualcomm.com \
--cc=abhinav.kumar@linux.dev \
--cc=airlied@gmail.com \
--cc=antomani103@gmail.com \
--cc=christian.koenig@amd.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=jesszhan0024@gmail.com \
--cc=jordan@cosmicpenguin.net \
--cc=konradybcio@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ltuikov89@gmail.com \
--cc=lumag@kernel.org \
--cc=marijn.suijten@somainline.org \
--cc=neil.armstrong@linaro.org \
--cc=robin.clark@oss.qualcomm.com \
--cc=sean@poorly.run \
--cc=simona@ffwll.ch \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®