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

Commit b8bfc1d9 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: synx: Perform idr access with lock"

parents 286fd16d 29edeb73
Loading
Loading
Loading
Loading
+8 −1
Original line number Original line Diff line number Diff line
@@ -97,9 +97,15 @@ int synx_create(s32 *synx_obj, const char *name)


	/* global synx id */
	/* global synx id */
	id = synx_create_handle(synx_dev->synx_table + idx);
	id = synx_create_handle(synx_dev->synx_table + idx);
	if (id < 0) {
		pr_err("unable to allocate the synx handle\n");
		clear_bit(idx, synx_dev->bitmap);
		return -EINVAL;
	}

	rc = synx_init_object(synx_dev->synx_table,
	rc = synx_init_object(synx_dev->synx_table,
			idx, id, name, &synx_fence_ops);
			idx, id, name, &synx_fence_ops);
	if (rc) {
	if (rc < 0) {
		pr_err("unable to init row at idx = %ld\n", idx);
		pr_err("unable to init row at idx = %ld\n", idx);
		clear_bit(idx, synx_dev->bitmap);
		clear_bit(idx, synx_dev->bitmap);
		return -EINVAL;
		return -EINVAL;
@@ -1443,6 +1449,7 @@ static int __init synx_init(void)
		spin_lock_init(&synx_dev->row_spinlocks[idx]);
		spin_lock_init(&synx_dev->row_spinlocks[idx]);


	idr_init(&synx_dev->synx_ids);
	idr_init(&synx_dev->synx_ids);
	spin_lock_init(&synx_dev->idr_lock);


	rc = alloc_chrdev_region(&synx_dev->dev, 0, 1, SYNX_DEVICE_NAME);
	rc = alloc_chrdev_region(&synx_dev->dev, 0, 1, SYNX_DEVICE_NAME);
	if (rc < 0) {
	if (rc < 0) {
+2 −0
Original line number Original line Diff line number Diff line
@@ -171,6 +171,7 @@ struct bind_operations {
 * @work_queue    : Work queue used for dispatching kernel callbacks
 * @work_queue    : Work queue used for dispatching kernel callbacks
 * @bitmap        : Bitmap representation of all synx objects
 * @bitmap        : Bitmap representation of all synx objects
 * synx_ids       : Global unique ids
 * synx_ids       : Global unique ids
 * idr_lock       : Spin lock for id allocation
 * dma_context    : dma context id
 * dma_context    : dma context id
 * bind_vtbl      : Table with bind ops for supported external sync objects
 * bind_vtbl      : Table with bind ops for supported external sync objects
 * client_list    : All the synx clients
 * client_list    : All the synx clients
@@ -189,6 +190,7 @@ struct synx_device {
	struct workqueue_struct *work_queue;
	struct workqueue_struct *work_queue;
	DECLARE_BITMAP(bitmap, SYNX_MAX_OBJS);
	DECLARE_BITMAP(bitmap, SYNX_MAX_OBJS);
	struct idr synx_ids;
	struct idr synx_ids;
	spinlock_t idr_lock;
	u64 dma_context;
	u64 dma_context;
	struct bind_operations bind_vtbl[SYNX_MAX_BIND_TYPES];
	struct bind_operations bind_vtbl[SYNX_MAX_BIND_TYPES];
	struct list_head client_list;
	struct list_head client_list;
+27 −5
Original line number Original line Diff line number Diff line
@@ -143,17 +143,20 @@ int synx_deinit_object(struct synx_table_row *row)
	struct synx_callback_info *synx_cb, *temp_cb;
	struct synx_callback_info *synx_cb, *temp_cb;
	struct synx_cb_data  *upayload_info, *temp_upayload;
	struct synx_cb_data  *upayload_info, *temp_upayload;


	if (!row)
	if (!row || !synx_dev)
		return -EINVAL;
		return -EINVAL;


	synx_obj = row->synx_obj;
	synx_obj = row->synx_obj;


	spin_lock_bh(&synx_dev->idr_lock);
	if ((struct synx_table_row *)idr_remove(&synx_dev->synx_ids,
	if ((struct synx_table_row *)idr_remove(&synx_dev->synx_ids,
			row->synx_obj) != row) {
			row->synx_obj) != row) {
		pr_err("removing data in idr table failed 0x%x\n",
		pr_err("removing data in idr table failed 0x%x\n",
			row->synx_obj);
			row->synx_obj);
		spin_unlock_bh(&synx_dev->idr_lock);
		return -EINVAL;
		return -EINVAL;
	}
	}
	spin_unlock_bh(&synx_dev->idr_lock);


	/*
	/*
	 * release the fence memory only for individual obj.
	 * release the fence memory only for individual obj.
@@ -488,9 +491,15 @@ u32 synx_status_locked(struct synx_table_row *row)
void *synx_from_handle(s32 synx_obj)
void *synx_from_handle(s32 synx_obj)
{
{
	s32 base;
	s32 base;
	struct synx_table_row *row =
	struct synx_table_row *row;
		(struct synx_table_row *) idr_find(&synx_dev->synx_ids,

	if (!synx_dev)
		return NULL;

	spin_lock_bh(&synx_dev->idr_lock);
	row = (struct synx_table_row *) idr_find(&synx_dev->synx_ids,
		synx_obj);
		synx_obj);
	spin_unlock_bh(&synx_dev->idr_lock);


	if (!row) {
	if (!row) {
		pr_err(
		pr_err(
@@ -512,8 +521,15 @@ void *synx_from_handle(s32 synx_obj)
s32 synx_create_handle(void *pObj)
s32 synx_create_handle(void *pObj)
{
{
	s32 base = current->tgid << 16;
	s32 base = current->tgid << 16;
	s32 id = idr_alloc(&synx_dev->synx_ids, pObj,
	s32 id;

	if (!synx_dev)
		return -EINVAL;

	spin_lock_bh(&synx_dev->idr_lock);
	id = idr_alloc(&synx_dev->synx_ids, pObj,
			base, base + 0x10000, GFP_ATOMIC);
			base, base + 0x10000, GFP_ATOMIC);
	spin_unlock_bh(&synx_dev->idr_lock);


	pr_debug("generated Id: 0x%x, base: 0x%x, client: 0x%x\n",
	pr_debug("generated Id: 0x%x, base: 0x%x, client: 0x%x\n",
		id, base, current->tgid);
		id, base, current->tgid);
@@ -567,11 +583,17 @@ void *synx_from_key(s32 id, u32 secure_key)
{
{
	struct synx_table_row *row = NULL;
	struct synx_table_row *row = NULL;


	if (!synx_dev)
		return NULL;

	spin_lock_bh(&synx_dev->idr_lock);
	row = (struct synx_table_row *) idr_find(&synx_dev->synx_ids, id);
	row = (struct synx_table_row *) idr_find(&synx_dev->synx_ids, id);
	if (!row) {
	if (!row) {
		pr_err("invalid synx obj 0x%x\n", id);
		pr_err("invalid synx obj 0x%x\n", id);
		spin_unlock_bh(&synx_dev->idr_lock);
		return NULL;
		return NULL;
	}
	}
	spin_unlock_bh(&synx_dev->idr_lock);


	if (row->secure_key != secure_key)
	if (row->secure_key != secure_key)
		row = NULL;
		row = NULL;