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

Commit 1d993caf authored by Abhilash Kumar's avatar Abhilash Kumar Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: crm: Access the task list of workqueue with locks



Add locks at proper place while acquiring, enqueuing and executing
a task from the list and while accessing the elements of workq.
Also the change ensures that the workq is destroyed safely.

Change-Id: I01bf2032133cc1a5269d699b94770141347d3cd0
Signed-off-by: default avatarAbhilash Kumar <krabhi@codeaurora.org>
Signed-off-by: default avatarKarthik Anantha Ram <kartanan@codeaurora.org>
parent 0af242ae
Loading
Loading
Loading
Loading
+17 −34
Original line number Diff line number Diff line
@@ -59,11 +59,11 @@ static void cam_req_mgr_workq_put_task(struct crm_workq_task *task)
		(struct cam_req_mgr_core_workq *)task->parent;
	unsigned long flags = 0;

	WORKQ_ACQUIRE_LOCK(workq, flags);
	list_del_init(&task->entry);
	task->cancel = 0;
	task->process_cb = NULL;
	task->priv = NULL;
	WORKQ_ACQUIRE_LOCK(workq, flags);
	list_add_tail(&task->entry,
		&workq->task.empty_head);
	atomic_add(1, &workq->task.free_cnt);
@@ -127,28 +127,6 @@ static void cam_req_mgr_process_workq(struct work_struct *w)
	}
}

void crm_workq_clear_q(struct cam_req_mgr_core_workq *workq)
{
	int32_t                 i = CRM_TASK_PRIORITY_0;
	struct crm_workq_task  *task, *task_save;

	CAM_DBG(CAM_CRM, "pending_cnt %d",
		atomic_read(&workq->task.pending_cnt));

	while (i < CRM_TASK_PRIORITY_MAX) {
		if (!list_empty(&workq->task.process_head[i])) {
			list_for_each_entry_safe(task, task_save,
				&workq->task.process_head[i], entry) {
				cam_req_mgr_workq_put_task(task);
				CAM_WARN(CAM_CRM, "flush task %pK, %d, cnt %d",
					task, i, atomic_read(
					&workq->task.free_cnt));
			}
		}
		i++;
	}
}

int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
	void *priv, int32_t prio)
{
@@ -167,10 +145,6 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
		rc = -EINVAL;
		goto end;
	}
	if (!workq->job) {
		rc = -EINVAL;
		goto end;
	}

	if (task->cancel == 1) {
		cam_req_mgr_workq_put_task(task);
@@ -184,16 +158,21 @@ int cam_req_mgr_workq_enqueue_task(struct crm_workq_task *task,
		? prio : CRM_TASK_PRIORITY_0;

	WORKQ_ACQUIRE_LOCK(workq, flags);
		if (!workq->job) {
			rc = -EINVAL;
			WORKQ_RELEASE_LOCK(workq, flags);
			goto end;
		}

	list_add_tail(&task->entry,
		&workq->task.process_head[task->priority]);
	WORKQ_RELEASE_LOCK(workq, flags);

	atomic_add(1, &workq->task.pending_cnt);
	CAM_DBG(CAM_CRM, "enq task %pK pending_cnt %d",
		task, atomic_read(&workq->task.pending_cnt));

	queue_work(workq->job, &workq->work);

	WORKQ_RELEASE_LOCK(workq, flags);
end:
	return rc;
}
@@ -252,8 +231,7 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks,
			task = &crm_workq->task.pool[i];
			task->parent = (void *)crm_workq;
			/* Put all tasks in free pool */
			list_add_tail(&task->entry,
			&crm_workq->task.process_head[CRM_TASK_PRIORITY_0]);
			INIT_LIST_HEAD(&task->entry);
			cam_req_mgr_workq_put_task(task);
		}
		*workq = crm_workq;
@@ -266,13 +244,18 @@ int cam_req_mgr_workq_create(char *name, int32_t num_tasks,

void cam_req_mgr_workq_destroy(struct cam_req_mgr_core_workq **crm_workq)
{
	unsigned long flags = 0;
	struct workqueue_struct   *job;
	CAM_DBG(CAM_CRM, "destroy workque %pK", crm_workq);
	if (*crm_workq) {
		crm_workq_clear_q(*crm_workq);
		WORKQ_ACQUIRE_LOCK(*crm_workq, flags);
		if ((*crm_workq)->job) {
			destroy_workqueue((*crm_workq)->job);
			job = (*crm_workq)->job;
			(*crm_workq)->job = NULL;
		}
			WORKQ_RELEASE_LOCK(*crm_workq, flags);
			destroy_workqueue(job);
		} else
			WORKQ_RELEASE_LOCK(*crm_workq, flags);
		kfree((*crm_workq)->task.pool);
		kfree(*crm_workq);
		*crm_workq = NULL;