Commit 950942b4 authored by Karol Wachowski's avatar Karol Wachowski Committed by Jacek Lawrynowicz
Browse files

accel/ivpu: Separate DB ID and CMDQ ID allocations from CMDQ allocation



Move doorbell ID and command queue ID XArray allocations from command
queue memory allocation function. This will allow ID allocations to be
done without the need for actual memory allocation.

Signed-off-by: default avatarKarol Wachowski <karol.wachowski@intel.com>
Signed-off-by: default avatarMaciej Falkowski <maciej.falkowski@linux.intel.com>
Reviewed-by: default avatarJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Signed-off-by: default avatarJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250107173238.381120-2-maciej.falkowski@linux.intel.com
parent 5d40d4fa
Loading
Loading
Loading
Loading
+64 −24
Original line number Diff line number Diff line
@@ -83,23 +83,9 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv)
	if (!cmdq)
		return NULL;

	ret = xa_alloc_cyclic(&vdev->db_xa, &cmdq->db_id, NULL, vdev->db_limit, &vdev->db_next,
			      GFP_KERNEL);
	if (ret < 0) {
		ivpu_err(vdev, "Failed to allocate doorbell id: %d\n", ret);
		goto err_free_cmdq;
	}

	ret = xa_alloc_cyclic(&file_priv->cmdq_xa, &cmdq->id, cmdq, file_priv->cmdq_limit,
			      &file_priv->cmdq_id_next, GFP_KERNEL);
	if (ret < 0) {
		ivpu_err(vdev, "Failed to allocate command queue id: %d\n", ret);
		goto err_erase_db_xa;
	}

	cmdq->mem = ivpu_bo_create_global(vdev, SZ_4K, DRM_IVPU_BO_WC | DRM_IVPU_BO_MAPPABLE);
	if (!cmdq->mem)
		goto err_erase_cmdq_xa;
		goto err_free_cmdq;

	ret = ivpu_preemption_buffers_create(vdev, file_priv, cmdq);
	if (ret)
@@ -107,10 +93,6 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv)

	return cmdq;

err_erase_cmdq_xa:
	xa_erase(&file_priv->cmdq_xa, cmdq->id);
err_erase_db_xa:
	xa_erase(&vdev->db_xa, cmdq->db_id);
err_free_cmdq:
	kfree(cmdq);
	return NULL;
@@ -233,30 +215,88 @@ static int ivpu_cmdq_fini(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cm
	return 0;
}

static int ivpu_db_id_alloc(struct ivpu_device *vdev, u32 *db_id)
{
	int ret;
	u32 id;

	ret = xa_alloc_cyclic(&vdev->db_xa, &id, NULL, vdev->db_limit, &vdev->db_next, GFP_KERNEL);
	if (ret < 0)
		return ret;

	*db_id = id;
	return 0;
}

static int ivpu_cmdq_id_alloc(struct ivpu_file_priv *file_priv, u32 *cmdq_id)
{
	int ret;
	u32 id;

	ret = xa_alloc_cyclic(&file_priv->cmdq_xa, &id, NULL, file_priv->cmdq_limit,
			      &file_priv->cmdq_id_next, GFP_KERNEL);
	if (ret < 0)
		return ret;

	*cmdq_id = id;
	return 0;
}

static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u8 priority)
{
	struct ivpu_device *vdev = file_priv->vdev;
	struct ivpu_cmdq *cmdq;
	unsigned long cmdq_id;
	unsigned long id;
	int ret;

	lockdep_assert_held(&file_priv->lock);

	xa_for_each(&file_priv->cmdq_xa, cmdq_id, cmdq)
	xa_for_each(&file_priv->cmdq_xa, id, cmdq)
		if (cmdq->priority == priority)
			break;

	if (!cmdq) {
		cmdq = ivpu_cmdq_alloc(file_priv);
		if (!cmdq)
		if (!cmdq) {
			ivpu_err(vdev, "Failed to allocate command queue\n");
			return NULL;
		}

		ret = ivpu_db_id_alloc(vdev, &cmdq->db_id);
		if (ret) {
			ivpu_err(file_priv->vdev, "Failed to allocate doorbell ID: %d\n", ret);
			goto err_free_cmdq;
		}

		ret = ivpu_cmdq_id_alloc(file_priv, &cmdq->id);
		if (ret) {
			ivpu_err(vdev, "Failed to allocate command queue ID: %d\n", ret);
			goto err_erase_db_id;
		}

		cmdq->priority = priority;
		ret = xa_err(xa_store(&file_priv->cmdq_xa, cmdq->id, cmdq, GFP_KERNEL));
		if (ret) {
			ivpu_err(vdev, "Failed to store command queue in cmdq_xa: %d\n", ret);
			goto err_erase_cmdq_id;
		}
	}

	ret = ivpu_cmdq_init(file_priv, cmdq, priority);
	if (ret)
		return NULL;
	if (ret) {
		ivpu_err(vdev, "Failed to initialize command queue: %d\n", ret);
		goto err_free_cmdq;
	}

	return cmdq;

err_erase_cmdq_id:
	xa_erase(&file_priv->cmdq_xa, cmdq->id);
err_erase_db_id:
	xa_erase(&vdev->db_xa, cmdq->db_id);
err_free_cmdq:
	ivpu_cmdq_free(file_priv, cmdq);
	return NULL;
}

void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv)