[PATCH v1 02/11] media: intel/ipu6: fix firmware message buffer leak on send failure

From: Valerii Sokolov

Date: Fri Oct 23 2026 - 15:58:27 EST


ipu6_get_fw_msg_buf() moves a message buffer from isys->framebuflist to
isys->framebuflist_fw. Buffers carrying a frame capture command are
returned to the free pool when the firmware reports
IPU6_FW_ISYS_RESP_TYPE_PIN_DATA_READY for them.

If sending the command fails, in ipu6_isys_start_stream_firmware() via
fw_ops->stream_start() or in buf_queue() via fw_ops->stream_capture(),
the firmware never sees it: both the IPU6 and the IPU7 send paths return
an error before committing a queue token. No PIN_DATA_READY response
will ever arrive, so the buffer stays on framebuflist_fw until
ipu6_cleanup_fw_msg_bufs() reclaims it on the next runtime resume, and
ipu6_get_fw_msg_buf() has to allocate new buffers in the meantime.

Return the buffer to the free pool when sending the command fails.

Buffers whose command was sent, but whose stream start then timed out or
failed, are deliberately left alone: the firmware may still own them,
and they are reclaimed on the next runtime resume.

Fixes: 3c1dfb5a69cf ("media: intel/ipu6: input system video nodes and buffer queues")
Signed-off-by: Valerii Sokolov <valerii.sokolov@xxxxx>
---
drivers/media/pci/intel/ipu6/ipu6-isys-queue.c | 4 +++-
drivers/media/pci/intel/ipu6/ipu6-isys-video.c | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c
index 23d00e1f89..7a38feb911 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-queue.c
@@ -359,8 +359,10 @@ static void buf_queue(struct vb2_buffer *vb)
ipu6_isys_buffer_list_queue(&bl, IPU6_ISYS_BUFFER_LIST_FL_ACTIVE, 0);

ret = fw_ops->stream_capture(stream->isys, stream->stream_handle, msg);
- if (ret < 0)
+ if (ret < 0) {
dev_err(dev, "send stream capture failed\n");
+ ipu6_put_fw_msg_buf(stream->isys, msg);
+ }

out:
mutex_unlock(&stream->mutex);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
index f394e78db6..c7e2dc1311 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
@@ -538,6 +538,7 @@ int ipu6_isys_start_stream_firmware(struct ipu6_isys_stream *stream,
capture);
if (ret < 0) {
dev_err(dev, "can't start streaming (%d)\n", ret);
+ ipu6_put_fw_msg_buf(stream->isys, msg);
goto out_stream_close;
}

--
2.56.0