* [PATCH v2 0/2] media: chips-media: wave5: Handle decoder runtime resume failures
@ 2026-07-18 13:00 Guangshuo Li
2026-07-18 13:00 ` [PATCH v2 1/2] media: chips-media: wave5: Check decoder qbuf runtime resume Guangshuo Li
2026-07-18 13:00 ` [PATCH v2 2/2] media: chips-media: wave5: Check decoder runtime resume errors Guangshuo Li
0 siblings, 2 replies; 6+ messages in thread
From: Guangshuo Li @ 2026-07-18 13:00 UTC (permalink / raw)
To: Nas Chung, Jackson Lee, Mauro Carvalho Chehab, Nicolas Dufresne,
Hans Verkuil, linux-media, linux-kernel
This series checks the return value from every
pm_runtime_resume_and_get() call in wave5-vpu-dec.c.
The first patch fixes the capture-buffer queue path introduced by
cbb9c0d50e47. The second patch fixes the start-streaming,
stop-streaming and device-run paths introduced by 2092b3833487.
On a runtime resume failure, the decoder must not continue accessing VPU
registers. Since pm_runtime_resume_and_get() does not retain a runtime PM
usage reference on failure, these paths must also avoid calling an
unmatched pm_runtime_put_autosuspend().
Each callback now handles the failure according to its interface by
returning or completing queued buffers, cleaning up the stop-streaming
path without touching hardware, or finishing the current mem2mem job.
v2:
- Check all four pm_runtime_resume_and_get() call sites in
wave5-vpu-dec.c, as suggested by Nicolas.
- Split the changes into two patches according to the commits that
introduced the affected calls.
- Add callback-specific cleanup for runtime resume failures.
Guangshuo Li (2):
media: chips-media: wave5: Check decoder qbuf runtime resume
media: chips-media: wave5: Check decoder runtime resume errors
.../chips-media/wave5/wave5-vpu-dec.c | 44 +++++++++++++++++--
1 file changed, 40 insertions(+), 4 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/2] media: chips-media: wave5: Check decoder qbuf runtime resume
2026-07-18 13:00 [PATCH v2 0/2] media: chips-media: wave5: Handle decoder runtime resume failures Guangshuo Li
@ 2026-07-18 13:00 ` Guangshuo Li
2026-09-28 21:10 ` Nicolas Dufresne
2026-07-18 13:00 ` [PATCH v2 2/2] media: chips-media: wave5: Check decoder runtime resume errors Guangshuo Li
1 sibling, 1 reply; 6+ messages in thread
From: Guangshuo Li @ 2026-07-18 13:00 UTC (permalink / raw)
To: Nas Chung, Jackson Lee, Mauro Carvalho Chehab, Nicolas Dufresne,
Hans Verkuil, linux-media, linux-kernel
Cc: Guangshuo Li
wave5_vpu_dec_buf_queue_dst() resumes the VPU before it may clear a
decoder display flag. This is needed because clearing the display flag
accesses VPU registers.
However, the return value from pm_runtime_resume_and_get() is ignored.
If the resume fails, pm_runtime_resume_and_get() returns without holding
a runtime PM usage reference. The unconditional
pm_runtime_put_autosuspend() at the end of the function then drops an
unmatched reference.
The failed resume path can also continue into
wave5_vpu_dec_clr_disp_flag() while the device is still suspended.
Check the return value. If the resume fails, complete the queued buffer
with an error and return without touching the hardware or dropping an
unmatched runtime PM reference.
Fixes: cbb9c0d50e47 ("media: chips-media: wave5: Fix SError of kernel panic when closed")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
index bb2ba9204a83..03d108b808ba 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
@@ -1290,8 +1290,14 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb)
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct vpu_instance *inst = vb2_get_drv_priv(vb->vb2_queue);
struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
+ int ret;
+
+ ret = pm_runtime_resume_and_get(inst->dev->dev);
+ if (ret < 0) {
+ vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
+ return;
+ }
- pm_runtime_resume_and_get(inst->dev->dev);
vbuf->sequence = inst->queued_dst_buf_num++;
if (inst->state == VPU_INST_STATE_PIC_RUN) {
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] media: chips-media: wave5: Check decoder runtime resume errors
2026-07-18 13:00 [PATCH v2 0/2] media: chips-media: wave5: Handle decoder runtime resume failures Guangshuo Li
2026-07-18 13:00 ` [PATCH v2 1/2] media: chips-media: wave5: Check decoder qbuf runtime resume Guangshuo Li
@ 2026-07-18 13:00 ` Guangshuo Li
2026-09-28 21:13 ` Nicolas Dufresne
1 sibling, 1 reply; 6+ messages in thread
From: Guangshuo Li @ 2026-07-18 13:00 UTC (permalink / raw)
To: Nas Chung, Jackson Lee, Mauro Carvalho Chehab, Nicolas Dufresne,
Hans Verkuil, linux-media, linux-kernel
Cc: Guangshuo Li
The decoder start_streaming, stop_streaming and device_run callbacks
resume the VPU before accessing hardware, but do not check the return
value from pm_runtime_resume_and_get().
If runtime resume fails, continuing can access the VPU while it remains
suspended. Since pm_runtime_resume_and_get() does not retain a runtime PM
usage reference on failure, the later unconditional
pm_runtime_put_autosuspend() can also drop an unmatched reference.
Check the return value in all three callbacks. Return queued buffers as
required by vb2 when start_streaming fails, clean up buffers without
touching hardware when stop_streaming fails, and finish the current
mem2mem job when device_run cannot resume.
Only call pm_runtime_put_autosuspend() after a successful runtime
resume.
Fixes: 2092b3833487 ("media: chips-media: wave5: Support runtime suspend/resume")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
---
.../chips-media/wave5/wave5-vpu-dec.c | 36 +++++++++++++++++--
1 file changed, 33 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
index 03d108b808ba..bb59bc962603 100644
--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
@@ -1380,7 +1380,11 @@ static int wave5_vpu_dec_start_streaming(struct vb2_queue *q, unsigned int count
int ret = 0;
dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
- pm_runtime_resume_and_get(inst->dev->dev);
+ ret = pm_runtime_resume_and_get(inst->dev->dev);
+ if (ret < 0) {
+ wave5_return_bufs(q, VB2_BUF_STATE_QUEUED);
+ return ret;
+ }
v4l2_m2m_update_start_streaming_state(m2m_ctx, q);
@@ -1544,9 +1548,29 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q)
struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
bool check_cmd = TRUE;
+ int ret;
dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
- pm_runtime_resume_and_get(inst->dev->dev);
+ ret = pm_runtime_resume_and_get(inst->dev->dev);
+ if (ret < 0) {
+ struct vpu_src_buffer *vpu_buf;
+
+ v4l2_m2m_update_stop_streaming_state(m2m_ctx, q);
+
+ if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
+ inst->retry = false;
+ inst->queuing_num = 0;
+ while ((vpu_buf = inst_src_buf_remove(inst)) != NULL)
+ ;
+ inst->eos = false;
+ }
+
+ wave5_return_bufs(q, VB2_BUF_STATE_ERROR);
+ inst->empty_queue = false;
+ inst->sent_eos = false;
+ return;
+ }
+
inst->empty_queue = true;
while (check_cmd) {
struct queue_status_info q_status;
@@ -1659,7 +1683,13 @@ static void wave5_vpu_dec_device_run(void *priv)
int ret = 0;
dev_dbg(inst->dev->dev, "%s: Fill the ring buffer with new bitstream data", __func__);
- pm_runtime_resume_and_get(inst->dev->dev);
+
+ ret = pm_runtime_resume_and_get(inst->dev->dev);
+ if (ret < 0) {
+ v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
+ return;
+ }
+
if (!inst->retry) {
ret = fill_ringbuffer(inst);
if (ret < 0) {
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] media: chips-media: wave5: Check decoder qbuf runtime resume
2026-07-18 13:00 ` [PATCH v2 1/2] media: chips-media: wave5: Check decoder qbuf runtime resume Guangshuo Li
@ 2026-09-28 21:10 ` Nicolas Dufresne
0 siblings, 0 replies; 6+ messages in thread
From: Nicolas Dufresne @ 2026-09-28 21:10 UTC (permalink / raw)
To: Guangshuo Li, Nas Chung, Jackson Lee, Mauro Carvalho Chehab,
Hans Verkuil, linux-media, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2127 bytes --]
Le samedi 18 juillet 2026 à 21:00 +0800, Guangshuo Li a écrit :
> wave5_vpu_dec_buf_queue_dst() resumes the VPU before it may clear a
> decoder display flag. This is needed because clearing the display flag
> accesses VPU registers.
>
> However, the return value from pm_runtime_resume_and_get() is ignored.
> If the resume fails, pm_runtime_resume_and_get() returns without holding
> a runtime PM usage reference. The unconditional
> pm_runtime_put_autosuspend() at the end of the function then drops an
> unmatched reference.
>
> The failed resume path can also continue into
> wave5_vpu_dec_clr_disp_flag() while the device is still suspended.
>
> Check the return value. If the resume fails, complete the queued buffer
> with an error and return without touching the hardware or dropping an
> unmatched runtime PM reference.
>
> Fixes: cbb9c0d50e47 ("media: chips-media: wave5: Fix SError of kernel panic when closed")
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Picked, ty
> ---
> drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c | 8 +++++++-
> 1 file changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
> index bb2ba9204a83..03d108b808ba 100644
> --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
> +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
> @@ -1290,8 +1290,14 @@ static void wave5_vpu_dec_buf_queue_dst(struct vb2_buffer *vb)
> struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
> struct vpu_instance *inst = vb2_get_drv_priv(vb->vb2_queue);
> struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
> + int ret;
> +
> + ret = pm_runtime_resume_and_get(inst->dev->dev);
> + if (ret < 0) {
> + vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
> + return;
> + }
>
> - pm_runtime_resume_and_get(inst->dev->dev);
> vbuf->sequence = inst->queued_dst_buf_num++;
>
> if (inst->state == VPU_INST_STATE_PIC_RUN) {
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] media: chips-media: wave5: Check decoder runtime resume errors
2026-07-18 13:00 ` [PATCH v2 2/2] media: chips-media: wave5: Check decoder runtime resume errors Guangshuo Li
@ 2026-09-28 21:13 ` Nicolas Dufresne
2026-09-28 21:21 ` Nicolas Dufresne
0 siblings, 1 reply; 6+ messages in thread
From: Nicolas Dufresne @ 2026-09-28 21:13 UTC (permalink / raw)
To: Guangshuo Li, Nas Chung, Jackson Lee, Mauro Carvalho Chehab,
Hans Verkuil, linux-media, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 3458 bytes --]
Le samedi 18 juillet 2026 à 21:00 +0800, Guangshuo Li a écrit :
> The decoder start_streaming, stop_streaming and device_run callbacks
> resume the VPU before accessing hardware, but do not check the return
> value from pm_runtime_resume_and_get().
>
> If runtime resume fails, continuing can access the VPU while it remains
> suspended. Since pm_runtime_resume_and_get() does not retain a runtime PM
> usage reference on failure, the later unconditional
> pm_runtime_put_autosuspend() can also drop an unmatched reference.
>
> Check the return value in all three callbacks. Return queued buffers as
> required by vb2 when start_streaming fails, clean up buffers without
> touching hardware when stop_streaming fails, and finish the current
> mem2mem job when device_run cannot resume.
>
> Only call pm_runtime_put_autosuspend() after a successful runtime
> resume.
>
> Fixes: 2092b3833487 ("media: chips-media: wave5: Support runtime suspend/resume")
> Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Nicolas Dufresne ņicolas.dufresne@collabora.com>
Picked, ty
> ---
> .../chips-media/wave5/wave5-vpu-dec.c | 36 +++++++++++++++++--
> 1 file changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
> index 03d108b808ba..bb59bc962603 100644
> --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
> +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
> @@ -1380,7 +1380,11 @@ static int wave5_vpu_dec_start_streaming(struct vb2_queue *q, unsigned int count
> int ret = 0;
>
> dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
> - pm_runtime_resume_and_get(inst->dev->dev);
> + ret = pm_runtime_resume_and_get(inst->dev->dev);
> + if (ret < 0) {
> + wave5_return_bufs(q, VB2_BUF_STATE_QUEUED);
> + return ret;
> + }
>
> v4l2_m2m_update_start_streaming_state(m2m_ctx, q);
>
> @@ -1544,9 +1548,29 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q)
> struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
>
> bool check_cmd = TRUE;
> + int ret;
>
> dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
> - pm_runtime_resume_and_get(inst->dev->dev);
> + ret = pm_runtime_resume_and_get(inst->dev->dev);
> + if (ret < 0) {
> + struct vpu_src_buffer *vpu_buf;
> +
> + v4l2_m2m_update_stop_streaming_state(m2m_ctx, q);
> +
> + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> + inst->retry = false;
> + inst->queuing_num = 0;
> + while ((vpu_buf = inst_src_buf_remove(inst)) != NULL)
> + ;
> + inst->eos = false;
> + }
> +
> + wave5_return_bufs(q, VB2_BUF_STATE_ERROR);
> + inst->empty_queue = false;
> + inst->sent_eos = false;
> + return;
> + }
> +
> inst->empty_queue = true;
> while (check_cmd) {
> struct queue_status_info q_status;
> @@ -1659,7 +1683,13 @@ static void wave5_vpu_dec_device_run(void *priv)
> int ret = 0;
>
> dev_dbg(inst->dev->dev, "%s: Fill the ring buffer with new bitstream data", __func__);
> - pm_runtime_resume_and_get(inst->dev->dev);
> +
> + ret = pm_runtime_resume_and_get(inst->dev->dev);
> + if (ret < 0) {
> + v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
> + return;
> + }
> +
> if (!inst->retry) {
> ret = fill_ringbuffer(inst);
> if (ret < 0) {
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 2/2] media: chips-media: wave5: Check decoder runtime resume errors
2026-09-28 21:13 ` Nicolas Dufresne
@ 2026-09-28 21:21 ` Nicolas Dufresne
0 siblings, 0 replies; 6+ messages in thread
From: Nicolas Dufresne @ 2026-09-28 21:21 UTC (permalink / raw)
To: Guangshuo Li, Nas Chung, Jackson Lee, Mauro Carvalho Chehab,
Hans Verkuil, linux-media, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 3852 bytes --]
Le lundi 28 septembre 2026 à 17:13 -0400, Nicolas Dufresne a écrit :
> Le samedi 18 juillet 2026 à 21:00 +0800, Guangshuo Li a écrit :
> > The decoder start_streaming, stop_streaming and device_run callbacks
> > resume the VPU before accessing hardware, but do not check the return
> > value from pm_runtime_resume_and_get().
> >
> > If runtime resume fails, continuing can access the VPU while it remains
> > suspended. Since pm_runtime_resume_and_get() does not retain a runtime PM
> > usage reference on failure, the later unconditional
> > pm_runtime_put_autosuspend() can also drop an unmatched reference.
> >
> > Check the return value in all three callbacks. Return queued buffers as
> > required by vb2 when start_streaming fails, clean up buffers without
> > touching hardware when stop_streaming fails, and finish the current
> > mem2mem job when device_run cannot resume.
> >
> > Only call pm_runtime_put_autosuspend() after a successful runtime
> > resume.
> >
> > Fixes: 2092b3833487 ("media: chips-media: wave5: Support runtime suspend/resume")
> > Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
>
> Reviewed-by: Nicolas Dufresne ņicolas.dufresne@collabora.com>
>
> Picked, ty
Spoken too fast, I picked the first, please rebase and resubmit this one, it has
conflicts that are non trivial to fix.
Nicolas
>
> > ---
> > .../chips-media/wave5/wave5-vpu-dec.c | 36 +++++++++++++++++--
> > 1 file changed, 33 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
> > index 03d108b808ba..bb59bc962603 100644
> > --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
> > +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
> > @@ -1380,7 +1380,11 @@ static int wave5_vpu_dec_start_streaming(struct vb2_queue *q, unsigned int count
> > int ret = 0;
> >
> > dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
> > - pm_runtime_resume_and_get(inst->dev->dev);
> > + ret = pm_runtime_resume_and_get(inst->dev->dev);
> > + if (ret < 0) {
> > + wave5_return_bufs(q, VB2_BUF_STATE_QUEUED);
> > + return ret;
> > + }
> >
> > v4l2_m2m_update_start_streaming_state(m2m_ctx, q);
> >
> > @@ -1544,9 +1548,29 @@ static void wave5_vpu_dec_stop_streaming(struct vb2_queue *q)
> > struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
> >
> > bool check_cmd = TRUE;
> > + int ret;
> >
> > dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
> > - pm_runtime_resume_and_get(inst->dev->dev);
> > + ret = pm_runtime_resume_and_get(inst->dev->dev);
> > + if (ret < 0) {
> > + struct vpu_src_buffer *vpu_buf;
> > +
> > + v4l2_m2m_update_stop_streaming_state(m2m_ctx, q);
> > +
> > + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
> > + inst->retry = false;
> > + inst->queuing_num = 0;
> > + while ((vpu_buf = inst_src_buf_remove(inst)) != NULL)
> > + ;
> > + inst->eos = false;
> > + }
> > +
> > + wave5_return_bufs(q, VB2_BUF_STATE_ERROR);
> > + inst->empty_queue = false;
> > + inst->sent_eos = false;
> > + return;
> > + }
> > +
> > inst->empty_queue = true;
> > while (check_cmd) {
> > struct queue_status_info q_status;
> > @@ -1659,7 +1683,13 @@ static void wave5_vpu_dec_device_run(void *priv)
> > int ret = 0;
> >
> > dev_dbg(inst->dev->dev, "%s: Fill the ring buffer with new bitstream data", __func__);
> > - pm_runtime_resume_and_get(inst->dev->dev);
> > +
> > + ret = pm_runtime_resume_and_get(inst->dev->dev);
> > + if (ret < 0) {
> > + v4l2_m2m_job_finish(inst->v4l2_m2m_dev, m2m_ctx);
> > + return;
> > + }
> > +
> > if (!inst->retry) {
> > ret = fill_ringbuffer(inst);
> > if (ret < 0) {
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-28 21:21 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-18 13:00 [PATCH v2 0/2] media: chips-media: wave5: Handle decoder runtime resume failures Guangshuo Li
2026-07-18 13:00 ` [PATCH v2 1/2] media: chips-media: wave5: Check decoder qbuf runtime resume Guangshuo Li
2026-09-28 21:10 ` Nicolas Dufresne
2026-07-18 13:00 ` [PATCH v2 2/2] media: chips-media: wave5: Check decoder runtime resume errors Guangshuo Li
2026-09-28 21:13 ` Nicolas Dufresne
2026-09-28 21:21 ` Nicolas Dufresne
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®