[PATCH 3/6] drm/xe/xe2: Introduce identity map for compressed pat for vram
Matthew Auld
matthew.auld at intel.com
Thu Jul 11 12:32:52 UTC 2024
On 11/07/2024 10:19, Akshata Jahagirdar wrote:
> Xe2+ has unified compression (exactly one compression mode/format),
> where compression is now controlled via PAT at PTE level.
> This simplifies KMD operations, as it can now decompress freely
> without concern for the buffer's original compression format—unlike DG2,
> which had multiple compression formats and thus required copying the
> raw CCS state during VRAM eviction. In addition mixed VRAM and system
> memory buffers were not supported with compression enabled.
>
> On Xe2 dGPU compression is still only supported with VRAM, however we
> can now support compression with VRAM and system memory buffers,
> with GPU access being seamless underneath. So long as when doing
> VRAM -> system memory the KMD uses compressed -> uncompressed,
> to decompress it. This also allows CPU access to such buffers,
> assuming that userspace first decompress the corresponding
> pages being accessed.
> If the pages are already in system memory then KMD would have already
> decompressed them. When restoring such buffers with sysmem -> VRAM
> the KMD can't easily know which pages were originally compressed,
> so we always use uncompressed -> uncompressed here.
> With this it also means we can drop all the raw CCS handling on such
> platforms (including needing to allocate extra CCS storage).
>
> In order to support this we now need to have two different identity
> mappings for compressed and uncompressed VRAM.
> In this patch, we set up the additional identity map for the VRAM with
> compressed pat_index. We then select the appropriate mapping during
> migration/clear.During eviction (vram->sysmem), we use the mapping from compressed -> uncompressed.
> During restore (sysmem->vram), we need the mapping from uncompressed -> uncompressed.
> Therefore, we need to have two different mappings for compressed and uncompressed
> vram. We set up an additional identity map for the vram with compressed
> pat_index. We then select the appropriate mapping during migration/clear.
Nit: Formatting looks off.
>
> Signed-off-by: Akshata Jahagirdar <akshata.jahagirdar at intel.com>
Should this not be earlier in the series. I would have expected it to be
the first patch, since both the new clearing and copy logic are built on
top of this AFAICT.
> ---
> drivers/gpu/drm/xe/xe_migrate.c | 55 +++++++++++++++++++++++++--------
> 1 file changed, 42 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c
> index 2fc2cf375b1e..a3d6d3113ac2 100644
> --- a/drivers/gpu/drm/xe/xe_migrate.c
> +++ b/drivers/gpu/drm/xe/xe_migrate.c
> @@ -120,14 +120,20 @@ static u64 xe_migrate_vm_addr(u64 slot, u32 level)
> return (slot + 1ULL) << xe_pt_shift(level + 1);
> }
>
> -static u64 xe_migrate_vram_ofs(struct xe_device *xe, u64 addr)
> +static u64 xe_migrate_vram_ofs(struct xe_device *xe, u64 addr, bool is_comp_pte)
> {
> /*
> * Remove the DPA to get a correct offset into identity table for the
> * migrate offset
> */
> + u64 identity_offset = 256ULL;
> +
> + if (GRAPHICS_VER(xe) >= 20 && is_comp_pte)
> + identity_offset = 256ULL +
> + DIV_ROUND_UP_ULL(xe->mem.vram.actual_physical_size, SZ_1G);
> +
> addr -= xe->mem.vram.dpa_base;
> - return addr + (256ULL << xe_pt_shift(2));
> + return addr + (identity_offset << xe_pt_shift(2));
> }
>
> static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
> @@ -214,12 +220,12 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
> } else {
> u64 batch_addr = xe_bo_addr(batch, 0, XE_PAGE_SIZE);
>
> - m->batch_base_ofs = xe_migrate_vram_ofs(xe, batch_addr);
> + m->batch_base_ofs = xe_migrate_vram_ofs(xe, batch_addr, false);
>
> if (xe->info.has_usm) {
> batch = tile->primary_gt->usm.bb_pool->bo;
> batch_addr = xe_bo_addr(batch, 0, XE_PAGE_SIZE);
> - m->usm_batch_base_ofs = xe_migrate_vram_ofs(xe, batch_addr);
> + m->usm_batch_base_ofs = xe_migrate_vram_ofs(xe, batch_addr, false);
> }
> }
>
> @@ -251,7 +257,7 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
> | XE_PTE_NULL);
> m->cleared_mem_ofs = (255ULL << xe_pt_shift(level));
>
> - /* Identity map the entire vram at 256GiB offset */
> + /* Identity map the entire vram for uncompressed pat_index at 256GiB offset */
> if (IS_DGFX(xe)) {
> u64 pos, ofs, flags;
> /* XXX: Unclear if this should be usable_size? */
> @@ -294,6 +300,30 @@ static int xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
> }
>
> xe_assert(xe, pos == vram_limit);
> +
> + /*
> + * Identity map the entire vram for compressed pat_index for xe2+
> + * if flat ccs is enabled.
> + */
> + if (GRAPHICS_VER(xe) >= 20 && xe_device_has_flat_ccs(xe)) {
> + u16 comp_pat_index = xe->pat.idx[XE_CACHE_NONE_COMPRESSION];
> + u64 vram_offset = 256 +
> + DIV_ROUND_UP_ULL(xe->mem.vram.actual_physical_size, SZ_1G);
> +
> + level = 2;
> + ofs = map_ofs + XE_PAGE_SIZE * level + vram_offset * 8;
> + flags = vm->pt_ops->pte_encode_addr(xe, 0, comp_pat_index, level,
> + true, 0);
> +
> + /*
> + * Use 1GB pages, it shouldn't matter the physical amount of
> + * vram is less, when we don't access it.
> + */
> + for (pos = xe->mem.vram.dpa_base;
> + pos < xe->mem.vram.actual_physical_size + xe->mem.vram.dpa_base;
> + pos += SZ_1G, ofs += 8)
Nit: Formatting looks off? There are some other formatting issues
reported by checkpatch in the ci results.
Also it looks like there were some recent changes in
xe_migrate_prepare_vm, with how the identity map is constructed. I think
this will need to be updated to match? See:
6d3581edffea0b3a64b0d3094d3f09222e0024f7.
> + xe_map_wr(xe, &bo->vmap, ofs, u64, pos | flags);
> + }
> }
>
> /*
> @@ -475,7 +505,7 @@ static bool xe_migrate_allow_identity(u64 size, const struct xe_res_cursor *cur)
> }
>
> static u32 pte_update_size(struct xe_migrate *m,
> - bool is_vram,
> + bool is_vram, bool is_comp_pte,
> struct ttm_resource *res,
> struct xe_res_cursor *cur,
> u64 *L0, u64 *L0_ofs, u32 *L0_pt,
> @@ -487,7 +517,7 @@ static u32 pte_update_size(struct xe_migrate *m,
> if (is_vram && xe_migrate_allow_identity(*L0, cur)) {
> /* Offset into identity map. */
> *L0_ofs = xe_migrate_vram_ofs(tile_to_xe(m->tile),
> - cur->start + vram_region_gpu_offset(res));
> + cur->start + vram_region_gpu_offset(res), is_comp_pte);
> cmds += cmd_size;
> } else {
> /* Clip L0 to available size */
> @@ -778,17 +808,17 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m,
>
> src_L0 = min(src_L0, dst_L0);
>
> - batch_size += pte_update_size(m, src_is_vram, src, &src_it, &src_L0,
> + batch_size += pte_update_size(m, src_is_vram, false, src, &src_it, &src_L0,
> &src_L0_ofs, &src_L0_pt, 0, 0,
> avail_pts);
>
> - batch_size += pte_update_size(m, dst_is_vram, dst, &dst_it, &src_L0,
> + batch_size += pte_update_size(m, dst_is_vram, false, dst, &dst_it, &src_L0,
> &dst_L0_ofs, &dst_L0_pt, 0,
> avail_pts, avail_pts);
>
> if (copy_system_ccs) {
> ccs_size = xe_device_ccs_bytes(xe, src_L0);
> - batch_size += pte_update_size(m, false, NULL, &ccs_it, &ccs_size,
> + batch_size += pte_update_size(m, false, false, NULL, &ccs_it, &ccs_size,
> &ccs_ofs, &ccs_pt, 0,
> 2 * avail_pts,
> avail_pts);
> @@ -1029,14 +1059,13 @@ struct dma_fence *xe_migrate_clear(struct xe_migrate *m,
>
> /* Calculate final sizes and batch size.. */
> batch_size = 2 +
> - pte_update_size(m, clear_vram, src, &src_it,
> + pte_update_size(m, clear_vram, false, src, &src_it,
> &clear_L0, &clear_L0_ofs, &clear_L0_pt,
> clear_system_ccs ? 0 : emit_clear_cmd_len(gt), 0,
> avail_pts);
>
> if (xe_device_needs_ccs_emit(xe))
> batch_size += EMIT_COPY_CCS_DW;
> -
> /* Clear commands */
>
> if (WARN_ON_ONCE(!clear_L0))
> @@ -1146,7 +1175,7 @@ static void write_pgtable(struct xe_tile *tile, struct xe_bb *bb, u64 ppgtt_ofs,
> if (!ppgtt_ofs)
> ppgtt_ofs = xe_migrate_vram_ofs(tile_to_xe(tile),
> xe_bo_addr(update->pt_bo, 0,
> - XE_PAGE_SIZE));
> + XE_PAGE_SIZE), false);
>
> do {
> u64 addr = ppgtt_ofs + ofs * 8;
More information about the Intel-xe
mailing list