mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 13:53:33 +00:00
habanalabs: take timestamp on wait for interrupt
Taking an accurate timestamp in a close proximity of the interrupt is required for user side statistics management. Signed-off-by: Yuri Nudelman <ynudelman@habana.ai> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
This commit is contained in:
parent
c1904127ce
commit
f05d17b226
3 changed files with 21 additions and 3 deletions
|
@ -2740,7 +2740,8 @@ static int hl_cs_wait_ioctl(struct hl_fpriv *hpriv, void *data)
|
|||
static int _hl_interrupt_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx,
|
||||
u32 timeout_us, u64 user_address,
|
||||
u64 target_value, u16 interrupt_offset,
|
||||
enum hl_cs_wait_status *status)
|
||||
enum hl_cs_wait_status *status,
|
||||
bool take_timestamp, u64 *timestamp)
|
||||
{
|
||||
struct hl_user_pending_interrupt *pend;
|
||||
struct hl_user_interrupt *interrupt;
|
||||
|
@ -2764,6 +2765,8 @@ static int _hl_interrupt_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx,
|
|||
|
||||
hl_fence_init(&pend->fence, ULONG_MAX);
|
||||
|
||||
pend->fence.take_timestamp = take_timestamp;
|
||||
|
||||
if (interrupt_offset == HL_COMMON_USER_INTERRUPT_ID)
|
||||
interrupt = &hdev->common_user_interrupt;
|
||||
else
|
||||
|
@ -2838,6 +2841,8 @@ static int _hl_interrupt_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx,
|
|||
list_del(&pend->wait_list_node);
|
||||
spin_unlock_irqrestore(&interrupt->wait_list_lock, flags);
|
||||
|
||||
*timestamp = ktime_to_ns(pend->fence.timestamp);
|
||||
|
||||
kfree(pend);
|
||||
hl_ctx_put(ctx);
|
||||
|
||||
|
@ -2851,6 +2856,7 @@ static int hl_interrupt_wait_ioctl(struct hl_fpriv *hpriv, void *data)
|
|||
struct asic_fixed_properties *prop;
|
||||
union hl_wait_cs_args *args = data;
|
||||
enum hl_cs_wait_status status;
|
||||
u64 timestamp;
|
||||
int rc;
|
||||
|
||||
prop = &hdev->asic_prop;
|
||||
|
@ -2880,7 +2886,9 @@ static int hl_interrupt_wait_ioctl(struct hl_fpriv *hpriv, void *data)
|
|||
|
||||
rc = _hl_interrupt_wait_ioctl(hdev, hpriv->ctx,
|
||||
args->in.interrupt_timeout_us, args->in.addr,
|
||||
args->in.target, interrupt_offset, &status);
|
||||
args->in.target, interrupt_offset, &status,
|
||||
args->in.flags & HL_CS_FLAGS_TIMESTAMP,
|
||||
×tamp);
|
||||
|
||||
if (rc) {
|
||||
if (rc != -EINTR)
|
||||
|
@ -2892,6 +2900,11 @@ static int hl_interrupt_wait_ioctl(struct hl_fpriv *hpriv, void *data)
|
|||
|
||||
memset(args, 0, sizeof(*args));
|
||||
|
||||
if (timestamp) {
|
||||
args->out.timestamp_nsec = timestamp;
|
||||
args->out.flags |= HL_WAIT_CS_STATUS_FLAG_TIMESTAMP_VLD;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case CS_WAIT_STATUS_COMPLETED:
|
||||
args->out.status = HL_WAIT_CS_STATUS_COMPLETED;
|
||||
|
|
|
@ -601,6 +601,7 @@ struct asic_fixed_properties {
|
|||
* masters QIDs that multi cs is waiting on
|
||||
* @error: mark this fence with error
|
||||
* @timestamp: timestamp upon completion
|
||||
* @take_timestamp: timestamp shall be taken upon completion
|
||||
*/
|
||||
struct hl_fence {
|
||||
struct completion completion;
|
||||
|
@ -609,6 +610,7 @@ struct hl_fence {
|
|||
u32 stream_master_qid_map;
|
||||
int error;
|
||||
ktime_t timestamp;
|
||||
u8 take_timestamp;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -143,8 +143,11 @@ static void handle_user_cq(struct hl_device *hdev,
|
|||
struct hl_user_pending_interrupt *pend;
|
||||
|
||||
spin_lock(&user_cq->wait_list_lock);
|
||||
list_for_each_entry(pend, &user_cq->wait_list_head, wait_list_node)
|
||||
list_for_each_entry(pend, &user_cq->wait_list_head, wait_list_node) {
|
||||
if (pend->fence.take_timestamp)
|
||||
pend->fence.timestamp = ktime_get();
|
||||
complete_all(&pend->fence.completion);
|
||||
}
|
||||
spin_unlock(&user_cq->wait_list_lock);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue