]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
media: iris: Verify internal buffer release on close
authorDikshita Agarwal <quic_dikshita@quicinc.com>
Fri, 9 May 2025 08:38:48 +0000 (14:08 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Aug 2025 14:34:29 +0000 (16:34 +0200)
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

index 663f5602b5ad29f273f01b59328da104b79e1d84..a8144595cc78e8fbe33ad5bfa9688f96f2ef8ea6 100644 (file)
@@ -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);