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

Commit 54265086 authored by Ravi kumar Koyyana's avatar Ravi kumar Koyyana Committed by Junzhe Zou
Browse files

msm: camera: sync: use lock to protect row state read



Add lock to protect row state read from race condition.

Change-Id: I3a6fd1e857fcc436ee33658a1aa1f370ee35f9d7
Signed-off-by: default avatarRavi kumar Koyyana <rkoyyana@codeaurora.org>
Signed-off-by: default avatarJunzhe Zou <jnzhezou@codeaurora.org>
parent 27349551
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ int cam_sync_create(int32_t *sync_obj, const char *name)
	}

	*sync_obj = idx;
	CAM_DBG(CAM_SYNC, "sync_obj: %i", *sync_obj);
	spin_unlock_bh(&sync_dev->row_spinlocks[idx]);

	return rc;
@@ -170,21 +171,24 @@ int cam_sync_signal(int32_t sync_obj, uint32_t status)
	INIT_LIST_HEAD(&sync_list);

	if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0) {
		CAM_ERR(CAM_SYNC, "Error: Out of range sync obj");
		CAM_ERR(CAM_SYNC, "Error: Out of range sync obj (0 <= %d < %d)",
			sync_obj, CAM_SYNC_MAX_OBJS);
		return -EINVAL;
	}
	row = sync_dev->sync_table + sync_obj;
	spin_lock_bh(&sync_dev->row_spinlocks[sync_obj]);
	if (row->state == CAM_SYNC_STATE_INVALID) {
		spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
		CAM_ERR(CAM_SYNC,
			"Error: accessing an uninitialized sync obj = %d",
			sync_obj);
		return -EINVAL;
	}

	spin_lock_bh(&sync_dev->row_spinlocks[sync_obj]);
	if (row->type == CAM_SYNC_TYPE_GROUP) {
		spin_unlock_bh(&sync_dev->row_spinlocks[sync_obj]);
		CAM_ERR(CAM_SYNC, "Error: Signaling a GROUP sync object = %d",
		CAM_ERR(CAM_SYNC,
			"Error: Signaling a GROUP sync object = %d",
			sync_obj);
		return -EINVAL;
	}
@@ -368,6 +372,7 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)

int cam_sync_destroy(int32_t sync_obj)
{
	CAM_DBG(CAM_SYNC, "sync_obj: %i", sync_obj);
	return cam_sync_deinit_object(sync_dev->sync_table, sync_obj);
}

+12 −9
Original line number Diff line number Diff line
@@ -51,8 +51,9 @@ int cam_sync_init_object(struct sync_table_row *table,
	init_completion(&row->signaled);
	INIT_LIST_HEAD(&row->callback_list);
	INIT_LIST_HEAD(&row->user_payload_list);
	CAM_DBG(CAM_SYNC, "Sync object Initialised: sync_id:%u row_state:%u ",
		row->sync_id, row->state);
	CAM_DBG(CAM_SYNC,
		"row name:%s sync_id:%i [idx:%u] row_state:%u ",
		row->name, row->sync_id, idx, row->state);

	return 0;
}
@@ -209,12 +210,16 @@ int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx)
	if (!table || idx <= 0 || idx >= CAM_SYNC_MAX_OBJS)
		return -EINVAL;

	CAM_DBG(CAM_SYNC,
		"row name:%s sync_id:%i [idx:%u] row_state:%u",
		row->name, row->sync_id, idx, row->state);

	spin_lock_bh(&sync_dev->row_spinlocks[idx]);
	if (row->state == CAM_SYNC_STATE_INVALID) {
		spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
		CAM_ERR(CAM_SYNC,
			"Error: accessing an uninitialized sync obj: idx = %d",
			idx);
		spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
		return -EINVAL;
	}
	row->state = CAM_SYNC_STATE_INVALID;
@@ -252,9 +257,9 @@ int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx)
		spin_lock_bh(&sync_dev->row_spinlocks[child_info->sync_id]);

		if (child_row->state == CAM_SYNC_STATE_INVALID) {
			list_del_init(&child_info->list);
			spin_unlock_bh(&sync_dev->row_spinlocks[
				child_info->sync_id]);
			list_del_init(&child_info->list);
			kfree(child_info);
			continue;
		}
@@ -262,9 +267,8 @@ int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx)
		cam_sync_util_cleanup_parents_list(child_row,
			SYNC_LIST_CLEAN_ONE, idx);

		spin_unlock_bh(&sync_dev->row_spinlocks[child_info->sync_id]);

		list_del_init(&child_info->list);
		spin_unlock_bh(&sync_dev->row_spinlocks[child_info->sync_id]);
		kfree(child_info);
	}

@@ -277,9 +281,9 @@ int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx)
		spin_lock_bh(&sync_dev->row_spinlocks[parent_info->sync_id]);

		if (parent_row->state == CAM_SYNC_STATE_INVALID) {
			list_del_init(&parent_info->list);
			spin_unlock_bh(&sync_dev->row_spinlocks[
				parent_info->sync_id]);
			list_del_init(&parent_info->list);
			kfree(parent_info);
			continue;
		}
@@ -287,9 +291,8 @@ int cam_sync_deinit_object(struct sync_table_row *table, uint32_t idx)
		cam_sync_util_cleanup_children_list(parent_row,
			SYNC_LIST_CLEAN_ONE, idx);

		spin_unlock_bh(&sync_dev->row_spinlocks[parent_info->sync_id]);

		list_del_init(&parent_info->list);
		spin_unlock_bh(&sync_dev->row_spinlocks[parent_info->sync_id]);
		kfree(parent_info);
	}