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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
Extension
.c
Size
8980 bytes
Lines
304
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 (i >= range_start && i <= range_end) {
			__set_bit(i, qpd->doorbell_bitmap);
			__set_bit(i + KFD_QUEUE_DOORBELL_MIRROR_OFFSET,
				  qpd->doorbell_bitmap);
		}
	}

	return 0;
}

phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
{
	struct amdgpu_device *adev = pdd->dev->adev;
	uint32_t first_db_index;

	if (!pdd->qpd.proc_doorbells) {
		if (kfd_alloc_process_doorbells(pdd->dev->kfd, pdd))
			/* phys_addr_t 0 is error */
			return 0;
	}

	first_db_index = amdgpu_doorbell_index_on_bar(adev,
						      pdd->qpd.proc_doorbells,
						      0,
						      pdd->dev->kfd->device_info.doorbell_size);
	return adev->doorbell.base + first_db_index * sizeof(uint32_t);
}

int kfd_alloc_process_doorbells(struct kfd_dev *kfd, struct kfd_process_device *pdd)
{
	int r;
	struct qcm_process_device *qpd = &pdd->qpd;

	/* Allocate bitmap for dynamic doorbell allocation */
	qpd->doorbell_bitmap = bitmap_zalloc(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
					     GFP_KERNEL);
	if (!qpd->doorbell_bitmap) {
		DRM_ERROR("Failed to allocate process doorbell bitmap\n");
		return -ENOMEM;
	}

	r = init_doorbell_bitmap(&pdd->qpd, kfd);
	if (r) {
		DRM_ERROR("Failed to initialize process doorbells\n");
		r = -ENOMEM;
		goto err;
	}

	/* Allocate doorbells for this process */
	r = amdgpu_bo_create_kernel(kfd->adev,
				    kfd_doorbell_process_slice(kfd),
				    PAGE_SIZE,
				    AMDGPU_GEM_DOMAIN_DOORBELL,
				    &qpd->proc_doorbells,
				    NULL,
				    NULL);
	if (r) {
		DRM_ERROR("Failed to allocate process doorbells\n");
		goto err;
	}
	return 0;

err:
	bitmap_free(qpd->doorbell_bitmap);
	qpd->doorbell_bitmap = NULL;
	return r;
}

void kfd_free_process_doorbells(struct kfd_dev *kfd, struct kfd_process_device *pdd)
{
	struct qcm_process_device *qpd = &pdd->qpd;

	if (qpd->doorbell_bitmap) {
		bitmap_free(qpd->doorbell_bitmap);
		qpd->doorbell_bitmap = NULL;
	}

	amdgpu_bo_free_kernel(&qpd->proc_doorbells, NULL, NULL);
}

Annotation

Implementation Notes