drivers/gpu/drm/xe/xe_mem_pool.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_mem_pool.c
Extension
.c
Size
11181 bytes
Lines
404
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_mem_pool {
	/** @base: Range allocator over [0, @size) in bytes */
	struct drm_mm base;
	/** @bo: Active pool BO (GGTT-pinned, CPU-mapped). */
	struct xe_bo *bo;
	/** @shadow: Shadow BO for atomic command updates. */
	struct xe_bo *shadow;
	/** @swap_guard: Timeline guard updating @bo and @shadow */
	struct mutex swap_guard;
	/** @cpu_addr: CPU virtual address of the active BO. */
	void *cpu_addr;
	/** @is_iomem: Indicates if the BO mapping is I/O memory. */
	bool is_iomem;
};

static struct xe_mem_pool *node_to_pool(struct xe_mem_pool_node *node)
{
	return container_of(node->sa_node.mm, struct xe_mem_pool, base);
}

static struct xe_tile *pool_to_tile(struct xe_mem_pool *pool)
{
	return pool->bo->tile;
}

static void fini_pool_action(struct drm_device *drm, void *arg)
{
	struct xe_mem_pool *pool = arg;

	if (pool->is_iomem)
		kvfree(pool->cpu_addr);

	drm_mm_takedown(&pool->base);
}

static int pool_shadow_init(struct xe_mem_pool *pool)
{
	struct xe_tile *tile = pool->bo->tile;
	struct xe_device *xe = tile_to_xe(tile);
	struct xe_bo *shadow;
	int ret;

	xe_assert(xe, !pool->shadow);

	ret = drmm_mutex_init(&xe->drm, &pool->swap_guard);
	if (ret)
		return ret;

	if (IS_ENABLED(CONFIG_PROVE_LOCKING)) {
		fs_reclaim_acquire(GFP_KERNEL);
		might_lock(&pool->swap_guard);
		fs_reclaim_release(GFP_KERNEL);
	}
	shadow = xe_managed_bo_create_pin_map(xe, tile,
					      xe_bo_size(pool->bo),
					      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))
		return PTR_ERR(shadow);

	pool->shadow = shadow;

	return 0;
}

/**
 * xe_mem_pool_init() - Initialize memory pool.
 * @tile: the &xe_tile where allocate.
 * @size: number of bytes to allocate.
 * @guard: the size of the guard region at the end of the BO that is not
 * sub-allocated, in bytes.
 * @flags: flags to use to create shadow pool.
 *
 * Initializes a memory pool for sub-allocating memory from a backing BO on the
 * specified XE tile. The backing BO is pinned in the GGTT and mapped into
 * the CPU address space for direct access. Optionally, a shadow BO can also be
 * initialized for atomic updates to the primary BO's contents.
 *
 * Returns: a pointer to the &xe_mem_pool, or an error pointer on failure.
 */
struct xe_mem_pool *xe_mem_pool_init(struct xe_tile *tile, u32 size,
				     u32 guard, int flags)
{
	struct xe_device *xe = tile_to_xe(tile);
	struct xe_mem_pool *pool;
	struct xe_bo *bo;
	u32 managed_size;
	int ret;

Annotation

Implementation Notes