drivers/gpu/drm/xe/xe_bo.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_bo.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_bo.c
Extension
.c
Size
105443 bytes
Lines
3897
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct xe_ttm_tt {
	struct ttm_tt ttm;
	struct sg_table sgt;
	struct sg_table *sg;
	/** @purgeable: Whether the content of the pages of @ttm is purgeable. */
	bool purgeable;
};

static int xe_tt_map_sg(struct xe_device *xe, struct ttm_tt *tt)
{
	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
	unsigned long num_pages = tt->num_pages;
	int ret;

	XE_WARN_ON((tt->page_flags & TTM_TT_FLAG_EXTERNAL) &&
		   !(tt->page_flags & TTM_TT_FLAG_EXTERNAL_MAPPABLE));

	if (xe_tt->sg)
		return 0;

	ret = sg_alloc_table_from_pages_segment(&xe_tt->sgt, tt->pages,
						num_pages, 0,
						(u64)num_pages << PAGE_SHIFT,
						xe_sg_segment_size(xe->drm.dev),
						GFP_KERNEL);
	if (ret)
		return ret;

	xe_tt->sg = &xe_tt->sgt;
	ret = dma_map_sgtable(xe->drm.dev, xe_tt->sg, DMA_BIDIRECTIONAL,
			      DMA_ATTR_SKIP_CPU_SYNC);
	if (ret) {
		sg_free_table(xe_tt->sg);
		xe_tt->sg = NULL;
		return ret;
	}

	return 0;
}

static void xe_tt_unmap_sg(struct xe_device *xe, struct ttm_tt *tt)
{
	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);

	if (xe_tt->sg) {
		dma_unmap_sgtable(xe->drm.dev, xe_tt->sg,
				  DMA_BIDIRECTIONAL, 0);
		sg_free_table(xe_tt->sg);
		xe_tt->sg = NULL;
	}
}

struct sg_table *xe_bo_sg(struct xe_bo *bo)
{
	struct ttm_tt *tt = bo->ttm.ttm;
	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);

	return xe_tt->sg;
}

/*
 * Account ttm pages against the device shrinker's shrinkable and
 * purgeable counts.
 */
static void xe_ttm_tt_account_add(struct xe_device *xe, struct ttm_tt *tt)
{
	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);

	if (xe_tt->purgeable)
		xe_shrinker_mod_pages(xe->mem.shrinker, 0, tt->num_pages);
	else
		xe_shrinker_mod_pages(xe->mem.shrinker, tt->num_pages, 0);
}

static void xe_ttm_tt_account_subtract(struct xe_device *xe, struct ttm_tt *tt)
{
	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);

	if (xe_tt->purgeable)
		xe_shrinker_mod_pages(xe->mem.shrinker, 0, -(long)tt->num_pages);
	else
		xe_shrinker_mod_pages(xe->mem.shrinker, -(long)tt->num_pages, 0);
}

static void update_global_total_pages(struct ttm_device *ttm_dev,
				      long num_pages)
{
#if IS_ENABLED(CONFIG_TRACE_GPU_MEM)
	struct xe_device *xe = ttm_to_xe_device(ttm_dev);
	u64 global_total_pages =

Annotation

Implementation Notes