[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(&gt_to_tile(gt)->sriov.pf.lmtt);
>  	}
>  
>  	err = xe_uc_init(&gt->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(&gt_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(&gt_to_tile(gt)->sriov.pf.lmtt);
> +
>  	xe_mocs_init(gt);
>  	err = xe_uc_start(&gt->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