drivers/gpu/drm/xe/xe_sa.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_sa.c
Extension
.c
Size
6996 bytes
Lines
253
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

if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
			fs_reclaim_acquire(GFP_KERNEL);
			might_lock(&sa_manager->swap_guard);
			fs_reclaim_release(GFP_KERNEL);
		}

		shadow = xe_managed_bo_create_pin_map(xe, tile, size,
						      XE_BO_FLAG_VRAM_IF_DGFX(tile) |
						      XE_BO_FLAG_GGTT |
						      XE_BO_FLAG_GGTT_INVALIDATE |
						      XE_BO_FLAG_PINNED_NORESTORE);
		if (IS_ERR(shadow)) {
			drm_err(&xe->drm, "Failed to prepare %uKiB BO for SA manager (%pe)\n",
				size / SZ_1K, shadow);
			return ERR_CAST(shadow);
		}
		sa_manager->shadow = shadow;
	}

	drm_suballoc_manager_init(&sa_manager->base, managed_size, align);
	ret = drmm_add_action_or_reset(&xe->drm, xe_sa_bo_manager_fini,
				       sa_manager);
	if (ret)
		return ERR_PTR(ret);

	return sa_manager;
}

/**
 * xe_sa_bo_swap_shadow() - Swap the SA BO with shadow BO.
 * @sa_manager: the XE sub allocator manager
 *
 * Swaps the sub-allocator primary buffer object with shadow buffer object.
 *
 * Return: None.
 */
void xe_sa_bo_swap_shadow(struct xe_sa_manager *sa_manager)
{
	struct xe_device *xe = tile_to_xe(sa_manager->bo->tile);

	xe_assert(xe, sa_manager->shadow);
	lockdep_assert_held(&sa_manager->swap_guard);

	swap(sa_manager->bo, sa_manager->shadow);
	if (!sa_manager->bo->vmap.is_iomem)
		sa_manager->cpu_ptr = sa_manager->bo->vmap.vaddr;
}

/**
 * xe_sa_bo_sync_shadow() - Sync the SA Shadow BO with primary BO.
 * @sa_bo: the sub-allocator buffer object.
 *
 * Synchronize sub-allocator shadow buffer object with primary buffer object.
 *
 * Return: None.
 */
void xe_sa_bo_sync_shadow(struct drm_suballoc *sa_bo)
{
	struct xe_sa_manager *sa_manager = to_xe_sa_manager(sa_bo->manager);
	struct xe_device *xe = tile_to_xe(sa_manager->bo->tile);

	xe_assert(xe, sa_manager->shadow);
	lockdep_assert_held(&sa_manager->swap_guard);

	xe_map_memcpy_to(xe, &sa_manager->shadow->vmap,
			 drm_suballoc_soffset(sa_bo),
			 xe_sa_bo_cpu_addr(sa_bo),
			 drm_suballoc_size(sa_bo));
}

/**
 * __xe_sa_bo_new() - Make a suballocation but use custom gfp flags.
 * @sa_manager: the &xe_sa_manager
 * @size: number of bytes we want to suballocate
 * @gfp: gfp flags used for memory allocation. Typically GFP_KERNEL.
 *
 * Try to make a suballocation of size @size.
 *
 * Return: a &drm_suballoc, or an ERR_PTR.
 */
struct drm_suballoc *__xe_sa_bo_new(struct xe_sa_manager *sa_manager, u32 size, gfp_t gfp)
{
	/*
	 * BB to large, return -ENOBUFS indicating user should split
	 * array of binds into smaller chunks.
	 */
	if (size > sa_manager->base.size)
		return ERR_PTR(-ENOBUFS);

	return drm_suballoc_new(&sa_manager->base, size, gfp, true, 0);

Annotation

Implementation Notes