Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 26f2554b authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: access vb2 buffer under vb2_queue lock"

parents 78033016 f142eece
Loading
Loading
Loading
Loading
+77 −79
Original line number Diff line number Diff line
@@ -2322,9 +2322,13 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer(
		return NULL;
	}

	q = &inst->bufq[port].vb2_bufq;
	mutex_lock(&inst->bufq[port].lock);
	found = false;
	q = &inst->bufq[port].vb2_bufq;
	if (!q->streaming) {
		dprintk(VIDC_ERR, "port %d is not streaming", port);
		goto unlock;
	}
	list_for_each_entry(vb, &q->queued_list, queued_entry) {
		if (vb->state != VB2_BUF_STATE_ACTIVE)
			continue;
@@ -2333,6 +2337,7 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer(
			break;
		}
	}
unlock:
	mutex_unlock(&inst->bufq[port].lock);
	if (!found) {
		print_vidc_buffer(VIDC_ERR, "vb2 not found for", inst, mbuf);
@@ -2343,28 +2348,52 @@ struct vb2_buffer *msm_comm_get_vb_using_vidc_buffer(
}

int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst,
		struct vb2_buffer *vb)
		struct msm_vidc_buffer *mbuf)
{
	u32 port;
	struct vb2_buffer *vb2;
	struct vb2_v4l2_buffer *vbuf;
	u32 i, port;

	if (!inst || !vb) {
	if (!inst || !mbuf) {
		dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n",
			__func__, inst, vb);
			__func__, inst, mbuf);
		return -EINVAL;
	}

	if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
	if (mbuf->vvb.vb2_buf.type ==
			V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
		port = CAPTURE_PORT;
	} else if (vb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
	else if (mbuf->vvb.vb2_buf.type ==
			V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
		port = OUTPUT_PORT;
	} else {
		dprintk(VIDC_ERR, "%s: invalid type %d\n",
			__func__, vb->type);
	else
		return -EINVAL;

	vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf);
	if (!vb2)
		return -EINVAL;
	}

	/*
	 * access vb2 buffer under q->lock and if streaming only to
	 * ensure the buffer was not free'd by vb2 framework while
	 * we are accessing it here.
	 */
	mutex_lock(&inst->bufq[port].lock);
	vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
	if (inst->bufq[port].vb2_bufq.streaming) {
		vbuf = to_vb2_v4l2_buffer(vb2);
		vbuf->flags = mbuf->vvb.flags;
		vb2->timestamp = mbuf->vvb.vb2_buf.timestamp;
		for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) {
			vb2->planes[i].bytesused =
				mbuf->vvb.vb2_buf.planes[i].bytesused;
			vb2->planes[i].data_offset =
				mbuf->vvb.vb2_buf.planes[i].data_offset;
		}
		vb2_buffer_done(vb2, VB2_BUF_STATE_DONE);
	} else {
		dprintk(VIDC_ERR, "%s: port %d is not streaming\n",
			__func__, port);
	}
	mutex_unlock(&inst->bufq[port].lock);

	return 0;
@@ -2438,12 +2467,11 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
{
	struct msm_vidc_cb_data_done *response = data;
	struct msm_vidc_buffer *mbuf;
	struct vb2_buffer *vb, *vb2;
	struct vb2_buffer *vb;
	struct msm_vidc_inst *inst;
	struct vidc_hal_ebd *empty_buf_done;
	struct vb2_v4l2_buffer *vbuf;
	u32 planes[VIDEO_MAX_PLANES] = {0};
	u32 extra_idx = 0, i;
	u32 extra_idx = 0;

	if (!response) {
		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
@@ -2476,15 +2504,6 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
			__func__, planes[0], planes[1]);
		goto exit;
	}
	vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf);

	/*
	 * take registeredbufs.lock to update mbuf & vb2 variables together
	 * so that both are in sync else if mbuf and vb2 variables are not
	 * in sync msm_comm_compare_vb2_planes() returns false for the
	 * right buffer due to data_offset field mismatch.
	 */
	mutex_lock(&inst->registeredbufs.lock);
	vb = &mbuf->vvb.vb2_buf;

	vb->planes[0].bytesused = response->input_done.filled_len;
