From d6a66d59609fc45afc91149e13dddafb8faff0d6 Mon Sep 17 00:00:00 2001 From: Ofir Bitton Date: Tue, 28 Jun 2022 18:34:58 +0300 Subject: [PATCH] habanalabs: add support for common decoder interrupts User application should be able to get notification for any decoder completion. Hence, we introduce a new interface in which a user can wait for all current decoder pending interrupts. Signed-off-by: Ofir Bitton Reviewed-by: Oded Gabbay Signed-off-by: Oded Gabbay --- drivers/misc/habanalabs/common/command_submission.c | 5 +++++ drivers/misc/habanalabs/common/habanalabs.h | 3 +++ drivers/misc/habanalabs/common/irq.c | 9 +++------ drivers/misc/habanalabs/gaudi2/gaudi2.c | 4 ++++ include/uapi/misc/habanalabs.h | 4 ++++ 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/misc/habanalabs/common/command_submission.c b/drivers/misc/habanalabs/common/command_submission.c index 275dcb69a40e9..eb5f1aee15fce 100644 --- a/drivers/misc/habanalabs/common/command_submission.c +++ b/drivers/misc/habanalabs/common/command_submission.c @@ -1082,6 +1082,9 @@ void hl_release_pending_user_interrupts(struct hl_device *hdev) interrupt = &hdev->common_user_cq_interrupt; wake_pending_user_interrupt_threads(interrupt); + + interrupt = &hdev->common_decoder_interrupt; + wake_pending_user_interrupt_threads(interrupt); } static void job_wq_completion(struct work_struct *work) @@ -3375,6 +3378,8 @@ static int hl_interrupt_wait_ioctl(struct hl_fpriv *hpriv, void *data) } else if (interrupt_id == HL_COMMON_USER_CQ_INTERRUPT_ID) { interrupt = &hdev->common_user_cq_interrupt; + } else if (interrupt_id == HL_COMMON_DEC_INTERRUPT_ID) { + interrupt = &hdev->common_decoder_interrupt; } else { dev_err(hdev->dev, "invalid user interrupt %u", interrupt_id); return -EINVAL; diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h index 9b2451f3619a7..7e84f2ce49ae0 100644 --- a/drivers/misc/habanalabs/common/habanalabs.h +++ b/drivers/misc/habanalabs/common/habanalabs.h @@ -77,6 +77,7 @@ struct hl_fpriv; #define HL_INVALID_QUEUE UINT_MAX #define HL_COMMON_USER_CQ_INTERRUPT_ID 0xFFF +#define HL_COMMON_DEC_INTERRUPT_ID 0xFFE #define HL_STATE_DUMP_HIST_LEN 5 @@ -2955,6 +2956,7 @@ struct hl_reset_info { * @common_user_cq_interrupt: common user CQ interrupt for all user CQ interrupts. * upon any user CQ interrupt, driver will monitor the * list of fences registered to this common structure. + * @common_decoder_interrupt: common decoder interrupt for all user decoder interrupts. * @shadow_cs_queue: pointer to a shadow queue that holds pointers to * outstanding command submissions. * @cq_wq: work queues of completion queues for executing work in process @@ -3119,6 +3121,7 @@ struct hl_device { struct hl_cq *completion_queue; struct hl_user_interrupt *user_interrupt; struct hl_user_interrupt common_user_cq_interrupt; + struct hl_user_interrupt common_decoder_interrupt; struct hl_cs **shadow_cs_queue; struct workqueue_struct **cq_wq; struct workqueue_struct *eq_wq; diff --git a/drivers/misc/habanalabs/common/irq.c b/drivers/misc/habanalabs/common/irq.c index fd8f2bd9020e5..d60dafb03a8e2 100644 --- a/drivers/misc/habanalabs/common/irq.c +++ b/drivers/misc/habanalabs/common/irq.c @@ -333,12 +333,9 @@ irqreturn_t hl_irq_handler_user_interrupt(int irq, void *arg) struct hl_user_interrupt *user_int = arg; struct hl_device *hdev = user_int->hdev; - /* If the interrupt is not a decoder interrupt, it means the interrupt - * belongs to a user cq. In that case, before handling it, we need to handle the common - * user cq - */ - if (!user_int->is_decoder) - /* Handle user cq interrupts registered on all interrupts */ + if (user_int->is_decoder) + handle_user_interrupt(hdev, &hdev->common_decoder_interrupt); + else handle_user_interrupt(hdev, &hdev->common_user_cq_interrupt); /* Handle user cq or decoder interrupts registered on this specific irq */ diff --git a/drivers/misc/habanalabs/gaudi2/gaudi2.c b/drivers/misc/habanalabs/gaudi2/gaudi2.c index 8f012076363d2..83da4247e71bf 100644 --- a/drivers/misc/habanalabs/gaudi2/gaudi2.c +++ b/drivers/misc/habanalabs/gaudi2/gaudi2.c @@ -2895,6 +2895,10 @@ static void gaudi2_user_interrupt_setup(struct hl_device *hdev) HL_USR_INTR_STRUCT_INIT(hdev->common_user_cq_interrupt, hdev, HL_COMMON_USER_CQ_INTERRUPT_ID, false); + /* Initialize common decoder interrupt */ + HL_USR_INTR_STRUCT_INIT(hdev->common_decoder_interrupt, hdev, + HL_COMMON_DEC_INTERRUPT_ID, true); + /* User interrupts structure holds both decoder and user interrupts from various engines. * We first initialize the decoder interrupts and then we add the user interrupts. * The only limitation is that the last decoder interrupt id must be smaller diff --git a/include/uapi/misc/habanalabs.h b/include/uapi/misc/habanalabs.h index 4ee24a3a13e9c..8c6ab71e78314 100644 --- a/include/uapi/misc/habanalabs.h +++ b/include/uapi/misc/habanalabs.h @@ -1443,6 +1443,7 @@ union hl_cs_args { #define HL_WAIT_CS_FLAGS_INTERRUPT 0x2 #define HL_WAIT_CS_FLAGS_INTERRUPT_MASK 0xFFF00000 #define HL_WAIT_CS_FLAGS_ANY_CQ_INTERRUPT 0xFFF00000 +#define HL_WAIT_CS_FLAGS_ANY_DEC_INTERRUPT 0xFFE00000 #define HL_WAIT_CS_FLAGS_MULTI_CS 0x4 #define HL_WAIT_CS_FLAGS_INTERRUPT_KERNEL_CQ 0x10 #define HL_WAIT_CS_FLAGS_REGISTER_INTERRUPT 0x20 @@ -1496,6 +1497,9 @@ struct hl_wait_cs_in { * * in order to wait for any CQ interrupt, set interrupt value to * HL_WAIT_CS_FLAGS_ANY_CQ_INTERRUPT. + * + * in order to wait for any decoder interrupt, set interrupt value to + * HL_WAIT_CS_FLAGS_ANY_DEC_INTERRUPT. */ __u32 flags; -- 2.30.2