Skip to content

Commit 3b434a3

Browse files
committed
accel/ivpu: Use threaded IRQ to handle JOB done messages
Remove job_done thread and replace it with generic callback based mechanism. Signed-off-by: Jacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com> Reviewed-by: Jeffrey Hugo <quic_jhugo@quicinc.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231113170252.758137-6-jacek.lawrynowicz@linux.intel.com
1 parent 58cde80 commit 3b434a3

8 files changed

Lines changed: 199 additions & 201 deletions

File tree

drivers/accel/ivpu/ivpu_drv.c

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -318,13 +318,11 @@ static int ivpu_wait_for_ready(struct ivpu_device *vdev)
318318
if (ivpu_test_mode & IVPU_TEST_MODE_FW_TEST)
319319
return 0;
320320

321-
ivpu_ipc_consumer_add(vdev, &cons, IVPU_IPC_CHAN_BOOT_MSG);
321+
ivpu_ipc_consumer_add(vdev, &cons, IVPU_IPC_CHAN_BOOT_MSG, NULL);
322322

323323
timeout = jiffies + msecs_to_jiffies(vdev->timeout.boot);
324324
while (1) {
325-
ret = ivpu_ipc_irq_handler(vdev);
326-
if (ret)
327-
break;
325+
ivpu_ipc_irq_handler(vdev, NULL);
328326
ret = ivpu_ipc_receive(vdev, &cons, &ipc_hdr, NULL, 0);
329327
if (ret != -ETIMEDOUT || time_after_eq(jiffies, timeout))
330328
break;
@@ -378,7 +376,6 @@ int ivpu_boot(struct ivpu_device *vdev)
378376
enable_irq(vdev->irq);
379377
ivpu_hw_irq_enable(vdev);
380378
ivpu_ipc_enable(vdev);
381-
ivpu_job_done_thread_enable(vdev);
382379
return 0;
383380
}
384381

@@ -388,7 +385,6 @@ void ivpu_prepare_for_reset(struct ivpu_device *vdev)
388385
disable_irq(vdev->irq);
389386
ivpu_ipc_disable(vdev);
390387
ivpu_mmu_disable(vdev);
391-
ivpu_job_done_thread_disable(vdev);
392388
}
393389

394390
int ivpu_shutdown(struct ivpu_device *vdev)
@@ -429,6 +425,13 @@ static const struct drm_driver driver = {
429425
.minor = DRM_IVPU_DRIVER_MINOR,
430426
};
431427