@@ -2510,18 +2529,6 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
	if (extra_idx && extra_idx < VIDEO_MAX_PLANES)
		vb->planes[extra_idx].bytesused = vb->planes[extra_idx].length;

	if (vb2) {
		vbuf = to_vb2_v4l2_buffer(vb2);
		vbuf->flags |= mbuf->vvb.flags;
		for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) {
			vb2->planes[i].bytesused =
				mbuf->vvb.vb2_buf.planes[i].bytesused;
			vb2->planes[i].data_offset =
				mbuf->vvb.vb2_buf.planes[i].data_offset;
		}
	}
	mutex_unlock(&inst->registeredbufs.lock);

	update_recon_stats(inst, &empty_buf_done->recon_stats);
	msm_vidc_clear_freq_entry(inst, mbuf->smem[0].device_addr);
	/*
@@ -2535,7 +2542,7 @@ static void handle_ebd(enum hal_command_response cmd, void *data)
	 * in put_buffer.
	 */
	msm_comm_put_vidc_buffer(inst, mbuf);
	msm_comm_vb2_buffer_done(inst, vb2);
	msm_comm_vb2_buffer_done(inst, mbuf);
	msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_EBD);
	kref_put_mbuf(mbuf);
exit:
@@ -2589,13 +2596,12 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
	struct msm_vidc_cb_data_done *response = data;
	struct msm_vidc_buffer *mbuf;
	struct msm_vidc_inst *inst;
	struct vb2_buffer *vb, *vb2;
	struct vb2_buffer *vb;
	struct vidc_hal_fbd *fill_buf_done;
	struct vb2_v4l2_buffer *vbuf;
	enum hal_buffer buffer_type;
	u64 time_usec = 0;
	u32 planes[VIDEO_MAX_PLANES] = {0};
	u32 extra_idx, i;
	u32 extra_idx;

	if (!response) {
		dprintk(VIDC_ERR, "Invalid response from vidc_hal\n");
@@ -2623,7 +2629,6 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
				__func__, planes[0], planes[1]);
			goto exit;
		}
		vb2 = msm_comm_get_vb_using_vidc_buffer(inst, mbuf);
	} else {
		if (handle_multi_stream_buffers(inst,
				fill_buf_done->packet_buffer1))
@@ -2632,14 +2637,6 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
				&fill_buf_done->packet_buffer1);
		goto exit;
	}

	/*
	 * take registeredbufs.lock to update mbuf & vb2 variables together
	 * so that both are in sync else if mbuf and vb2 variables are not
	 * in sync msm_comm_compare_vb2_planes() returns false for the
	 * right buffer due to data_offset field mismatch.
	 */
	mutex_lock(&inst->registeredbufs.lock);
	vb = &mbuf->vvb.vb2_buf;

	if (fill_buf_done->flags1 & HAL_BUFFERFLAG_DROP_FRAME)
@@ -2698,19 +2695,6 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
		break;
	}

	if (vb2) {
		vbuf = to_vb2_v4l2_buffer(vb2);
		vbuf->flags = mbuf->vvb.flags;
		vb2->timestamp = mbuf->vvb.vb2_buf.timestamp;
		for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++) {
			vb2->planes[i].bytesused =
				mbuf->vvb.vb2_buf.planes[i].bytesused;
			vb2->planes[i].data_offset =
				mbuf->vvb.vb2_buf.planes[i].data_offset;
		}
	}
	mutex_unlock(&inst->registeredbufs.lock);

	/*
	 * dma cache operations need to be performed before dma_unmap
	 * which is done inside msm_comm_put_vidc_buffer()
@@ -2722,7 +2706,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
	 * in put_buffer.
	 */
	msm_comm_put_vidc_buffer(inst, mbuf);
	msm_comm_vb2_buffer_done(inst, vb2);
	msm_comm_vb2_buffer_done(inst, mbuf);
	msm_vidc_debugfs_update(inst, MSM_VIDC_DEBUGFS_EVENT_FBD);
	kref_put_mbuf(mbuf);

