Commit 4b0a5f5c authored by Piotr Piórkowski's avatar Piotr Piórkowski Committed by Lucas De Marchi
Browse files

drm/xe: Unify the initialization of VRAM regions



Currently in the drivers we have defined VRAM regions per device and per
tile. Initialization of these regions is done in two completely different
ways. To simplify the logic of the code and make it easier to add new
regions in the future, let's unify the way we initialize VRAM regions.

v2:
- fix doc comments in struct xe_vram_region
- remove unnecessary includes (Jani)
v3:
- move code from xe_vram_init_regions_managers to xe_tile_init_noalloc
  (Matthew)
- replace ioremap_wc to devm_ioremap_wc for mapping VRAM BAR
  (Matthew)
- Replace the tile id parameter with vram region in the xe_pf_begin
  function.
v4:
- remove tile back pointer from struct xe_vram_region
- add new back pointers: xe and migarte to xe_vram_region

Signed-off-by: default avatarPiotr Piórkowski <piotr.piorkowski@intel.com>
Cc: Stuart Summers <stuart.summers@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com> # rev3
Acked-by: default avatarMatthew Brost <matthew.brost@intel.com>
Link: https://lore.kernel.org/r/20250714184818.89201-6-piotr.piorkowski@intel.com


Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
parent d65ff1ec
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include "xe_macros.h"
#include "xe_vm_types.h"
#include "xe_vm.h"
#include "xe_vram_types.h"

#define XE_DEFAULT_GTT_SIZE_MB          3072ULL /* 3GB by default */

@@ -23,8 +24,9 @@
#define XE_BO_FLAG_VRAM_MASK		(XE_BO_FLAG_VRAM0 | XE_BO_FLAG_VRAM1)
/* -- */
#define XE_BO_FLAG_STOLEN		BIT(4)
#define XE_BO_FLAG_VRAM(vram)		(XE_BO_FLAG_VRAM0 << ((vram)->id))
#define XE_BO_FLAG_VRAM_IF_DGFX(tile)	(IS_DGFX(tile_to_xe(tile)) ? \
					 XE_BO_FLAG_VRAM0 << (tile)->id : \
					 XE_BO_FLAG_VRAM((tile)->mem.vram) : \
					 XE_BO_FLAG_SYSTEM)
#define XE_BO_FLAG_GGTT			BIT(5)
#define XE_BO_FLAG_IGNORE_MIN_PAGE_SIZE BIT(6)
+8 −5
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "xe_svm.h"
#include "xe_trace_bo.h"
#include "xe_vm.h"
#include "xe_vram_types.h"

struct pagefault {
	u64 page_addr;
@@ -74,7 +75,7 @@ static bool vma_is_valid(struct xe_tile *tile, struct xe_vma *vma)
}

