drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
Extension
.c
Size
16788 bytes
Lines
640
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 amdgpu_pasid_cb {
	struct dma_fence_cb cb;
	u32 pasid;
};

/**
 * amdgpu_pasid_alloc - Allocate a PASID
 * @bits: Maximum width of the PASID in bits, must be at least 1
 *
 * Uses kernel's IDR cyclic allocator (same as PID allocation).
 * Allocates sequentially with automatic wrap-around.
 *
 * Returns a positive integer on success. Returns %-EINVAL if bits==0.
 * Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on
 * memory allocation failure.
 */
int amdgpu_pasid_alloc(unsigned int bits)
{
	u32 pasid;
	int r;

	if (bits == 0)
		return -EINVAL;

	r = xa_alloc_cyclic_irq(&amdgpu_pasid_xa, &pasid, xa_mk_value(0),
			    XA_LIMIT(1, (1U << bits) - 1),
			    &amdgpu_pasid_xa_next, GFP_KERNEL);
	if (r < 0)
		return r;

	trace_amdgpu_pasid_allocated(pasid);
	return pasid;
}

/**
 * amdgpu_pasid_free - Free a PASID
 * @pasid: PASID to free
 *
 * Called in IRQ context.
 */
void amdgpu_pasid_free(u32 pasid)
{
	unsigned long flags;

	trace_amdgpu_pasid_freed(pasid);

	xa_lock_irqsave(&amdgpu_pasid_xa, flags);
	__xa_erase(&amdgpu_pasid_xa, pasid);
	xa_unlock_irqrestore(&amdgpu_pasid_xa, flags);
}

static void amdgpu_pasid_free_cb(struct dma_fence *fence,
				 struct dma_fence_cb *_cb)
{
	struct amdgpu_pasid_cb *cb =
		container_of(_cb, struct amdgpu_pasid_cb, cb);

	amdgpu_pasid_free(cb->pasid);
	dma_fence_put(fence);
	kfree(cb);
}

/**
 * amdgpu_pasid_free_delayed - free pasid when fences signal
 *
 * @resv: reservation object with the fences to wait for
 * @pasid: pasid to free
 *
 * Free the pasid only after all the fences in resv are signaled.
 */
void amdgpu_pasid_free_delayed(struct dma_resv *resv,
			       u32 pasid)
{
	struct amdgpu_pasid_cb *cb;
	struct dma_fence *fence;
	int r;

	r = dma_resv_get_singleton(resv, DMA_RESV_USAGE_BOOKKEEP, &fence);
	if (r)
		goto fallback;

	if (!fence) {
		amdgpu_pasid_free(pasid);
		return;
	}

	cb = kmalloc_obj(*cb);
	if (!cb) {
		/* Last resort when we are OOM */
		dma_fence_wait(fence, false);

Annotation

Implementation Notes