Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: revert "rework reserved VMID handling" v2

This reverts commit e44a0fe630c58b0a87d8281f5c1077a3479e5fce.

Initially we used VMID reservation to enforce isolation between
processes. That has now been replaced by proper fence handling.

Both OpenGL, RADV and ROCm developers requested a way to reserve a VMID
for SPM, so restore that approach by reverting back to only allowing a
single process to use the reserved VMID.

Only compile tested for now.

v2: use -ENOENT instead of -EINVAL if VMID is not available

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Christian König and committed by
Alex Deucher
90e09ea4 66f3883d

+50 -41
+40 -21
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
··· 275 275 { 276 276 struct amdgpu_device *adev = ring->adev; 277 277 unsigned vmhub = ring->vm_hub; 278 - struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub]; 279 278 uint64_t fence_context = adev->fence_context + ring->idx; 280 279 bool needs_flush = vm->use_cpu_for_update; 281 280 uint64_t updates = amdgpu_vm_tlb_seq(vm); 282 281 int r; 283 282 284 - *id = id_mgr->reserved; 283 + *id = vm->reserved_vmid[vmhub]; 285 284 if ((*id)->owner != vm->immediate.fence_context || 286 285 !amdgpu_vmid_compatible(*id, job) || 287 286 (*id)->flushed_updates < updates || ··· 473 474 return vm->reserved_vmid[vmhub]; 474 475 } 475 476 476 - int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev, 477 + /* 478 + * amdgpu_vmid_alloc_reserved - reserve a specific VMID for this vm 479 + * @adev: amdgpu device structure 480 + * @vm: the VM to reserve an ID for 481 + * @vmhub: the VMHUB which should be used 482 + * 483 + * Mostly used to have a reserved VMID for debugging and SPM. 484 + * 485 + * Returns: 0 for success, -ENOENT if an ID is already reserved. 486 + */ 487 + int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev, struct amdgpu_vm *vm, 477 488 unsigned vmhub) 478 489 { 479 490 struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub]; 491 + struct amdgpu_vmid *id; 492 + int r = 0; 480 493 481 494 mutex_lock(&id_mgr->lock); 482 - 483 - ++id_mgr->reserved_use_count; 484 - if (!id_mgr->reserved) { 485 - struct amdgpu_vmid *id; 486 - 487 - id = list_first_entry(&id_mgr->ids_lru, struct amdgpu_vmid, 488 - list); 489 - /* Remove from normal round robin handling */ 490 - list_del_init(&id->list); 491 - id_mgr->reserved = id; 495 + if (vm->reserved_vmid[vmhub]) 496 + goto unlock; 497 + if (id_mgr->reserved_vmid) { 498 + r = -ENOENT; 499 + goto unlock; 492 500 } 493 - 501 + /* Remove from normal round robin handling */ 502 + id = list_first_entry(&id_mgr->ids_lru, struct amdgpu_vmid, list); 503 + list_del_init(&id->list); 504 + vm->reserved_vmid[vmhub] = id; 505 + id_mgr->reserved_vmid = true; 494 506 mutex_unlock(&id_mgr->lock); 507 + 495 508 return 0; 509 + unlock: 510 + mutex_unlock(&id_mgr->lock); 511 + return r; 496 512 } 497 513 498 - void amdgpu_vmid_free_reserved(struct amdgpu_device *adev, 514 + /* 515 + * amdgpu_vmid_free_reserved - free up a reserved VMID again 516 + * @adev: amdgpu device structure 517 + * @vm: the VM with the reserved ID 518 + * @vmhub: the VMHUB which should be used 519 + */ 520 + void amdgpu_vmid_free_reserved(struct amdgpu_device *adev, struct amdgpu_vm *vm, 499 521 unsigned vmhub) 500 522 { 501 523 struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub]; 502 524 503 525 mutex_lock(&id_mgr->lock); 504 - if (!--id_mgr->reserved_use_count) { 505 - /* give the reserved ID back to normal round robin */ 506 - list_add(&id_mgr->reserved->list, &id_mgr->ids_lru); 507 - id_mgr->reserved = NULL; 526 + if (vm->reserved_vmid[vmhub]) { 527 + list_add(&vm->reserved_vmid[vmhub]->list, 528 + &id_mgr->ids_lru); 529 + vm->reserved_vmid[vmhub] = NULL; 530 + id_mgr->reserved_vmid = false; 508 531 } 509 - 510 532 mutex_unlock(&id_mgr->lock); 511 533 } 512 534 ··· 594 574 595 575 mutex_init(&id_mgr->lock); 596 576 INIT_LIST_HEAD(&id_mgr->ids_lru); 597 - id_mgr->reserved_use_count = 0; 598 577 599 578 /* for GC <10, SDMA uses MMHUB so use first_kfd_vmid for both GC and MM */ 600 579 if (amdgpu_ip_version(adev, GC_HWIP, 0) < IP_VERSION(10, 0, 0))
+5 -6
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
··· 67 67 unsigned num_ids; 68 68 struct list_head ids_lru; 69 69 struct amdgpu_vmid ids[AMDGPU_NUM_VMID]; 70 - struct amdgpu_vmid *reserved; 71 - unsigned int reserved_use_count; 70 + bool reserved_vmid; 72 71 }; 73 72 74 73 int amdgpu_pasid_alloc(unsigned int bits); ··· 78 79 bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev, 79 80 struct amdgpu_vmid *id); 80 81 bool amdgpu_vmid_uses_reserved(struct amdgpu_vm *vm, unsigned int vmhub); 81 - int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev, 82 - unsigned vmhub); 83 - void amdgpu_vmid_free_reserved(struct amdgpu_device *adev, 84 - unsigned vmhub); 82 + int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev, struct amdgpu_vm *vm, 83 + unsigned vmhub); 84 + void amdgpu_vmid_free_reserved(struct amdgpu_device *adev, struct amdgpu_vm *vm, 85 + unsigned vmhub); 85 86 int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring, 86 87 struct amdgpu_job *job, struct dma_fence **fence); 87 88 void amdgpu_vmid_reset(struct amdgpu_device *adev, unsigned vmhub,
+4 -13
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
··· 2790 2790 dma_fence_put(vm->last_update); 2791 2791 2792 2792 for (i = 0; i < AMDGPU_MAX_VMHUBS; i++) { 2793 - if (vm->reserved_vmid[i]) { 2794 - amdgpu_vmid_free_reserved(adev, i); 2795 - vm->reserved_vmid[i] = false; 2796 - } 2793 + amdgpu_vmid_free_reserved(adev, vm, i); 2797 2794 } 2798 2795 2799 2796 ttm_lru_bulk_move_fini(&adev->mman.bdev, &vm->lru_bulk_move); ··· 2886 2889 union drm_amdgpu_vm *args = data; 2887 2890 struct amdgpu_device *adev = drm_to_adev(dev); 2888 2891 struct amdgpu_fpriv *fpriv = filp->driver_priv; 2892 + struct amdgpu_vm *vm = &fpriv->vm; 2889 2893 2890 2894 /* No valid flags defined yet */ 2891 2895 if (args->in.flags) ··· 2895 2897 switch (args->in.op) { 2896 2898 case AMDGPU_VM_OP_RESERVE_VMID: 2897 2899 /* We only have requirement to reserve vmid from gfxhub */ 2898 - if (!fpriv->vm.reserved_vmid[AMDGPU_GFXHUB(0)]) { 2899 - amdgpu_vmid_alloc_reserved(adev, AMDGPU_GFXHUB(0)); 2900 - fpriv->vm.reserved_vmid[AMDGPU_GFXHUB(0)] = true; 2901 - } 2902 - 2900 + amdgpu_vmid_alloc_reserved(adev, vm, AMDGPU_GFXHUB(0)); 2903 2901 break; 2904 2902 case AMDGPU_VM_OP_UNRESERVE_VMID: 2905 - if (fpriv->vm.reserved_vmid[AMDGPU_GFXHUB(0)]) { 2906 - amdgpu_vmid_free_reserved(adev, AMDGPU_GFXHUB(0)); 2907 - fpriv->vm.reserved_vmid[AMDGPU_GFXHUB(0)] = false; 2908 - } 2903 + amdgpu_vmid_free_reserved(adev, vm, AMDGPU_GFXHUB(0)); 2909 2904 break; 2910 2905 default: 2911 2906 return -EINVAL;
+1 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h
··· 415 415 struct dma_fence *last_unlocked; 416 416 417 417 unsigned int pasid; 418 - bool reserved_vmid[AMDGPU_MAX_VMHUBS]; 418 + struct amdgpu_vmid *reserved_vmid[AMDGPU_MAX_VMHUBS]; 419 419 420 420 /* Flag to indicate if VM tables are updated by CPU or GPU (SDMA) */ 421 421 bool use_cpu_for_update;