Commit 4fd6ca90 authored by Lizhi Hou's avatar Lizhi Hou Committed by Jeff Hugo
Browse files

accel/amdxdna: Refactor hardware context destroy routine



It is required by firmware to wait up to 2 seconds for pending commands
before sending the destroy hardware context command. After 2 seconds
wait, if there are still pending commands, driver needs to cancel them.

So the context destroy steps need to be:
  1. Stop drm scheduler. (drm_sched_entity_destroy)
  2. Wait up to 2 seconds for pending commands.
  3. Destroy hardware context and cancel the rest pending requests.
  4. Wait all jobs associated with the hwctx are freed.
  5. Free job resources.

Signed-off-by: default avatarLizhi Hou <lizhi.hou@amd.com>
Reviewed-by: default avatarJeffrey Hugo <quic_jhugo@quicinc.com>
Signed-off-by: default avatarJeffrey Hugo <quic_jhugo@quicinc.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250124173536.148676-1-lizhi.hou@amd.com
parent 41129e23
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ static void aie2_job_release(struct kref *ref)

	job = container_of(ref, struct amdxdna_sched_job, refcnt);
	amdxdna_sched_job_cleanup(job);
	atomic64_inc(&job->hwctx->job_free_cnt);
	wake_up(&job->hwctx->priv->job_free_wq);
	if (job->out_fence)
		dma_fence_put(job->out_fence);
	kfree(job);
@@ -134,7 +136,8 @@ static void aie2_hwctx_wait_for_idle(struct amdxdna_hwctx *hwctx)
	if (!fence)
		return;

	dma_fence_wait(fence, false);
	/* Wait up to 2 seconds for fw to finish all pending requests */
	dma_fence_wait_timeout(fence, false, msecs_to_jiffies(2000));
	dma_fence_put(fence);
}

@@ -622,6 +625,7 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx)
	hwctx->status = HWCTX_STAT_INIT;
	ndev = xdna->dev_handle;
	ndev->hwctx_num++;
	init_waitqueue_head(&priv->job_free_wq);

	XDNA_DBG(xdna, "hwctx %s init completed", hwctx->name);

@@ -658,25 +662,23 @@ void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx)
	xdna = hwctx->client->xdna;
	ndev = xdna->dev_handle;
	ndev->hwctx_num--;
	drm_sched_wqueue_stop(&hwctx->priv->sched);

	/* Now, scheduler will not send command to device. */
	XDNA_DBG(xdna, "%s sequence number %lld", hwctx->name, hwctx->priv->seq);
	drm_sched_entity_destroy(&hwctx->priv->entity);

	aie2_hwctx_wait_for_idle(hwctx);

	/* Request fw to destroy hwctx and cancel the rest pending requests */
	aie2_release_resource(hwctx);

	/*
	 * All submitted commands are aborted.
	 * Restart scheduler queues to cleanup jobs. The amdxdna_sched_job_run()
	 * will return NODEV if it is called.
	 */
	drm_sched_wqueue_start(&hwctx->priv->sched);
	/* Wait for all submitted jobs to be completed or canceled */
	wait_event(hwctx->priv->job_free_wq,
		   atomic64_read(&hwctx->job_submit_cnt) ==
		   atomic64_read(&hwctx->job_free_cnt));

	aie2_hwctx_wait_for_idle(hwctx);
	drm_sched_entity_destroy(&hwctx->priv->entity);
	drm_sched_fini(&hwctx->priv->sched);
	aie2_ctx_syncobj_destroy(hwctx);

	XDNA_DBG(xdna, "%s sequence number %lld", hwctx->name, hwctx->priv->seq);

	for (idx = 0; idx < ARRAY_SIZE(hwctx->priv->cmd_buf); idx++)
		drm_gem_object_put(to_gobj(hwctx->priv->cmd_buf[idx]));
	amdxdna_gem_unpin(hwctx->priv->heap);
@@ -885,6 +887,7 @@ int aie2_cmd_submit(struct amdxdna_hwctx *hwctx, struct amdxdna_sched_job *job,
	drm_gem_unlock_reservations(job->bos, job->bo_cnt, &acquire_ctx);

	aie2_job_put(job);
	atomic64_inc(&hwctx->job_submit_cnt);

	return 0;

+2 −0
Original line number Diff line number Diff line
@@ -220,6 +220,8 @@ int amdxdna_drm_create_hwctx_ioctl(struct drm_device *dev, void *data, struct dr
	args->syncobj_handle = hwctx->syncobj_hdl;
	mutex_unlock(&xdna->dev_lock);

	atomic64_set(&hwctx->job_submit_cnt, 0);
	atomic64_set(&hwctx->job_free_cnt, 0);
	XDNA_DBG(xdna, "PID %d create HW context %d, ret %d", client->pid, args->handle, ret);
	drm_dev_exit(idx);
	return 0;
+3 −0
Original line number Diff line number Diff line
@@ -87,6 +87,9 @@ struct amdxdna_hwctx {
	struct amdxdna_qos_info		     qos;
	struct amdxdna_hwctx_param_config_cu *cus;
	u32				syncobj_hdl;

	atomic64_t			job_submit_cnt;
	atomic64_t			job_free_cnt ____cacheline_aligned_in_smp;
};

#define drm_job_to_xdna_job(j) \