6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dikshita Agarwal quic_dikshita@quicinc.com
commit d2abb1ff5a3c13321d407ee19865d0d8d834c7c6 upstream.
Validate all internal buffers queued to firmware are released back to driver on close. This helps ensure buffer lifecycle correctness and aids in debugging any resporce leaks.
Cc: stable@vger.kernel.org Fixes: 73702f45db81 ("media: iris: allocate, initialize and queue internal buffers") Tested-by: Neil Armstrong neil.armstrong@linaro.org # on SM8550-QRD Tested-by: Neil Armstrong neil.armstrong@linaro.org # on SM8550-HDK Tested-by: Neil Armstrong neil.armstrong@linaro.org # on SM8650-QRD Tested-by: Neil Armstrong neil.armstrong@linaro.org # on SM8650-HDK Signed-off-by: Dikshita Agarwal quic_dikshita@quicinc.com Tested-by: Vikash Garodia quic_vgarodia@quicinc.com # on sa8775p-ride Signed-off-by: Bryan O'Donoghue bod@kernel.org Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/platform/qcom/iris/iris_vidc.c | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index 663f5602b5ad..a8144595cc78 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -221,6 +221,33 @@ static void iris_session_close(struct iris_inst *inst) iris_wait_for_session_response(inst, false); }
+static void iris_check_num_queued_internal_buffers(struct iris_inst *inst, u32 plane) +{ + const struct iris_platform_data *platform_data = inst->core->iris_platform_data; + struct iris_buffer *buf, *next; + struct iris_buffers *buffers; + const u32 *internal_buf_type; + u32 internal_buffer_count, i; + u32 count = 0; + + if (V4L2_TYPE_IS_OUTPUT(plane)) { + internal_buf_type = platform_data->dec_ip_int_buf_tbl; + internal_buffer_count = platform_data->dec_ip_int_buf_tbl_size; + } else { + internal_buf_type = platform_data->dec_op_int_buf_tbl; + internal_buffer_count = platform_data->dec_op_int_buf_tbl_size; + } + + for (i = 0; i < internal_buffer_count; i++) { + buffers = &inst->buffers[internal_buf_type[i]]; + list_for_each_entry_safe(buf, next, &buffers->list, list) + count++; + if (count) + dev_err(inst->core->dev, "%d buffer of type %d not released", + count, internal_buf_type[i]); + } +} + int iris_close(struct file *filp) { struct iris_inst *inst = iris_get_inst(filp, NULL); @@ -235,6 +262,8 @@ int iris_close(struct file *filp) iris_v4l2_fh_deinit(inst); iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); iris_destroy_all_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + iris_check_num_queued_internal_buffers(inst, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); iris_remove_session(inst); mutex_unlock(&inst->lock); mutex_destroy(&inst->ctx_q_lock);