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

Commit 5e02c63e authored by Maheshwar Ajja's avatar Maheshwar Ajja
Browse files

msm: vidc: Fix double list_del in rbr event processing



Do not use mbuf after kref_put_mbuf() instead get the
mbuf from the registered bufs list to use it again.
Using the same mbuf after kref_put_mbuf() might lead to
video failures.

Change-Id: I69f03ca1f9b7d607d407952e7a83d4977962cc5d
Signed-off-by: default avatarMaheshwar Ajja <majja@codeaurora.org>
parent 2b6a49e9
Loading
Loading
Loading
Loading
+12 −4
Original line number Original line Diff line number Diff line
@@ -6269,6 +6269,7 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst,
	struct msm_vidc_buffer *temp;
	struct msm_vidc_buffer *temp;
	bool found = false;
	bool found = false;
	int i = 0;
	int i = 0;
	u32 planes[VIDEO_MAX_PLANES] = {0};


	mutex_lock(&inst->flush_lock);
	mutex_lock(&inst->flush_lock);
	mutex_lock(&inst->registeredbufs.lock);
	mutex_lock(&inst->registeredbufs.lock);
@@ -6282,6 +6283,10 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst,
		}
		}
	}
	}
	if (found) {
	if (found) {
		/* save device_addr */
		for (i = 0; i < mbuf->vvb.vb2_buf.num_planes; i++)
			planes[i] = mbuf->smem[i].device_addr;

		/* send RBR event to client */
		/* send RBR event to client */
		msm_vidc_queue_rbr_event(inst,
		msm_vidc_queue_rbr_event(inst,
			mbuf->vvb.vb2_buf.planes[0].m.fd,
			mbuf->vvb.vb2_buf.planes[0].m.fd,
@@ -6299,6 +6304,7 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst,
		if (!mbuf->smem[0].refcount) {
		if (!mbuf->smem[0].refcount) {
			list_del(&mbuf->list);
			list_del(&mbuf->list);
			kref_put_mbuf(mbuf);
			kref_put_mbuf(mbuf);
			mbuf = NULL;
		}
		}
	} else {
	} else {
		print_vidc_buffer(VIDC_ERR, "mbuf not found", inst, mbuf);
		print_vidc_buffer(VIDC_ERR, "mbuf not found", inst, mbuf);
@@ -6316,8 +6322,8 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst,
	 */
	 */
	found = false;
	found = false;
	list_for_each_entry(temp, &inst->registeredbufs.list, list) {
	list_for_each_entry(temp, &inst->registeredbufs.list, list) {
		if (msm_comm_compare_vb2_plane(inst, mbuf,
		if (msm_comm_compare_device_plane(temp, planes, 0)) {
				&temp->vvb.vb2_buf, 0)) {
			mbuf = temp;
			found = true;
			found = true;
			break;
			break;
		}
		}
@@ -6337,9 +6343,11 @@ void handle_release_buffer_reference(struct msm_vidc_inst *inst,
		/* don't queue the buffer */
		/* don't queue the buffer */
		found = false;
		found = false;
	}
	}
	/* clear DEFERRED flag, if any, as the buffer is going to be queued */
	/* clear required flags as the buffer is going to be queued */
	if (found)
	if (found) {
		mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED;
		mbuf->flags &= ~MSM_VIDC_FLAG_DEFERRED;
		mbuf->flags &= ~MSM_VIDC_FLAG_RBR_PENDING;
	}


unlock:
unlock:
	mutex_unlock(&inst->registeredbufs.lock);
	mutex_unlock(&inst->registeredbufs.lock);