@@ -6100,7 +6084,6 @@ bool msm_comm_compare_vb2_plane(struct msm_vidc_inst *inst,

	vb = &mbuf->vvb.vb2_buf;
	if (vb->planes[i].m.fd == vb2->planes[i].m.fd &&
		vb->planes[i].data_offset == vb2->planes[i].data_offset &&
		vb->planes[i].length == vb2->planes[i].length) {
		return true;
	}
@@ -6232,6 +6215,7 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst,
{
	int rc;
	struct vb2_buffer *vb;
	u32 port;

	if (!inst || !mbuf) {
		dprintk(VIDC_ERR, "%s: invalid params %pK %pK\n",
@@ -6246,11 +6230,24 @@ int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst,
		return -EINVAL;
	}

	if (mbuf->vvb.vb2_buf.type ==
			V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
		port = CAPTURE_PORT;
	else if (mbuf->vvb.vb2_buf.type ==
			V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
		port = OUTPUT_PORT;
	else
		return -EINVAL;

	mutex_lock(&inst->bufq[port].lock);
	if (inst->bufq[port].vb2_bufq.streaming) {
		vb->planes[0].bytesused = 0;
	rc = msm_comm_vb2_buffer_done(inst, vb);
	if (rc)
		print_vidc_buffer(VIDC_ERR,
			"vb2_buffer_done failed for", inst, mbuf);
		vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
	} else {
		dprintk(VIDC_ERR, "%s: port %d is not streaming\n",
			__func__, port);
	}
	mutex_unlock(&inst->bufq[port].lock);

	return rc;
}
@@ -6415,23 +6412,24 @@ struct msm_vidc_buffer *msm_comm_get_vidc_buffer(struct msm_vidc_inst *inst,
	}

	mutex_lock(&inst->registeredbufs.lock);
	if (inst->session_type == MSM_VIDC_DECODER) {
	/*
	 * for encoder input, client may queue the same buffer with different
	 * fd before driver returned old buffer to the client. This buffer
	 * should be treated as new buffer Search the list with fd so that
	 * it will be treated as new msm_vidc_buffer.
	 */
	if (is_encode_session(inst) && vb2->type ==
			V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
		list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
			if (msm_comm_compare_dma_planes(inst, mbuf,
					dma_planes)) {
			if (msm_comm_compare_vb2_planes(inst, mbuf, vb2)) {
				found = true;
				break;
			}
		}
	} else {
		/*
		 * for encoder, client may queue the same buffer with different
		 * fd before driver returned old buffer to the client. This
		 * buffer should be treated as new buffer. Search the list with
		 * fd so that it will be treated as new msm_vidc_buffer.
		 */
		list_for_each_entry(mbuf, &inst->registeredbufs.list, list) {
			if (msm_comm_compare_vb2_planes(inst, mbuf, vb2)) {
			if (msm_comm_compare_dma_planes(inst, mbuf,
					dma_planes)) {
				found = true;
				break;
			}
+1 −1
Original line number Diff line number Diff line
@@ -214,7 +214,7 @@ void msm_comm_put_vidc_buffer(struct msm_vidc_inst *inst,
void handle_release_buffer_reference(struct msm_vidc_inst *inst,
		struct msm_vidc_buffer *mbuf);
int msm_comm_vb2_buffer_done(struct msm_vidc_inst *inst,
		struct vb2_buffer *vb);
		struct msm_vidc_buffer *mbuf);
int msm_comm_flush_vidc_buffer(struct msm_vidc_inst *inst,
		struct msm_vidc_buffer *mbuf);
int msm_comm_unmap_vidc_buffer(struct msm_vidc_inst *inst,