428+
static irqreturn_t ivpu_irq_thread_handler(int irq, void *arg)
429+
{
430+
struct ivpu_device *vdev = arg;
431+
432+
return ivpu_ipc_irq_thread_handler(vdev);
433+
}
434+
432435
static int ivpu_irq_init(struct ivpu_device *vdev)
433436
{
434437
struct pci_dev *pdev = to_pci_dev(vdev->drm.dev);
@@ -442,8 +445,8 @@ static int ivpu_irq_init(struct ivpu_device *vdev)
442445

443446
vdev->irq = pci_irq_vector(pdev, 0);
444447

445-
ret = devm_request_irq(vdev->drm.dev, vdev->irq, vdev->hw->ops->irq_handler,
446-
IRQF_NO_AUTOEN, DRIVER_NAME, vdev);
448+
ret = devm_request_threaded_irq(vdev->drm.dev, vdev->irq, vdev->hw->ops->irq_handler,
449+
ivpu_irq_thread_handler, IRQF_NO_AUTOEN, DRIVER_NAME, vdev);
447450
if (ret)
448451
ivpu_err(vdev, "Failed to request an IRQ %d\n", ret);
449452

@@ -581,20 +584,15 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
581584

582585
ivpu_pm_init(vdev);
583586

584-
ret = ivpu_job_done_thread_init(vdev);
585-
if (ret)
586-
goto err_ipc_fini;
587-
588587
ret = ivpu_boot(vdev);
589588
if (ret)
590-
goto err_job_done_thread_fini;
589+
goto err_ipc_fini;
591590

591+
ivpu_job_done_consumer_init(vdev);
592592
ivpu_pm_enable(vdev);
593593

594594
return 0;
595595

596-
err_job_done_thread_fini:
597-
ivpu_job_done_thread_fini(vdev);
598596
err_ipc_fini:
599597
ivpu_ipc_fini(vdev);
600598
err_fw_fini:
@@ -619,7 +617,7 @@ static void ivpu_dev_fini(struct ivpu_device *vdev)
619617
ivpu_shutdown(vdev);
620618
if (IVPU_WA(d3hot_after_power_off))
621619
pci_set_power_state(to_pci_dev(vdev->drm.dev), PCI_D3hot);
622-
ivpu_job_done_thread_fini(vdev);
620+
ivpu_job_done_consumer_fini(vdev);
623621
ivpu_pm_cancel_recovery(vdev);
624622

625623
ivpu_ipc_fini(vdev);

drivers/accel/ivpu/ivpu_drv.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <uapi/drm/ivpu_accel.h>
1818

1919
#include "ivpu_mmu_context.h"
20+
#include "ivpu_ipc.h"
2021

2122
#define DRIVER_NAME "intel_vpu"
2223
#define DRIVER_DESC "Driver for Intel NPU (Neural Processing Unit)"
@@ -120,7 +121,7 @@ struct ivpu_device {
120121
struct list_head bo_list;
121122

122123
struct xarray submitted_jobs_xa;
123-
struct task_struct *job_done_thread;
124+
struct ivpu_ipc_consumer job_done_consumer;
124125

125126
atomic64_t unique_id_counter;
126127

drivers/accel/ivpu/ivpu_hw_37xx.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -891,17 +891,20 @@ static void ivpu_hw_37xx_irq_noc_firewall_handler(struct ivpu_device *vdev)
891891
}
892892

893893
/* Handler for IRQs from VPU core (irqV) */
894-
static u32 ivpu_hw_37xx_irqv_handler(struct ivpu_device *vdev, int irq)
894+
static bool ivpu_hw_37xx_irqv_handler(struct ivpu_device *vdev, int irq, bool *wake_thread)
895895
{
896896
u32 status = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
897897

898+
if (!status)
899+
return false;
900+
898901
REGV_WR32(VPU_37XX_HOST_SS_ICB_CLEAR_0, status);
899902

900903
if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
901904
ivpu_mmu_irq_evtq_handler(vdev);
902905

903906
if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
904-
ivpu_ipc_irq_handler(vdev);
907+
ivpu_ipc_irq_handler(vdev, wake_thread);
905908

906909
if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
907910
ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
@@ -918,17 +921,17 @@ static u32 ivpu_hw_37xx_irqv_handler(struct ivpu_device *vdev, int irq)
918921
if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
919922
ivpu_hw_37xx_irq_noc_firewall_handler(vdev);
920923

921-
return status;
924+
return true;
922925
}
923926

924927
/* Handler for IRQs from Buttress core (irqB) */
925-
static u32 ivpu_hw_37xx_irqb_handler(struct ivpu_device *vdev, int irq)
928+
static bool ivpu_hw_37xx_irqb_handler(struct ivpu_device *vdev, int irq)
926929
{
927930
u32 status = REGB_RD32(VPU_37XX_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
928931
bool schedule_recovery = false;
929932

930-
if (status == 0)
931-
return 0;
933+
if (!status)
934+
return false;
932935

933936
if (REG_TEST_FLD(VPU_37XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
934937
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE irq: %08x",
@@ -964,23 +967,27 @@ static u32 ivpu_hw_37xx_irqb_handler(struct ivpu_device *vdev, int irq)
964967
if (schedule_recovery)
965968
ivpu_pm_schedule_recovery(vdev);
966969

967-
return status;
970+
return true;
968971
}
969972

970973
static irqreturn_t ivpu_hw_37xx_irq_handler(int irq, void *ptr)
971974
{
972975
struct ivpu_device *vdev = ptr;
973-
u32 ret_irqv, ret_irqb;
976+
bool irqv_handled, irqb_handled, wake_thread = false;
974977

975978
REGB_WR32(VPU_37XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
976979

977-
ret_irqv = ivpu_hw_37xx_irqv_handler(vdev, irq);
978-
ret_irqb = ivpu_hw_37xx_irqb_handler(vdev, irq);
980+
irqv_handled = ivpu_hw_37xx_irqv_handler(vdev, irq, &wake_thread);
981+
irqb_handled = ivpu_hw_37xx_irqb_handler(vdev, irq);
979982

980983
/* Re-enable global interrupts to re-trigger MSI for pending interrupts */
981984
REGB_WR32(VPU_37XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
982985

983-
return IRQ_RETVAL(ret_irqb | ret_irqv);
986+
if (wake_thread)
987+
return IRQ_WAKE_THREAD;
988+
if (irqv_handled || irqb_handled)
989+
return IRQ_HANDLED;
990+
return IRQ_NONE;
984991
}
985992

986993
static void ivpu_hw_37xx_diagnose_failure(struct ivpu_device *vdev)

drivers/accel/ivpu/ivpu_hw_40xx.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,21 +1047,20 @@ static void ivpu_hw_40xx_irq_noc_firewall_handler(struct ivpu_device *vdev)
10471047
}
10481048

10491049
/* Handler for IRQs from VPU core (irqV) */
1050-
static irqreturn_t ivpu_hw_40xx_irqv_handler(struct ivpu_device *vdev, int irq)
1050+
static bool ivpu_hw_40xx_irqv_handler(struct ivpu_device *vdev, int irq, bool *wake_thread)
10511051
{
10521052
u32 status = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK;
1053-
irqreturn_t ret = IRQ_NONE;
10541053

10551054
if (!status)
1056-
return IRQ_NONE;
1055+
return false;
10571056

10581057
REGV_WR32(VPU_40XX_HOST_SS_ICB_CLEAR_0, status);
10591058

10601059
if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
10611060
ivpu_mmu_irq_evtq_handler(vdev);
10621061

10631062
if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
1064-
ret |= ivpu_ipc_irq_handler(vdev);
1063+
ivpu_ipc_irq_handler(vdev, wake_thread);
10651064

10661065
if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
10671066
ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
@@ -1078,17 +1077,17 @@ static irqreturn_t ivpu_hw_40xx_irqv_handler(struct ivpu_device *vdev, int irq)
10781077
if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
10791078
ivpu_hw_40xx_irq_noc_firewall_handler(vdev);
10801079

1081-
return ret;
1080+
return true;
10821081
}
10831082

10841083
/* Handler for IRQs from Buttress core (irqB) */
1085-
static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
1084+
static bool ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
10861085
{
10871086
bool schedule_recovery = false;
10881087
u32 status = REGB_RD32(VPU_40XX_BUTTRESS_INTERRUPT_STAT) & BUTTRESS_IRQ_MASK;
10891088

1090-
if (status == 0)
1091-
return IRQ_NONE;
1089+
if (!status)
1090+
return false;
10921091

10931092
if (REG_TEST_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE, status))
10941093
ivpu_dbg(vdev, IRQ, "FREQ_CHANGE");
@@ -1140,26 +1139,27 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
11401139
if (schedule_recovery)
11411140
ivpu_pm_schedule_recovery(vdev);
11421141

1143-
return IRQ_HANDLED;
1142+
return true;
11441143
}
11451144

11461145
static irqreturn_t ivpu_hw_40xx_irq_handler(int irq, void *ptr)
11471146
{
1147+
bool irqv_handled, irqb_handled, wake_thread = false;
11481148
struct ivpu_device *vdev = ptr;
1149-
irqreturn_t ret = IRQ_NONE;
11501149

11511150
REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x1);
11521151

1153-
ret |= ivpu_hw_40xx_irqv_handler(vdev, irq);
1154-
ret |= ivpu_hw_40xx_irqb_handler(vdev, irq);
1152+
irqv_handled = ivpu_hw_40xx_irqv_handler(vdev, irq, &wake_thread);
1153+
irqb_handled = ivpu_hw_40xx_irqb_handler(vdev, irq);
11551154

11561155
/* Re-enable global interrupts to re-trigger MSI for pending interrupts */
11571156
REGB_WR32(VPU_40XX_BUTTRESS_GLOBAL_INT_MASK, 0x0);
11581157

1159-
if (ret & IRQ_WAKE_THREAD)
1158+
if (wake_thread)
11601159
return IRQ_WAKE_THREAD;
1161-
1162-
return ret;
1160+
if (irqv_handled || irqb_handled)
1161+
return IRQ_HANDLED;
1162+
return IRQ_NONE;
11631163
}
11641164

11651165
static void ivpu_hw_40xx_diagnose_failure(struct ivpu_device *vdev)

0 commit comments

Comments
 (0)