Skip to content

Commit a74f4d9

Browse files
kwachowsjlawryno
authored andcommitted
accel/ivpu: Defer MMU root page table allocation
Defer root page table allocation and unify context init/fini functions. Move allocation of the root page table from the file_priv_open function to perform a lazy allocation approach during ivpu_bo_pin(). By doing so, we avoid the overhead of allocating page tables for simple operations like GET_PARAM that do not require them. Additionally, the MMU context descriptor table initialization has been moved to the ivpu_mmu_context_map_page function. This change streamlines the process and ensures that the descriptor table is only initialized when it is actually needed. Refactor init/fini functions to remove redundant code and make the context management more straightforward. Overall, these changes lead to a reduction in the time taken by the file descriptor open operation, as the costly root page table allocation is now avoided for operations that do not require it. Signed-off-by: Karol Wachowski <[email protected]> Reviewed-by: Jacek Lawrynowicz <[email protected]> Reviewed-by: Jeffrey Hugo <[email protected]> Signed-off-by: Jacek Lawrynowicz <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent ce68f86 commit a74f4d9

File tree

5 files changed

+115
-149
lines changed

5 files changed

+115
-149
lines changed

drivers/accel/ivpu/ivpu_drv.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static void file_priv_unbind(struct ivpu_device *vdev, struct ivpu_file_priv *fi
8686

8787
ivpu_cmdq_release_all_locked(file_priv);
8888
ivpu_bo_unbind_all_bos_from_context(vdev, &file_priv->ctx);
89-
ivpu_mmu_user_context_fini(vdev, &file_priv->ctx);
89+
ivpu_mmu_context_fini(vdev, &file_priv->ctx);
9090
file_priv->bound = false;
9191
drm_WARN_ON(&vdev->drm, !xa_erase_irq(&vdev->context_xa, file_priv->ctx.id));
9292
}
@@ -254,9 +254,7 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file)
254254
goto err_unlock;
255255
}
256256

257-
ret = ivpu_mmu_user_context_init(vdev, &file_priv->ctx, ctx_id);
258-
if (ret)
259-
goto err_xa_erase;
257+
ivpu_mmu_context_init(vdev, &file_priv->ctx, ctx_id);
260258

261259
file_priv->default_job_limit.min = FIELD_PREP(IVPU_JOB_ID_CONTEXT_MASK,
262260
(file_priv->ctx.id - 1));
@@ -273,8 +271,6 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file)
273271

274272
return 0;
275273

276-
err_xa_erase:
277-
xa_erase_irq(&vdev->context_xa, ctx_id);
278274
err_unlock:
279275
mutex_unlock(&vdev->context_list_lock);
280276
mutex_destroy(&file_priv->ms_lock);
@@ -652,9 +648,7 @@ static int ivpu_dev_init(struct ivpu_device *vdev)
652648
if (ret)
653649
goto err_shutdown;
654650

655-
ret = ivpu_mmu_global_context_init(vdev);
656-
if (ret)
657-
goto err_shutdown;
651+
ivpu_mmu_global_context_init(vdev);
658652

659653
ret = ivpu_mmu_init(vdev);
660654
if (ret)

drivers/accel/ivpu/ivpu_mmu.c

Lines changed: 30 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid)
696696
return ret;
697697
}
698698

699-
static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
699+
static int ivpu_mmu_cdtab_entry_set(struct ivpu_device *vdev, u32 ssid, u64 cd_dma, bool valid)
700700
{
701701
struct ivpu_mmu_info *mmu = vdev->mmu;
702702
struct ivpu_mmu_cdtab *cdtab = &mmu->cdtab;
@@ -708,30 +708,29 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
708708
return -EINVAL;
709709

710710
entry = cdtab->base + (ssid * IVPU_MMU_CDTAB_ENT_SIZE);
711-
712-
if (cd_dma != 0) {
713-
cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) |
714-
FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) |
715-
FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) |
716-
FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) |
717-
FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) |
718-
FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) |
719-
FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) |
720-
IVPU_MMU_CD_0_TCR_EPD1 |
721-
IVPU_MMU_CD_0_AA64 |
722-
IVPU_MMU_CD_0_R |
723-
IVPU_MMU_CD_0_ASET |
724-
IVPU_MMU_CD_0_V;
725-
cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK;
726-
cd[2] = 0;
727-
cd[3] = 0x0000000000007444;
728-
729-
/* For global context generate memory fault on VPU */
730-
if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID)
731-
cd[0] |= IVPU_MMU_CD_0_A;
732-
} else {
733-
memset(cd, 0, sizeof(cd));
734-
}
711+
drm_WARN_ON(&vdev->drm, (entry[0] & IVPU_MMU_CD_0_V) == valid);
712+
713+
cd[0] = FIELD_PREP(IVPU_MMU_CD_0_TCR_T0SZ, IVPU_MMU_T0SZ_48BIT) |
714+
FIELD_PREP(IVPU_MMU_CD_0_TCR_TG0, 0) |
715+
FIELD_PREP(IVPU_MMU_CD_0_TCR_IRGN0, 0) |
716+
FIELD_PREP(IVPU_MMU_CD_0_TCR_ORGN0, 0) |
717+
FIELD_PREP(IVPU_MMU_CD_0_TCR_SH0, 0) |
718+
FIELD_PREP(IVPU_MMU_CD_0_TCR_IPS, IVPU_MMU_IPS_48BIT) |
719+
FIELD_PREP(IVPU_MMU_CD_0_ASID, ssid) |
720+
IVPU_MMU_CD_0_TCR_EPD1 |
721+
IVPU_MMU_CD_0_AA64 |
722+
IVPU_MMU_CD_0_R |
723+
IVPU_MMU_CD_0_ASET;
724+
cd[1] = cd_dma & IVPU_MMU_CD_1_TTB0_MASK;
725+
cd[2] = 0;
726+
cd[3] = 0x0000000000007444;
727+
728+
/* For global context generate memory fault on VPU */
729+
if (ssid == IVPU_GLOBAL_CONTEXT_MMU_SSID)
730+
cd[0] |= IVPU_MMU_CD_0_A;
731+
732+
if (valid)
733+
cd[0] |= IVPU_MMU_CD_0_V;
735734

