mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-16 09:13:55 +08:00
drm/amdkfd: Allocate doorbells only when needed
Only allocate doorbells when the first queue is created on a GPU or the doorbells need to be mapped into CPU or GPU virtual address space. This avoids allocating doorbells unnecessarily and can allow more processes to use KFD on multi-GPU systems. Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Reviewed-by: Kent Russell <kent.Russell@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
8243df4778
commit
16f0013157
@ -327,6 +327,12 @@ static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
|
|||||||
goto err_bind_process;
|
goto err_bind_process;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pdd->doorbell_index &&
|
||||||
|
kfd_alloc_process_doorbells(dev, &pdd->doorbell_index) < 0) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_alloc_doorbells;
|
||||||
|
}
|
||||||
|
|
||||||
/* Starting with GFX11, wptr BOs must be mapped to GART for MES to determine work
|
/* Starting with GFX11, wptr BOs must be mapped to GART for MES to determine work
|
||||||
* on unmapped queues for usermode queue oversubscription (no aggregated doorbell)
|
* on unmapped queues for usermode queue oversubscription (no aggregated doorbell)
|
||||||
*/
|
*/
|
||||||
@ -404,6 +410,7 @@ err_create_queue:
|
|||||||
if (wptr_bo)
|
if (wptr_bo)
|
||||||
amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
|
amdgpu_amdkfd_free_gtt_mem(dev->adev, wptr_bo);
|
||||||
err_wptr_map_gart:
|
err_wptr_map_gart:
|
||||||
|
err_alloc_doorbells:
|
||||||
err_bind_process:
|
err_bind_process:
|
||||||
err_pdd:
|
err_pdd:
|
||||||
mutex_unlock(&p->mutex);
|
mutex_unlock(&p->mutex);
|
||||||
@ -1092,6 +1099,10 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
|
|||||||
goto err_unlock;
|
goto err_unlock;
|
||||||
}
|
}
|
||||||
offset = kfd_get_process_doorbells(pdd);
|
offset = kfd_get_process_doorbells(pdd);
|
||||||
|
if (!offset) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_unlock;
|
||||||
|
}
|
||||||
} else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
|
} else if (flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
|
||||||
if (args->size != PAGE_SIZE) {
|
if (args->size != PAGE_SIZE) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
@ -2173,6 +2184,8 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
offset = kfd_get_process_doorbells(pdd);
|
offset = kfd_get_process_doorbells(pdd);
|
||||||
|
if (!offset)
|
||||||
|
return -ENOMEM;
|
||||||
} else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
|
} else if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP) {
|
||||||
/* MMIO BOs need remapped bus address */
|
/* MMIO BOs need remapped bus address */
|
||||||
if (bo_bucket->size != PAGE_SIZE) {
|
if (bo_bucket->size != PAGE_SIZE) {
|
||||||
|
@ -157,6 +157,8 @@ int kfd_doorbell_mmap(struct kfd_dev *dev, struct kfd_process *process,
|
|||||||
|
|
||||||
/* Calculate physical address of doorbell */
|
/* Calculate physical address of doorbell */
|
||||||
address = kfd_get_process_doorbells(pdd);
|
address = kfd_get_process_doorbells(pdd);
|
||||||
|
if (!address)
|
||||||
|
return -ENOMEM;
|
||||||
vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
|
vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
|
||||||
VM_DONTDUMP | VM_PFNMAP;
|
VM_DONTDUMP | VM_PFNMAP;
|
||||||
|
|
||||||
@ -275,6 +277,13 @@ uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
|
|||||||
|
|
||||||
phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
|
phys_addr_t kfd_get_process_doorbells(struct kfd_process_device *pdd)
|
||||||
{
|
{
|
||||||
|
if (!pdd->doorbell_index) {
|
||||||
|
int r = kfd_alloc_process_doorbells(pdd->dev,
|
||||||
|
&pdd->doorbell_index);
|
||||||
|
if (r)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return pdd->dev->doorbell_base +
|
return pdd->dev->doorbell_base +
|
||||||
pdd->doorbell_index * kfd_doorbell_process_slice(pdd->dev);
|
pdd->doorbell_index * kfd_doorbell_process_slice(pdd->dev);
|
||||||
}
|
}
|
||||||
|
@ -1499,11 +1499,6 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_dev *dev,
|
|||||||
if (!pdd)
|
if (!pdd)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (kfd_alloc_process_doorbells(dev, &pdd->doorbell_index) < 0) {
|
|
||||||
pr_err("Failed to alloc doorbell for pdd\n");
|
|
||||||
goto err_free_pdd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (init_doorbell_bitmap(&pdd->qpd, dev)) {
|
if (init_doorbell_bitmap(&pdd->qpd, dev)) {
|
||||||
pr_err("Failed to init doorbell for process\n");
|
pr_err("Failed to init doorbell for process\n");
|
||||||
goto err_free_pdd;
|
goto err_free_pdd;
|
||||||
|
Loading…
Reference in New Issue
Block a user