static int xe_pf_begin(struct drm_exec *exec, struct xe_vma *vma,
		       bool atomic, unsigned int id)
		       bool atomic, struct xe_vram_region *vram)
{
	struct xe_bo *bo = xe_vma_bo(vma);
	struct xe_vm *vm = xe_vma_vm(vma);
@@ -84,14 +85,16 @@ static int xe_pf_begin(struct drm_exec *exec, struct xe_vma *vma,
	if (err)
		return err;

	if (atomic && IS_DGFX(vm->xe)) {
	if (atomic && vram) {
		xe_assert(vm->xe, IS_DGFX(vm->xe));

		if (xe_vma_is_userptr(vma)) {
			err = -EACCES;
			return err;
		}

		/* Migrate to VRAM, move should invalidate the VMA first */
		err = xe_bo_migrate(bo, XE_PL_VRAM0 + id);
		err = xe_bo_migrate(bo, vram->placement);
		if (err)
			return err;
	} else if (bo) {
@@ -138,7 +141,7 @@ static int handle_vma_pagefault(struct xe_gt *gt, struct xe_vma *vma,
	/* Lock VM and BOs dma-resv */
	drm_exec_init(&exec, 0, 0);
	drm_exec_until_all_locked(&exec) {
		err = xe_pf_begin(&exec, vma, atomic, tile->id);
		err = xe_pf_begin(&exec, vma, atomic, tile->mem.vram);
		drm_exec_retry_on_contention(&exec);
		if (xe_vm_validate_should_retry(&exec, err, &end))
			err = -EAGAIN;
@@ -573,7 +576,7 @@ static int handle_acc(struct xe_gt *gt, struct acc *acc)
	/* Lock VM and BOs dma-resv */
	drm_exec_init(&exec, 0, 0);
	drm_exec_until_all_locked(&exec) {
		ret = xe_pf_begin(&exec, vma, true, tile->id);
		ret = xe_pf_begin(&exec, vma, true, tile->mem.vram);
		drm_exec_retry_on_contention(&exec);
		if (ret)
			break;
+2 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "xe_oa.h"
#include "xe_pxp.h"
#include "xe_ttm_vram_mgr.h"
#include "xe_vram_types.h"
#include "xe_wa.h"

static const u16 xe_to_user_engine_class[] = {
@@ -410,7 +411,7 @@ static int query_gt_list(struct xe_device *xe, struct drm_xe_device_query *query
			gt_list->gt_list[iter].near_mem_regions = 0x1;
		else
			gt_list->gt_list[iter].near_mem_regions =
				BIT(gt_to_tile(gt)->id) << 1;
				BIT(gt_to_tile(gt)->mem.vram->id) << 1;
		gt_list->gt_list[iter].far_mem_regions = xe->info.mem_region_mask ^
			gt_list->gt_list[iter].near_mem_regions;

+19 −24
Original line number Diff line number Diff line
@@ -311,12 +311,11 @@ static u64 xe_vram_region_page_to_dpa(struct xe_vram_region *vr,
				      struct page *page)
{
	u64 dpa;
	struct xe_tile *tile = vr->tile;
	u64 pfn = page_to_pfn(page);
	u64 offset;

	xe_tile_assert(tile, is_device_private_page(page));
	xe_tile_assert(tile, (pfn << PAGE_SHIFT) >= vr->hpa_base);
	xe_assert(vr->xe, is_device_private_page(page));
	xe_assert(vr->xe, (pfn << PAGE_SHIFT) >= vr->hpa_base);

	offset = (pfn << PAGE_SHIFT) - vr->hpa_base;
	dpa = vr->dpa_base + offset;
@@ -333,7 +332,7 @@ static int xe_svm_copy(struct page **pages, dma_addr_t *dma_addr,
		       unsigned long npages, const enum xe_svm_copy_dir dir)
{
	struct xe_vram_region *vr = NULL;
	struct xe_tile *tile;
	struct xe_device *xe;
	struct dma_fence *fence = NULL;
	unsigned long i;
#define XE_VRAM_ADDR_INVALID	~0x0ull
@@ -366,7 +365,7 @@ static int xe_svm_copy(struct page **pages, dma_addr_t *dma_addr,

		if (!vr && spage) {
			vr = page_to_vr(spage);
			tile = vr->tile;
			xe = vr->xe;
		}
		XE_WARN_ON(spage && page_to_vr(spage) != vr);

@@ -398,18 +397,18 @@ static int xe_svm_copy(struct page **pages, dma_addr_t *dma_addr,

			if (vram_addr != XE_VRAM_ADDR_INVALID) {
				if (sram) {
					vm_dbg(&tile->xe->drm,
					vm_dbg(&xe->drm,
					       "COPY TO SRAM - 0x%016llx -> 0x%016llx, NPAGES=%ld",
					       vram_addr, (u64)dma_addr[pos], i - pos + incr);
					__fence = xe_migrate_from_vram(tile->migrate,
					__fence = xe_migrate_from_vram(vr->migrate,
								       i - pos + incr,
								       vram_addr,
								       dma_addr + pos);
				} else {
					vm_dbg(&tile->xe->drm,
					vm_dbg(&xe->drm,
					       "COPY TO VRAM - 0x%016llx -> 0x%016llx, NPAGES=%ld",
					       (u64)dma_addr[pos], vram_addr, i - pos + incr);
					__fence = xe_migrate_to_vram(tile->migrate,
					__fence = xe_migrate_to_vram(vr->migrate,
								     i - pos + incr,
								     dma_addr + pos,
								     vram_addr);
@@ -434,17 +433,17 @@ static int xe_svm_copy(struct page **pages, dma_addr_t *dma_addr,
			/* Extra mismatched device page, copy it */
			if (!match && last && vram_addr != XE_VRAM_ADDR_INVALID) {
				if (sram) {
					vm_dbg(&tile->xe->drm,
					vm_dbg(&xe->drm,
					       "COPY TO SRAM - 0x%016llx -> 0x%016llx, NPAGES=%d",
					       vram_addr, (u64)dma_addr[pos], 1);
					__fence = xe_migrate_from_vram(tile->migrate, 1,
					__fence = xe_migrate_from_vram(vr->migrate, 1,
								       vram_addr,
								       dma_addr + pos);
				} else {
					vm_dbg(&tile->xe->drm,
					vm_dbg(&xe->drm,
					       "COPY TO VRAM - 0x%016llx -> 0x%016llx, NPAGES=%d",
					       (u64)dma_addr[pos], vram_addr, 1);
					__fence = xe_migrate_to_vram(tile->migrate, 1,
					__fence = xe_migrate_to_vram(vr->migrate, 1,
								     dma_addr + pos,
								     vram_addr);
				}
@@ -502,9 +501,9 @@ static u64 block_offset_to_pfn(struct xe_vram_region *vr, u64 offset)
	return PHYS_PFN(offset + vr->hpa_base);
}

static struct drm_buddy *tile_to_buddy(struct xe_tile *tile)
static struct drm_buddy *vram_to_buddy(struct xe_vram_region *vram)
{
	return &tile->mem.vram->ttm.mm;
	return &vram->ttm.mm;
}

static int xe_svm_populate_devmem_pfn(struct drm_pagemap_devmem *devmem_allocation,
@@ -518,8 +517,7 @@ static int xe_svm_populate_devmem_pfn(struct drm_pagemap_devmem *devmem_allocati

	list_for_each_entry(block, blocks, link) {
		struct xe_vram_region *vr = block->private;
		struct xe_tile *tile = vr->tile;
		struct drm_buddy *buddy = tile_to_buddy(tile);
		struct drm_buddy *buddy = vram_to_buddy(vr);
		u64 block_pfn = block_offset_to_pfn(vr, drm_buddy_block_offset(block));
		int i;

@@ -685,8 +683,7 @@ static int xe_drm_pagemap_populate_mm(struct drm_pagemap *dpagemap,
				      unsigned long timeslice_ms)
{
	struct xe_vram_region *vr = container_of(dpagemap, typeof(*vr), dpagemap);
	struct xe_tile *tile = vr->tile;
	struct xe_device *xe = tile_to_xe(tile);
	struct xe_device *xe = vr->xe;
	struct device *dev = xe->drm.dev;
	struct drm_buddy_block *block;
	struct list_head *blocks;
@@ -700,9 +697,9 @@ static int xe_drm_pagemap_populate_mm(struct drm_pagemap *dpagemap,
	xe_pm_runtime_get(xe);

 retry:
	bo = xe_bo_create_locked(tile_to_xe(tile), NULL, NULL, end - start,
	bo = xe_bo_create_locked(vr->xe, NULL, NULL, end - start,
				 ttm_bo_type_device,
				 XE_BO_FLAG_VRAM_IF_DGFX(tile) |
				 (IS_DGFX(xe) ? XE_BO_FLAG_VRAM(vr) : XE_BO_FLAG_SYSTEM) |
				 XE_BO_FLAG_CPU_ADDR_MIRROR);
	if (IS_ERR(bo)) {
		err = PTR_ERR(bo);
@@ -712,9 +709,7 @@ static int xe_drm_pagemap_populate_mm(struct drm_pagemap *dpagemap,
	}

	drm_pagemap_devmem_init(&bo->devmem_allocation, dev, mm,
				&dpagemap_devmem_ops,
				&tile->mem.vram->dpagemap,
				end - start);
				&dpagemap_devmem_ops, dpagemap, end - start);

	blocks = &to_xe_ttm_vram_mgr_resource(bo->ttm.resource)->blocks;
	list_for_each_entry(block, blocks, link)
+12 −25
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@

#include <drm/drm_managed.h>

#include "xe_bo.h"
#include "xe_device.h"
#include "xe_ggtt.h"
#include "xe_gt.h"
@@ -118,11 +119,9 @@ int xe_tile_alloc_vram(struct xe_tile *tile)
	if (!IS_DGFX(xe))
		return 0;

	vram = drmm_kzalloc(&xe->drm, sizeof(*vram), GFP_KERNEL);
	if (!vram)
		return -ENOMEM;

	vram->tile = tile;
	vram = xe_vram_region_alloc(xe, tile->id, XE_PL_VRAM0 + tile->id);
	if (IS_ERR(vram))
		return PTR_ERR(vram);
	tile->mem.vram = vram;

	return 0;
@@ -160,21 +159,6 @@ int xe_tile_init_early(struct xe_tile *tile, struct xe_device *xe, u8 id)
}
ALLOW_ERROR_INJECTION(xe_tile_init_early, ERRNO); /* See xe_pci_probe() */

static int tile_ttm_mgr_init(struct xe_tile *tile)
{
	struct xe_device *xe = tile_to_xe(tile);
	int err;

	if (tile->mem.vram) {
		err = xe_ttm_vram_mgr_init(tile, &tile->mem.vram->ttm);
		if (err)
			return err;
		xe->info.mem_region_mask |= BIT(tile->id) << 1;
	}

	return 0;
}

/**
 * xe_tile_init_noalloc - Init tile up to the point where allocations can happen.
 * @tile: The tile to initialize.
@@ -192,17 +176,20 @@ static int tile_ttm_mgr_init(struct xe_tile *tile)
int xe_tile_init_noalloc(struct xe_tile *tile)
{
	struct xe_device *xe = tile_to_xe(tile);
	int err;

	err = tile_ttm_mgr_init(tile);
	if (err)
		return err;

	xe_wa_apply_tile_workarounds(tile);

	if (xe->info.has_usm && IS_DGFX(xe))
		xe_devm_add(tile, tile->mem.vram);

	if (IS_DGFX(xe) && !ttm_resource_manager_used(&tile->mem.vram->ttm.manager)) {
		int err = xe_ttm_vram_mgr_init(xe, tile->mem.vram);

		if (err)
			return err;
		xe->info.mem_region_mask |= BIT(tile->mem.vram->id) << 1;
	}

	return xe_tile_sysfs_init(tile);
}

Loading