736735
WRITE_ONCE(entry[1], cd[1]);
737736
WRITE_ONCE(entry[2], cd[2]);
@@ -741,8 +740,8 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
741740
if (!ivpu_is_force_snoop_enabled(vdev))
742741
clflush_cache_range(entry, IVPU_MMU_CDTAB_ENT_SIZE);
743742

744-
ivpu_dbg(vdev, MMU, "CDTAB %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n",
745-
cd_dma ? "write" : "clear", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]);
743+
ivpu_dbg(vdev, MMU, "CDTAB set %s entry (SSID=%u, dma=%pad): 0x%llx, 0x%llx, 0x%llx, 0x%llx\n",
744+
valid ? "valid" : "invalid", ssid, &cd_dma, cd[0], cd[1], cd[2], cd[3]);
746745

747746
mutex_lock(&mmu->lock);
748747
if (!mmu->on)
@@ -758,33 +757,6 @@ static int ivpu_mmu_cd_add(struct ivpu_device *vdev, u32 ssid, u64 cd_dma)
758757
return ret;
759758
}
760759

761-
static int ivpu_mmu_cd_add_gbl(struct ivpu_device *vdev)
762-
{
763-
int ret;
764-
765-
ret = ivpu_mmu_cd_add(vdev, 0, vdev->gctx.pgtable.pgd_dma);
766-
if (ret)
767-
ivpu_err(vdev, "Failed to add global CD entry: %d\n", ret);
768-
769-
return ret;
770-
}
771-
772-
static int ivpu_mmu_cd_add_user(struct ivpu_device *vdev, u32 ssid, dma_addr_t cd_dma)
773-
{
774-
int ret;
775-
776-
if (ssid == 0) {
777-
ivpu_err(vdev, "Invalid SSID: %u\n", ssid);
778-
return -EINVAL;
779-
}
780-
781-
ret = ivpu_mmu_cd_add(vdev, ssid, cd_dma);
782-
if (ret)
783-
ivpu_err(vdev, "Failed to add CD entry SSID=%u: %d\n", ssid, ret);
784-
785-
return ret;
786-
}
787-
788760
int ivpu_mmu_init(struct ivpu_device *vdev)
789761
{
790762
struct ivpu_mmu_info *mmu = vdev->mmu;
@@ -808,12 +780,6 @@ int ivpu_mmu_init(struct ivpu_device *vdev)
808780
return ret;
809781
}
810782

811-
ret = ivpu_mmu_cd_add_gbl(vdev);
812-
if (ret) {
813-
ivpu_err(vdev, "Failed to initialize strtab: %d\n", ret);
814-
return ret;
815-
}
816-
817783
ret = ivpu_mmu_enable(vdev);
818784
if (ret) {
819785
ivpu_err(vdev, "Failed to resume MMU: %d\n", ret);
@@ -966,12 +932,12 @@ void ivpu_mmu_irq_gerr_handler(struct ivpu_device *vdev)
966932
REGV_WR32(IVPU_MMU_REG_GERRORN, gerror_val);
967933
}
968934

969-
int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable)
935+
int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable)
970936
{
971-
return ivpu_mmu_cd_add_user(vdev, ssid, pgtable->pgd_dma);
937+
return ivpu_mmu_cdtab_entry_set(vdev, ssid, pgtable->pgd_dma, true);
972938
}
973939

974-
void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid)
940+
void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid)
975941
{
976-
ivpu_mmu_cd_add_user(vdev, ssid, 0); /* 0 will clear CD entry */
942+
ivpu_mmu_cdtab_entry_set(vdev, ssid, 0, false);
977943
}

drivers/accel/ivpu/ivpu_mmu.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ struct ivpu_mmu_info {
4040
int ivpu_mmu_init(struct ivpu_device *vdev);
4141
void ivpu_mmu_disable(struct ivpu_device *vdev);
4242
int ivpu_mmu_enable(struct ivpu_device *vdev);
43-
int ivpu_mmu_set_pgtable(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable);
44-
void ivpu_mmu_clear_pgtable(struct ivpu_device *vdev, int ssid);
43+
int ivpu_mmu_cd_set(struct ivpu_device *vdev, int ssid, struct ivpu_mmu_pgtable *pgtable);
44+
void ivpu_mmu_cd_clear(struct ivpu_device *vdev, int ssid);
4545
int ivpu_mmu_invalidate_tlb(struct ivpu_device *vdev, u16 ssid);
4646

4747
void ivpu_mmu_irq_evtq_handler(struct ivpu_device *vdev);

0 commit comments

Comments
 (0)