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

Commit df4a11fd authored by Junzhe Zou's avatar Junzhe Zou
Browse files

msm: camera: sync: protect merged fence create with spinlock



Protect merged fence create with spinlock to avoid race condition with
single fence create.

Change-Id: I993da8c39a6ec3379e6d741f7120f522d1a40241
Signed-off-by: default avatarJunzhe Zou <jnzhezou@codeaurora.org>
parent e250b1b2
Loading
Loading
Loading
Loading
+10 −14
Original line number Diff line number Diff line
@@ -312,30 +312,26 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
		return -EINVAL;
	}

	rc = cam_sync_util_find_and_set_empty_row(sync_dev, &idx);
	if (rc < 0) {
		CAM_ERR(CAM_SYNC,
			"Error: Unable to find empty row, table full");
		return -EINVAL;
	}
	do {
		idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
		if (idx >= CAM_SYNC_MAX_OBJS)
			return -ENOMEM;
	} while (!spin_trylock_bh(&sync_dev->row_spinlocks[idx]));

	if (idx <= 0 || idx >= CAM_SYNC_MAX_OBJS) {
		CAM_ERR(CAM_SYNC,
			"Error: Invalid empty row index returned = %ld", idx);
		return -EINVAL;
	}
	set_bit(idx, sync_dev->bitmap);

	rc = cam_sync_init_group_object(sync_dev->sync_table,
		idx, sync_obj,
		num_objs);

	if (rc < 0) {
		CAM_ERR(CAM_SYNC, "Error: Unable to init row at idx = %ld",
			idx);
		spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
		return -EINVAL;
	}

	*merged_obj = idx;
	spin_unlock_bh(&sync_dev->row_spinlocks[idx]);

	return 0;
}
+0 −5
Original line number Diff line number Diff line
@@ -131,7 +131,6 @@ int cam_sync_init_group_object(struct sync_table_row *table,
	struct sync_table_row *row = table + idx;
	struct sync_table_row *child_row = NULL;

	spin_lock_bh(&sync_dev->row_spinlocks[idx]);
	INIT_LIST_HEAD(&row->parents_list);

	INIT_LIST_HEAD(&row->children_list);
@@ -147,7 +146,6 @@ int cam_sync_init_group_object(struct sync_table_row *table,
		if (!child_info) {
			cam_sync_util_cleanup_children_list(
				&row->children_list);
			spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
			return -ENOMEM;
		}

@@ -166,7 +164,6 @@ int cam_sync_init_group_object(struct sync_table_row *table,
			cam_sync_util_cleanup_children_list(
				&row->children_list);
			spin_unlock_bh(&sync_dev->row_spinlocks[sync_objs[i]]);
			spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
			return -ENOMEM;
		}
		parent_info->sync_id = idx;
@@ -182,7 +179,6 @@ int cam_sync_init_group_object(struct sync_table_row *table,
		sync_objs, num_objs);
	if (remaining < 0) {
		CAM_ERR(CAM_SYNC, "Failed getting remaining count");
		spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
		return -ENODEV;
	}

@@ -195,7 +191,6 @@ int cam_sync_init_group_object(struct sync_table_row *table,
	if (row->state != CAM_SYNC_STATE_ACTIVE)
		complete_all(&row->signaled);

	spin_unlock_bh(&sync_dev->row_spinlocks[idx]);
	return 0;
}