drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
Extension
.c
Size
32564 bytes
Lines
1086
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

KFD_GC_VERSION(mm->dev) != IP_VERSION(9, 5, 0)) {
		m->compute_static_thread_mgmt_se4 = se_mask[4];
		m->compute_static_thread_mgmt_se5 = se_mask[5];
		m->compute_static_thread_mgmt_se6 = se_mask[6];
		m->compute_static_thread_mgmt_se7 = se_mask[7];

		pr_debug("update cu mask to %#x %#x %#x %#x %#x %#x %#x %#x\n",
			m->compute_static_thread_mgmt_se0,
			m->compute_static_thread_mgmt_se1,
			m->compute_static_thread_mgmt_se2,
			m->compute_static_thread_mgmt_se3,
			m->compute_static_thread_mgmt_se4,
			m->compute_static_thread_mgmt_se5,
			m->compute_static_thread_mgmt_se6,
			m->compute_static_thread_mgmt_se7);
	} else {
		pr_debug("inst: %u, update cu mask to %#x %#x %#x %#x\n",
			inst, m->compute_static_thread_mgmt_se0,
			m->compute_static_thread_mgmt_se1,
			m->compute_static_thread_mgmt_se2,
			m->compute_static_thread_mgmt_se3);
	}
}

static void set_priority(struct v9_mqd *m, struct queue_properties *q)
{
	m->cp_hqd_pipe_priority = pipe_priority_map[q->priority];
}

static bool mqd_on_vram(struct amdgpu_device *adev)
{
	if (adev->apu_prefer_gtt)
		return false;

	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
	case IP_VERSION(9, 4, 3):
	case IP_VERSION(9, 5, 0):
		return true;
	default:
		return false;
	}
}

static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm,
		struct queue_properties *q)
{
	int retval;
	struct kfd_node *node = mm->dev;
	struct kfd_mem_obj *mqd_mem_obj = NULL;

	/* For V9 only, due to a HW bug, the control stack of a user mode
	 * compute queue needs to be allocated just behind the page boundary
	 * of its regular MQD buffer. So we allocate an enlarged MQD buffer:
	 * the first page of the buffer serves as the regular MQD buffer
	 * purpose and the remaining is for control stack. Although the two
	 * parts are in the same buffer object, they need different memory
	 * types: MQD part needs UC (uncached) as usual, while control stack
	 * needs NC (non coherent), which is different from the UC type which
	 * is used when control stack is allocated in user space.
	 *
	 * Because of all those, we use the gtt allocation function instead
	 * of sub-allocation function for this enlarged MQD buffer. Moreover,
	 * in order to achieve two memory types in a single buffer object, we
	 * pass a special bo flag AMDGPU_GEM_CREATE_CP_MQD_GFX9 to instruct
	 * amdgpu memory functions to do so.
	 */
	if (node->kfd->cwsr_enabled && (q->type == KFD_QUEUE_TYPE_COMPUTE)) {
		mqd_mem_obj = kzalloc_obj(struct kfd_mem_obj);
		if (!mqd_mem_obj)
			return NULL;
		retval = amdgpu_amdkfd_alloc_kernel_mem(node->adev,
			(ALIGN(ALIGN(q->ctl_stack_size, AMDGPU_GPU_PAGE_SIZE) +
			ALIGN(sizeof(struct v9_mqd), AMDGPU_GPU_PAGE_SIZE), PAGE_SIZE)) *
			NUM_XCC(node->xcc_mask),
			mqd_on_vram(node->adev) ? AMDGPU_GEM_DOMAIN_VRAM :
						  AMDGPU_GEM_DOMAIN_GTT,
			&(mqd_mem_obj->mem),
			&(mqd_mem_obj->gpu_addr),
			(void *)&(mqd_mem_obj->cpu_ptr), true);

		if (retval) {
			kfree(mqd_mem_obj);
			return NULL;
		}
	} else {
		retval = kfd_gtt_sa_allocate(node, sizeof(struct v9_mqd),
				&mqd_mem_obj);
		if (retval)
			return NULL;
	}

Annotation

Implementation Notes