Commit d2abb1ff authored by Dikshita Agarwal's avatar Dikshita Agarwal Committed by Hans Verkuil
Browse files

media: iris: Verify internal buffer release on close



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: 73702f45 ("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: default avatarDikshita Agarwal <quic_dikshita@quicinc.com>
Tested-by: Vikash Garodia <quic_vgarodia@quicinc.com> # on sa8775p-ride
Signed-off-by: default avatarBryan O'Donoghue <bod@kernel.org>
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
parent 7c452ffd
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -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);