[Intel-xe] [PATCH 3/5] drm/xe/pf: Introduce Local Memory Translation Table
Michał Winiarski
michal.winiarski at intel.com
Thu Dec 7 00:43:07 UTC 2023
On Tue, Nov 28, 2023 at 04:15:05PM +0100, Michal Wajdeczko wrote:
> The Local Memory Translation Table (LMTT) provides additional
> abstraction for Virtual Functions (VF) accessing device VRAM.
>
> This code is based on prior work of Michal Winiarski.
>
> In this patch we focus only on LMTT initialization. Remaining LMTT
> functions will be used once we add a VF provisioning to the PF.
>
> Bspec: 44117, 52404, 59314
> Signed-off-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
Reviewed-by: Michał Winiarski <michal.winiarski at intel.com>
One small comment/question below.
> ---
> drivers/gpu/drm/xe/Makefile | 5 +
> drivers/gpu/drm/xe/regs/xe_sriov_regs.h | 17 +
> drivers/gpu/drm/xe/xe_device_types.h | 8 +
> drivers/gpu/drm/xe/xe_gt.c | 10 +
> drivers/gpu/drm/xe/xe_lmtt.c | 502 ++++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_lmtt.h | 27 ++
> drivers/gpu/drm/xe/xe_lmtt_2l.c | 150 +++++++
> drivers/gpu/drm/xe/xe_lmtt_ml.c | 161 ++++++++
> drivers/gpu/drm/xe/xe_lmtt_types.h | 63 +++
> 9 files changed, 943 insertions(+)
> create mode 100644 drivers/gpu/drm/xe/regs/xe_sriov_regs.h
> create mode 100644 drivers/gpu/drm/xe/xe_lmtt.c
> create mode 100644 drivers/gpu/drm/xe/xe_lmtt.h
> create mode 100644 drivers/gpu/drm/xe/xe_lmtt_2l.c
> create mode 100644 drivers/gpu/drm/xe/xe_lmtt_ml.c
> create mode 100644 drivers/gpu/drm/xe/xe_lmtt_types.h
>
> diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
> index 551adbc22b5a..cf1237a148b1 100644
> --- a/drivers/gpu/drm/xe/Makefile
> +++ b/drivers/gpu/drm/xe/Makefile
> @@ -125,6 +125,11 @@ xe-$(CONFIG_HWMON) += xe_hwmon.o
> # graphics virtualization (SR-IOV) support
> xe-y += xe_sriov.o
>
> +xe-$(CONFIG_PCI_IOV) += \
> + xe_lmtt.o \
> + xe_lmtt_2l.o \
> + xe_lmtt_ml.o
> +
> # i915 Display compat #defines and #includes
> subdir-ccflags-$(CONFIG_DRM_XE_DISPLAY) += \
> -I$(srctree)/$(src)/display/ext \
> diff --git a/drivers/gpu/drm/xe/regs/xe_sriov_regs.h b/drivers/gpu/drm/xe/regs/xe_sriov_regs.h
> new file mode 100644
> index 000000000000..58a4e0fad1e1
> --- /dev/null
> +++ b/drivers/gpu/drm/xe/regs/xe_sriov_regs.h
> @@ -0,0 +1,17 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +
> +#ifndef _REGS_XE_SRIOV_REGS_H_
> +#define _REGS_XE_SRIOV_REGS_H_
> +
> +#include "regs/xe_reg_defs.h"
> +
> +#define XE2_LMEM_CFG XE_REG(0x48b0)
> +
> +#define LMEM_CFG XE_REG(0xcf58)
> +#define LMEM_EN REG_BIT(31)
> +#define LMTT_DIR_PTR REG_GENMASK(30, 0) /* in multiples of 64KB */
> +
> +#endif
> diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
> index 2712905c7a91..bded80c50027 100644
> --- a/drivers/gpu/drm/xe/xe_device_types.h
> +++ b/drivers/gpu/drm/xe/xe_device_types.h
> @@ -15,6 +15,7 @@
> #include "xe_devcoredump_types.h"
> #include "xe_heci_gsc.h"
> #include "xe_gt_types.h"
> +#include "xe_lmtt_types.h"
> #include "xe_platform_types.h"
> #include "xe_pt_types.h"
> #include "xe_pmu.h"
> @@ -186,6 +187,13 @@ struct xe_tile {
> struct xe_sa_manager *kernel_bb_pool;
> } mem;
>
> + union {
> + struct {
> + /** @sriov.pf.lmtt: Local Memory Translation Table. */
> + struct xe_lmtt lmtt;
> + } pf;
> + } sriov;
> +
> /** @migrate: Migration helper for vram blits and clearing */
> struct xe_migrate *migrate;
>
> diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
> index 0dddb751c6a4..2c311b0e49ee 100644
> --- a/drivers/gpu/drm/xe/xe_gt.c
> +++ b/drivers/gpu/drm/xe/xe_gt.c
> @@ -34,6 +34,7 @@
> #include "xe_hw_fence.h"
> #include "xe_hw_engine_class_sysfs.h"
> #include "xe_irq.h"
> +#include "xe_lmtt.h"
> #include "xe_lrc.h"
> #include "xe_map.h"
> #include "xe_migrate.h"
> @@ -44,6 +45,7 @@
> #include "xe_ring_ops.h"
> #include "xe_sa.h"
> #include "xe_sched_job.h"
> +#include "xe_sriov.h"
> #include "xe_tuning.h"
> #include "xe_uc.h"
> #include "xe_vm.h"
> @@ -344,6 +346,8 @@ static int gt_fw_domain_init(struct xe_gt *gt)
> err = xe_ggtt_init(gt_to_tile(gt)->mem.ggtt);
> if (err)
> goto err_force_wake;
> + if (IS_SRIOV_PF(gt_to_xe(gt)))
> + xe_lmtt_init(>_to_tile(gt)->sriov.pf.lmtt);
> }
>
> err = xe_uc_init(>->uc);
> @@ -451,6 +455,9 @@ static int all_fw_domain_init(struct xe_gt *gt)
> if (err)
> goto err_force_wake;
>
> + if (IS_SRIOV_PF(gt_to_xe(gt)) && !xe_gt_is_media_type(gt))
> + xe_lmtt_init_hw(>_to_tile(gt)->sriov.pf.lmtt);
> +
> err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
> XE_WARN_ON(err);
> xe_device_mem_access_put(gt_to_xe(gt));
> @@ -543,6 +550,9 @@ static int do_gt_restart(struct xe_gt *gt)
> if (err)
> return err;
>
> + if (IS_SRIOV_PF(gt_to_xe(gt)) && !xe_gt_is_media_type(gt))
> + xe_lmtt_init_hw(>_to_tile(gt)->sriov.pf.lmtt);
> +
> xe_mocs_init(gt);
> err = xe_uc_start(>->uc);
> if (err)
> diff --git a/drivers/gpu/drm/xe/xe_lmtt.c b/drivers/gpu/drm/xe/xe_lmtt.c
> new file mode 100644
> index 000000000000..d5ada31ae633
> --- /dev/null
> +++ b/drivers/gpu/drm/xe/xe_lmtt.c
> @@ -0,0 +1,502 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2023 Intel Corporation
> + */
> +
> +#include <linux/align.h>
> +
> +#include <drm/drm_managed.h>
> +
> +#include "regs/xe_sriov_regs.h"
> +
> +#include "xe_assert.h"
> +#include "xe_bo.h"
> +#include "xe_lmtt.h"
> +#include "xe_map.h"
> +#include "xe_mmio.h"
> +#include "xe_res_cursor.h"
> +#include "xe_sriov.h"
> +#include "xe_sriov_printk.h"
> +
> +/**
> + * DOC: Local Memory Translation Table
> + *
> + * The Local Memory Translation Table (LMTT) provides additional abstraction
> + * when Virtual Function (VF) is accessing device Local Memory (VRAM).
> + *
> + * The Root LMTT Page Directory contains one entry for each VF. Entries are
> + * indexed by the function number (1-based, index 0 is unused).
> + *
> + * See `Two-Level LMTT Structure`_ and `Multi-Level LMTT Structure`_.
> + */
> +
> +#define lmtt_assert(lmtt, condition) xe_tile_assert(lmtt_to_tile(lmtt), condition)
> +#define lmtt_debug(lmtt, msg...) xe_sriov_dbg_verbose(lmtt_to_xe(lmtt), "LMTT: " msg)
> +
> +static bool xe_has_multi_level_lmtt(struct xe_device *xe)
> +{
> + return xe->info.platform == XE_PVC;
> +}
> +
> +static struct xe_tile *lmtt_to_tile(struct xe_lmtt *lmtt)
> +{
> + return container_of(lmtt, struct xe_tile, sriov.pf.lmtt);
> +}
> +
> +static struct xe_device *lmtt_to_xe(struct xe_lmtt *lmtt)
> +{
> + return tile_to_xe(lmtt_to_tile(lmtt));
> +}
> +
> +static u64 lmtt_page_size(struct xe_lmtt *lmtt)
> +{
> + return BIT_ULL(lmtt->ops->lmtt_pte_shift(0));
> +}
> +
> +static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level)
> +{
> + unsigned int num_entries = level ? lmtt->ops->lmtt_pte_num(level) : 0;
> + struct xe_lmtt_pt *pt;
> + struct xe_bo *bo;
> + int err;
> +
> + pt = kzalloc(struct_size(pt, entries, num_entries), GFP_KERNEL);
> + if (!pt) {
> + err = -ENOMEM;
> + goto out;
> + }
> +
> + bo = xe_bo_create_pin_map(lmtt_to_xe(lmtt), lmtt_to_tile(lmtt), NULL,
> + PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) *
> + lmtt->ops->lmtt_pte_num(level)),
> + ttm_bo_type_kernel,
> + XE_BO_CREATE_VRAM_IF_DGFX(lmtt_to_tile(lmtt)) |
> + XE_BO_CREATE_PINNED_BIT);
I know that we have WARNs for misaligned objects, but do we actually
have a guarantee that PTs are contiguous and 64K aligned at this point?
-Michał
> + if (IS_ERR(bo)) {
> + err = PTR_ERR(bo);
> + goto out_free_pt;
> + }
> +
> + lmtt_assert(lmtt, xe_bo_is_vram(bo));
> +
> + pt->level = level;
> + pt->bo = bo;
> + return pt;
> +
> +out_free_pt:
> + kfree(pt);
> +out:
> + return ERR_PTR(err);
> +}
More information about the Intel-xe
mailing list