Commit b75f2250 authored by Omer Shpigelman's avatar Omer Shpigelman Committed by Oded Gabbay

habanalabs: add signal/wait to CS IOCTL operations

Add the following two operations to the CS IOCTL:

Signal:

The signal operation is basically a command submission, that is created by
the driver upon user request. It will be implemented using a dedicated PQE
that will increment a specific SOB. There will be a new flag:
HL_CS_FLAGS_SIGNAL. When the user set this flag in the CS IOCTL structure,
the driver will execute a dedicated code path that will prepare this
special PQE and submit it. The user only needs to provide a queue index on
which to put the signal.

Wait:

The wait operation is also a command submission that is created by the
driver upon user request. It will be implemented using a dedicated PQE that
will contain packets of "ARM a monitor" + FENCE packet. There will be a new
flag: HL_CS_FLAGS_WAIT. When the user set this flag in the CS structure,
the driver will execute a dedicated code path that will prepare this
special PQE and submit it.

The user needs to provide the following parameters:
1. queue ID
2. an array of signal_seq numbers and the number of signals to wait on
   (the length of signal_seq_arr).

The IOCTL will return the CS sequence number of the wait it put on the
queue ID.

Currently, the code supports signal_seq_nr==1. But this API definition will
allow us to put a single PQE that waits on multiple signals.

To correctly configure the monitor and fence, the driver will need to
retrieve the specified signal CS object that contains the relevant SOB and
its expected value. In case the signal CS has already been completed, there
is no point of adding a wait operation. In this case, the driver will
return to the user *without* putting anything on the PQ. The return code
should reflect to the user that the signal was completed, as we won't
return a CS sequence number for this wait.
Signed-off-by: default avatarOmer Shpigelman <oshpigelman@habana.ai>
Reviewed-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
Signed-off-by: default avatarOded Gabbay <oded.gabbay@gmail.com>
parent b0b5d925
...@@ -170,24 +170,16 @@ int hl_ctx_put(struct hl_ctx *ctx) ...@@ -170,24 +170,16 @@ int hl_ctx_put(struct hl_ctx *ctx)
struct dma_fence *hl_ctx_get_fence(struct hl_ctx *ctx, u64 seq) struct dma_fence *hl_ctx_get_fence(struct hl_ctx *ctx, u64 seq)
{ {
struct hl_device *hdev = ctx->hdev;
struct dma_fence *fence; struct dma_fence *fence;
spin_lock(&ctx->cs_lock); spin_lock(&ctx->cs_lock);
if (seq >= ctx->cs_sequence) { if (seq >= ctx->cs_sequence) {
dev_notice_ratelimited(hdev->dev,
"Can't wait on seq %llu because current CS is at seq %llu\n",
seq, ctx->cs_sequence);
spin_unlock(&ctx->cs_lock); spin_unlock(&ctx->cs_lock);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
if (seq + HL_MAX_PENDING_CS < ctx->cs_sequence) { if (seq + HL_MAX_PENDING_CS < ctx->cs_sequence) {
dev_dbg(hdev->dev,
"Can't wait on seq %llu because current CS is at seq %llu (Fence is gone)\n",
seq, ctx->cs_sequence);
spin_unlock(&ctx->cs_lock); spin_unlock(&ctx->cs_lock);
return NULL; return NULL;
} }
......
...@@ -843,6 +843,7 @@ struct hl_userptr { ...@@ -843,6 +843,7 @@ struct hl_userptr {
* @fence: pointer to the fence object of this CS. * @fence: pointer to the fence object of this CS.
* @signal_fence: pointer to the fence object of the signal CS (used by wait * @signal_fence: pointer to the fence object of the signal CS (used by wait
* CS only). * CS only).
* @finish_work: workqueue object to run when CS is completed by H/W.
* @work_tdr: delayed work node for TDR. * @work_tdr: delayed work node for TDR.
* @mirror_node : node in device mirror list of command submissions. * @mirror_node : node in device mirror list of command submissions.
* @debugfs_list: node in debugfs list of command submissions. * @debugfs_list: node in debugfs list of command submissions.
...@@ -863,6 +864,7 @@ struct hl_cs { ...@@ -863,6 +864,7 @@ struct hl_cs {
struct kref refcount; struct kref refcount;
struct dma_fence *fence; struct dma_fence *fence;
struct dma_fence *signal_fence; struct dma_fence *signal_fence;
struct work_struct finish_work;
struct delayed_work work_tdr; struct delayed_work work_tdr;
struct list_head mirror_node; struct list_head mirror_node;
struct list_head debugfs_list; struct list_head debugfs_list;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment