]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
drm/amdgpu: rework reserved VMID handling
authorChristian König <christian.koenig@amd.com>
Fri, 25 Nov 2022 16:04:25 +0000 (17:04 +0100)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 14 Dec 2022 14:48:33 +0000 (09:48 -0500)
Instead of reserving a VMID for a single process allow that many
processes use the reserved ID. This allows for proper isolation
between the processes.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.h
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h

index 6949dfec75d533fc7ba1689b4b6742fe5ab06f55..fcb711a11a5b6bc4d4cff56289c97df89d1a70d4 100644 (file)
@@ -278,12 +278,13 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
 {
        struct amdgpu_device *adev = ring->adev;
        unsigned vmhub = ring->funcs->vmhub;
+       struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
        uint64_t fence_context = adev->fence_context + ring->idx;
        bool needs_flush = vm->use_cpu_for_update;
        uint64_t updates = amdgpu_vm_tlb_seq(vm);
        int r;
 
-       *id = vm->reserved_vmid[vmhub];
+       *id = id_mgr->reserved;
        if ((*id)->owner != vm->immediate.fence_context ||
            !amdgpu_vmid_compatible(*id, job) ||
            (*id)->flushed_updates < updates ||
@@ -462,31 +463,27 @@ int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev,
                               struct amdgpu_vm *vm,
                               unsigned vmhub)
 {
-       struct amdgpu_vmid_mgr *id_mgr;
-       struct amdgpu_vmid *idle;
-       int r = 0;
+       struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
 
-       id_mgr = &adev->vm_manager.id_mgr[vmhub];
        mutex_lock(&id_mgr->lock);
        if (vm->reserved_vmid[vmhub])
                goto unlock;
-       if (atomic_inc_return(&id_mgr->reserved_vmid_num) >
-           AMDGPU_VM_MAX_RESERVED_VMID) {
-               DRM_ERROR("Over limitation of reserved vmid\n");
-               atomic_dec(&id_mgr->reserved_vmid_num);
-               r = -EINVAL;
-               goto unlock;
+
+       ++id_mgr->reserved_use_count;
+       if (!id_mgr->reserved) {
+               struct amdgpu_vmid *id;
+
+               id = list_first_entry(&id_mgr->ids_lru, struct amdgpu_vmid,
+                                     list);
+               /* Remove from normal round robin handling */
+               list_del_init(&id->list);
+               id_mgr->reserved = id;
        }
-       /* Select the first entry VMID */
-       idle = list_first_entry(&id_mgr->ids_lru, struct amdgpu_vmid, list);
-       list_del_init(&idle->list);
-       vm->reserved_vmid[vmhub] = idle;
-       mutex_unlock(&id_mgr->lock);
+       vm->reserved_vmid[vmhub] = true;
 
-       return 0;
 unlock:
        mutex_unlock(&id_mgr->lock);
-       return r;
+       return 0;
 }
 
 void amdgpu_vmid_free_reserved(struct amdgpu_device *adev,
@@ -496,12 +493,12 @@ void amdgpu_vmid_free_reserved(struct amdgpu_device *adev,
        struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
 
        mutex_lock(&id_mgr->lock);
-       if (vm->reserved_vmid[vmhub]) {
-               list_add(&vm->reserved_vmid[vmhub]->list,
-                       &id_mgr->ids_lru);
-               vm->reserved_vmid[vmhub] = NULL;
-               atomic_dec(&id_mgr->reserved_vmid_num);
+       if (vm->reserved_vmid[vmhub] &&
+           !--id_mgr->reserved_use_count) {
+               /* give the reserved ID back to normal round robin */
+               list_add(&id_mgr->reserved->list, &id_mgr->ids_lru);
        }
+       vm->reserved_vmid[vmhub] = false;
        mutex_unlock(&id_mgr->lock);
 }
 
@@ -568,7 +565,7 @@ void amdgpu_vmid_mgr_init(struct amdgpu_device *adev)
 
                mutex_init(&id_mgr->lock);
                INIT_LIST_HEAD(&id_mgr->ids_lru);
-               atomic_set(&id_mgr->reserved_vmid_num, 0);
+               id_mgr->reserved_use_count = 0;
 
                /* manage only VMIDs not used by KFD */
                id_mgr->num_ids = adev->vm_manager.first_kfd_vmid;
index 57efe61dceedc3e23878f04f7ae1714345bf761a..d1cc09b45da4a1783edfef7d9f182e247f4f3031 100644 (file)
@@ -67,7 +67,8 @@ struct amdgpu_vmid_mgr {
        unsigned                num_ids;
        struct list_head        ids_lru;
        struct amdgpu_vmid      ids[AMDGPU_NUM_VMID];
-       atomic_t                reserved_vmid_num;
+       struct amdgpu_vmid      *reserved;
+       unsigned int            reserved_use_count;
 };
 
 int amdgpu_pasid_alloc(unsigned int bits);
index 6546e786bf008a7aad40f25c08223710562b71bb..094bb48073031e3582ed2e25f9be1907eb308719 100644 (file)
@@ -119,9 +119,6 @@ struct amdgpu_bo_vm;
 /* Reserve 2MB at top/bottom of address space for kernel use */
 #define AMDGPU_VA_RESERVED_SIZE                        (2ULL << 20)
 
-/* max vmids dedicated for process */
-#define AMDGPU_VM_MAX_RESERVED_VMID    1
-
 /* See vm_update_mode */
 #define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0)
 #define AMDGPU_VM_USE_CPU_FOR_COMPUTE (1 << 1)
@@ -298,8 +295,7 @@ struct amdgpu_vm {
        struct dma_fence        *last_unlocked;
 
        unsigned int            pasid;
-       /* dedicated to vm */
-       struct amdgpu_vmid      *reserved_vmid[AMDGPU_MAX_VMHUBS];
+       bool                    reserved_vmid[AMDGPU_MAX_VMHUBS];
 
        /* Flag to indicate if VM tables are updated by CPU or GPU (SDMA) */
        bool                                    use_cpu_for_update;