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

Commit 95bbf3ac authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: vidc: Clean up video instance locking logic"

parents 71d00a58 808995c0
Loading
Loading
Loading
Loading
+13 −16
Original line number Diff line number Diff line
@@ -1395,7 +1395,7 @@ static int msm_vdec_queue_setup(struct vb2_queue *q,
				"Failed to get buffer requirements: %d\n", rc);
			break;
		}
		mutex_lock(&inst->lock);

		bufreq = get_buff_req_buffer(inst,
			msm_comm_get_hal_output_buffer(inst));
		if (!bufreq) {
@@ -1403,7 +1403,6 @@ static int msm_vdec_queue_setup(struct vb2_queue *q,
				"No buffer requirement for buffer type %x\n",
				HAL_BUFFER_OUTPUT);
			rc = -EINVAL;
			mutex_unlock(&inst->lock);
			break;
		}
		*num_buffers = max(*num_buffers, bufreq->buffer_count_min);
@@ -1415,7 +1414,7 @@ static int msm_vdec_queue_setup(struct vb2_queue *q,
			rc = call_hfi_op(hdev, session_set_property,
				inst->session, property_id, &new_buf_count);
		}
		mutex_unlock(&inst->lock);

		if (*num_buffers != bufreq->buffer_count_actual) {
			rc = msm_comm_try_get_bufreqs(inst);
			if (rc) {
@@ -1505,9 +1504,8 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
			goto fail_start;
		}
	}
	mutex_lock(&inst->sync_lock);
	if (!list_empty(&inst->pendingq)) {
		list_for_each_safe(ptr, next, &inst->pendingq) {
	mutex_lock(&inst->pendingq.lock);
	list_for_each_safe(ptr, next, &inst->pendingq.list) {
		temp = list_entry(ptr, struct vb2_buf_entry, list);
		rc = msm_comm_qbuf(temp->vb);
		if (rc) {
@@ -1518,8 +1516,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
		list_del(&temp->list);
		kfree(temp);
	}
	}
	mutex_unlock(&inst->sync_lock);
	mutex_unlock(&inst->pendingq.lock);
	return rc;
fail_start:
	return rc;
+11 −15
Original line number Diff line number Diff line
@@ -1220,11 +1220,9 @@ static int msm_venc_queue_setup(struct vb2_queue *q,
	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
		*num_planes = 1;

		mutex_lock(&inst->lock);
		*num_buffers = inst->buff_req.buffer[0].buffer_count_actual =
			max(*num_buffers, inst->buff_req.buffer[0].
				buffer_count_actual);
		mutex_unlock(&inst->lock);

		property_id = HAL_PARAM_BUFFER_COUNT_ACTUAL;
		new_buf_count.buffer_type = HAL_BUFFER_INPUT;
@@ -1348,9 +1346,8 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
			"Failed to move inst: %p to start done state\n", inst);
		goto fail_start;
	}
	mutex_lock(&inst->sync_lock);
	if (!list_empty(&inst->pendingq)) {
		list_for_each_safe(ptr, next, &inst->pendingq) {
	mutex_lock(&inst->pendingq.lock);
	list_for_each_safe(ptr, next, &inst->pendingq.list) {
		temp = list_entry(ptr, struct vb2_buf_entry, list);
		rc = msm_comm_qbuf(temp->vb);
		if (rc) {
@@ -1361,8 +1358,7 @@ static inline int start_streaming(struct msm_vidc_inst *inst)
		list_del(&temp->list);
		kfree(temp);
	}
	}
	mutex_unlock(&inst->sync_lock);
	mutex_unlock(&inst->pendingq.lock);
	return rc;
fail_start:
	return rc;
+83 −92
Original line number Diff line number Diff line
@@ -242,20 +242,19 @@ struct buffer_info *get_registered_buf(struct msm_vidc_inst *inst,
	struct buffer_info *temp;
	struct buffer_info *ret = NULL;
	int i;
	struct list_head *list = &inst->registered_bufs;
	int fd = b->m.planes[idx].reserved[0];
	u32 buff_off = b->m.planes[idx].reserved[1];
	u32 size = b->m.planes[idx].length;
	ion_phys_addr_t device_addr = b->m.planes[idx].m.userptr;

	if (!list || fd < 0 || !plane) {
	if (fd < 0 || !plane) {
		dprintk(VIDC_ERR, "Invalid input\n");
		goto err_invalid_input;
	}

	*plane = 0;
	mutex_lock(&inst->lock);
	list_for_each_entry(temp, list, list) {
	mutex_lock(&inst->registeredbufs.lock);
	list_for_each_entry(temp, &inst->registeredbufs.list, list) {
		for (i = 0; (i < temp->num_planes)
			&& (i < VIDEO_MAX_PLANES); i++) {
			if (temp &&
@@ -278,26 +277,29 @@ struct buffer_info *get_registered_buf(struct msm_vidc_inst *inst,
		if (ret)
			break;
	}
	mutex_unlock(&inst->lock);
	mutex_unlock(&inst->registeredbufs.lock);
err_invalid_input:
	return ret;
}

struct msm_smem *get_same_fd_buffer(struct msm_vidc_inst *inst,
			struct list_head *list, int fd)
static struct msm_smem *get_same_fd_buffer(struct msm_vidc_list *buf_list,
							int fd)
{
	struct buffer_info *temp;
	struct msm_smem *same_fd_handle = NULL;

	int i;

	if (fd == 0)
		return NULL;
	if (!list || fd < 0) {

	if (!buf_list || fd < 0) {
		dprintk(VIDC_ERR, "Invalid input\n");
		goto err_invalid_input;
	}
	mutex_lock(&inst->lock);
	list_for_each_entry(temp, list, list) {

	mutex_lock(&buf_list->lock);
	list_for_each_entry(temp, &buf_list->list, list) {
		for (i = 0; (i < temp->num_planes)
			&& (i < VIDEO_MAX_PLANES); i++) {
			if (temp && (temp->fd[i] == fd) &&
@@ -312,26 +314,28 @@ struct msm_smem *get_same_fd_buffer(struct msm_vidc_inst *inst,
		if (same_fd_handle)
			break;
	}
	mutex_unlock(&inst->lock);
	mutex_unlock(&buf_list->lock);

err_invalid_input:
	return same_fd_handle;
}

struct buffer_info *device_to_uvaddr(struct msm_vidc_inst *inst,
			struct list_head *list, ion_phys_addr_t device_addr)
struct buffer_info *device_to_uvaddr(struct msm_vidc_list *buf_list,
				ion_phys_addr_t device_addr)
{
	struct buffer_info *temp = NULL;
	struct buffer_info *dummy = NULL;
	int found = 0;
	int i;
	if (!list || !device_addr || !inst) {

	if (!buf_list || !device_addr) {
		dprintk(VIDC_ERR,
			"Invalid input- list: %p device_addr: 0x%pa inst: %p\n",
			list, &device_addr, inst);
			"Invalid input- device_addr: 0x%pa buf_list: %p\n",
			&device_addr, buf_list);
		goto err_invalid_input;
	}
	mutex_lock(&inst->lock);
	list_for_each_entry_safe(temp, dummy, list, list) {

	mutex_lock(&buf_list->lock);
	list_for_each_entry(temp, &buf_list->list, list) {
		for (i = 0; (i < temp->num_planes)
			&& (i < VIDEO_MAX_PLANES); i++) {
			if (temp && !temp->inactive &&
@@ -345,7 +349,8 @@ struct buffer_info *device_to_uvaddr(struct msm_vidc_inst *inst,
		if (found)
			break;
	}
	mutex_unlock(&inst->lock);
	mutex_unlock(&buf_list->lock);

err_invalid_input:
	return temp;
}
@@ -518,8 +523,7 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
		if (rc < 0)
			goto exit;

		same_fd_handle = get_same_fd_buffer(inst,
					&inst->registered_bufs,
		same_fd_handle = get_same_fd_buffer(&inst->registeredbufs,
					b->m.planes[i].reserved[0]);

		populate_buf_info(binfo, b, i);
@@ -561,10 +565,12 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
			&binfo->device_addr[i], binfo->fd[i],
			binfo->buff_off[i], binfo->mapped[i]);
	}
	mutex_lock(&inst->lock);
	list_add_tail(&binfo->list, &inst->registered_bufs);
	mutex_unlock(&inst->lock);

	mutex_lock(&inst->registeredbufs.lock);
	list_add_tail(&binfo->list, &inst->registeredbufs.list);
	mutex_unlock(&inst->registeredbufs.lock);
	return 0;

exit:
	kfree(binfo);
	return rc;
@@ -574,8 +580,6 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst,
{
	int i = 0;
	struct buffer_info *temp = NULL;
	struct buffer_info *dummy = NULL;
	struct list_head *list;
	bool found = false, keep_node = false;

	if (!inst || !binfo) {
@@ -584,13 +588,13 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst,
		return -EINVAL;
	}

	mutex_lock(&inst->lock);
	list = &inst->registered_bufs;
	mutex_lock(&inst->registeredbufs.lock);

	/*
	* Make sure the buffer to be unmapped and deleted
	* from the registered list is present in the list.
	*/
	list_for_each_entry_safe(temp, dummy, list, list) {
	list_for_each_entry(temp, &inst->registeredbufs.list, list) {
		if (temp == binfo) {
			found = true;
			break;
@@ -645,7 +649,7 @@ int unmap_and_deregister_buf(struct msm_vidc_inst *inst,
		dprintk(VIDC_DBG, "[UNMAP] NOT-FREED binfo: %p\n", temp);
	}
exit:
	mutex_unlock(&inst->lock);
	mutex_unlock(&inst->registeredbufs.lock);
	return 0;
}

@@ -744,9 +748,8 @@ EXPORT_SYMBOL(msm_vidc_prepare_buf);

int msm_vidc_release_buffers(void *instance, int buffer_type)
{
	struct list_head *ptr, *next;
	struct msm_vidc_inst *inst = instance;
	struct buffer_info *bi;
	struct buffer_info *bi, *dummy;
	struct v4l2_buffer buffer_info;
	struct v4l2_plane plane[VIDEO_MAX_PLANES];
	int i, rc = 0;
@@ -774,10 +777,9 @@ int msm_vidc_release_buffers(void *instance, int buffer_type)
		goto free_and_unmap;
	}

	list_for_each_safe(ptr, next, &inst->registered_bufs) {
	mutex_lock(&inst->registeredbufs.lock);
	list_for_each_entry(bi, &inst->registeredbufs.list, list) {
		bool release_buf = false;
		mutex_lock(&inst->lock);
		bi = list_entry(ptr, struct buffer_info, list);
		if (bi->type == buffer_type) {
			buffer_info.type = bi->type;
			for (i = 0; (i < bi->num_planes)
@@ -796,7 +798,7 @@ int msm_vidc_release_buffers(void *instance, int buffer_type)
			buffer_info.length = bi->num_planes;
			release_buf = true;
		}
		mutex_unlock(&inst->lock);

		if (!release_buf)
			continue;
		if (inst->session_type == MSM_VIDC_DECODER)
@@ -812,11 +814,11 @@ int msm_vidc_release_buffers(void *instance, int buffer_type)
				buffer_info.m.planes[0].reserved[1],
				buffer_info.m.planes[0].length);
	}
	mutex_unlock(&inst->registeredbufs.lock);

free_and_unmap:
	mutex_lock(&inst->lock);
	list_for_each_safe(ptr, next, &inst->registered_bufs) {
		bi = list_entry(ptr, struct buffer_info, list);
	mutex_lock(&inst->registeredbufs.lock);
	list_for_each_entry_safe(bi, dummy, &inst->registeredbufs.list, list) {
		if (bi->type == buffer_type) {
			list_del(&bi->list);
			for (i = 0; i < bi->num_planes; i++) {
@@ -833,7 +835,7 @@ free_and_unmap:
			kfree(bi);
		}
	}
	mutex_unlock(&inst->lock);
	mutex_unlock(&inst->registeredbufs.lock);
	return rc;
}
EXPORT_SYMBOL(msm_vidc_release_buffers);
@@ -980,8 +982,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
			!b->m.planes[i].m.userptr) {
			continue;
		}
		buffer_info = device_to_uvaddr(inst,
			&inst->registered_bufs,
		buffer_info = device_to_uvaddr(&inst->registeredbufs,
			b->m.planes[i].m.userptr);

		if (!buffer_info) {
@@ -1011,9 +1012,7 @@ int msm_vidc_dqbuf(void *instance, struct v4l2_buffer *b)
		if (!buffer_info)
			return -EINVAL;

		mutex_lock(&inst->lock);
		buffer_info->dequeued = true;
		mutex_unlock(&inst->lock);

		dprintk(VIDC_DBG, "[DEQUEUED]: fd[0] = %d\n",
			buffer_info->fd[0]);
@@ -1262,13 +1261,15 @@ void *msm_vidc_open(int core_id, int session_type)
	mutex_init(&inst->bufq[CAPTURE_PORT].lock);
	mutex_init(&inst->bufq[OUTPUT_PORT].lock);
	mutex_init(&inst->lock);

	INIT_MSM_VIDC_LIST(&inst->pendingq);
	INIT_MSM_VIDC_LIST(&inst->internalbufs);
	INIT_MSM_VIDC_LIST(&inst->persistbufs);
	INIT_MSM_VIDC_LIST(&inst->pending_getpropq);
	INIT_MSM_VIDC_LIST(&inst->outputbufs);
	INIT_MSM_VIDC_LIST(&inst->registeredbufs);

	inst->session_type = session_type;
	INIT_LIST_HEAD(&inst->pendingq);
	INIT_LIST_HEAD(&inst->internalbufs);
	INIT_LIST_HEAD(&inst->persistbufs);
	INIT_LIST_HEAD(&inst->registered_bufs);
	INIT_LIST_HEAD(&inst->outputbufs);
	INIT_LIST_HEAD(&inst->pending_getpropq);
	init_waitqueue_head(&inst->kernel_event_queue);
	inst->state = MSM_VIDC_CORE_UNINIT_DONE;
	inst->core = core;
@@ -1348,60 +1349,49 @@ EXPORT_SYMBOL(msm_vidc_open);

static void cleanup_instance(struct msm_vidc_inst *inst)
{
	struct list_head *ptr, *next;
	struct vb2_buf_entry *entry;
	struct vb2_buf_entry *entry, *dummy;
	if (inst) {
		mutex_lock(&inst->lock);
		if (!list_empty(&inst->pendingq)) {
			list_for_each_safe(ptr, next, &inst->pendingq) {
				entry = list_entry(ptr, struct vb2_buf_entry,
						list);

		mutex_lock(&inst->pendingq.lock);
		list_for_each_entry_safe(entry, dummy, &inst->pendingq.list,
				list) {
			list_del(&entry->list);
			kfree(entry);
		}
		}
		if (!list_empty(&inst->internalbufs)) {
			mutex_unlock(&inst->lock);
			if (msm_comm_release_scratch_buffers(inst, false))
		mutex_unlock(&inst->pendingq.lock);

		if (msm_comm_release_scratch_buffers(inst, false)) {
			dprintk(VIDC_ERR,
				"Failed to release scratch buffers\n");

			mutex_lock(&inst->lock);
		}
		if (!list_empty(&inst->persistbufs)) {
			mutex_unlock(&inst->lock);
			if (msm_comm_release_persist_buffers(inst))

		if (msm_comm_release_persist_buffers(inst)) {
			dprintk(VIDC_ERR,
				"Failed to release persist buffers\n");

			mutex_lock(&inst->lock);
		}
		if (!list_empty(&inst->outputbufs)) {
			mutex_unlock(&inst->lock);
			if (msm_comm_release_output_buffers(inst))

		if (msm_comm_release_output_buffers(inst)) {
			dprintk(VIDC_ERR,
				"Failed to release output buffers\n");

			mutex_lock(&inst->lock);
		}
		if (inst->extradata_handle) {
			mutex_unlock(&inst->lock);

		if (inst->extradata_handle)
			msm_comm_smem_free(inst, inst->extradata_handle);
			mutex_lock(&inst->lock);
		}
		mutex_unlock(&inst->lock);

		debugfs_remove_recursive(inst->debugfs_root);
		WARN_ON(!list_empty(&inst->pending_getpropq));

		mutex_lock(&inst->pending_getpropq.lock);
		WARN_ON(!list_empty(&inst->pending_getpropq.list));
		mutex_unlock(&inst->pending_getpropq.lock);
	}
}

int msm_vidc_close(void *instance)
{
	struct msm_vidc_inst *inst = instance;
	struct msm_vidc_inst *temp;
	struct msm_vidc_inst *temp, *inst_dummy;
	struct msm_vidc_core *core;
	struct list_head *ptr, *next;
	struct buffer_info *bi;
	struct buffer_info *bi, *dummy;
	int rc = 0;
	int i;

@@ -1409,8 +1399,9 @@ int msm_vidc_close(void *instance)
		return -EINVAL;

	v4l2_fh_del(&inst->event_handler);
	list_for_each_safe(ptr, next, &inst->registered_bufs) {
		bi = list_entry(ptr, struct buffer_info, list);

	mutex_lock(&inst->registeredbufs.lock);
	list_for_each_entry_safe(bi, dummy, &inst->registeredbufs.list, list) {
		if (bi->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
			list_del(&bi->list);
			for (i = 0; (i < bi->num_planes)
@@ -1421,11 +1412,11 @@ int msm_vidc_close(void *instance)
			kfree(bi);
		}
	}
	mutex_unlock(&inst->registeredbufs.lock);

	core = inst->core;
	mutex_lock(&core->lock);
	list_for_each_safe(ptr, next, &core->instances) {
		temp = list_entry(ptr, struct msm_vidc_inst, list);
	list_for_each_entry_safe(temp, inst_dummy, &core->instances, list) {
		if (temp == inst)
			list_del(&inst->list);
	}
+196 −212

File changed.

Preview size limit exceeded, changes collapsed.

+5 −8
Original line number Diff line number Diff line
@@ -237,21 +237,18 @@ static int inst_info_open(struct inode *inode, struct file *file)
static int publish_unreleased_reference(struct msm_vidc_inst *inst)
{
	struct buffer_info *temp = NULL;
	struct buffer_info *dummy = NULL;
	struct list_head *list = NULL;

	if (!inst) {
		dprintk(VIDC_ERR, "%s: invalid param\n", __func__);
		return -EINVAL;
	}

	list = &inst->registered_bufs;
	mutex_lock(&inst->lock);
	if (inst->buffer_mode_set[CAPTURE_PORT] == HAL_BUFFER_MODE_DYNAMIC) {
		write_str(&dbg_buf, "Pending buffer references:\n");
		list_for_each_entry_safe(temp, dummy, list, list) {
			if (temp && temp->type ==
			V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&

		mutex_lock(&inst->registeredbufs.lock);
		list_for_each_entry(temp, &inst->registeredbufs.list, list) {
			if (temp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE &&
			!temp->inactive && atomic_read(&temp->ref_count)) {
				write_str(&dbg_buf,
				"\tpending buffer: 0x%lx fd[0] = %d ref_count = %d held by: %s\n",
@@ -261,8 +258,8 @@ static int publish_unreleased_reference(struct msm_vidc_inst *inst)
				DYNAMIC_BUF_OWNER(temp));
			}
		}
		mutex_unlock(&inst->registeredbufs.lock);
	}
	mutex_unlock(&inst->lock);
	return 0;
}

Loading