From 97beadbfc477940edf9184c6796c2a3c50e481bc Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 18 Feb 2019 07:37:03 -0500 Subject: [PATCH] drm/amdgpu: Convert pasid_idr to XArray Signed-off-by: Matthew Wilcox --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 64 ++++++++------------------ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 3 +- 2 files changed, 21 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 24c3c05e2fb7..2e8731605245 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -2736,12 +2736,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, amdgpu_bo_unreserve(vm->root.base.bo); if (pasid) { - unsigned long flags; - - spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); - r = idr_alloc(&adev->vm_manager.pasid_idr, vm, pasid, pasid + 1, - GFP_ATOMIC); - spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); + r = xa_insert_irq(&adev->vm_manager.vms, pasid, vm, GFP_KERNEL); if (r < 0) goto error_free_root; @@ -2832,16 +2827,9 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns goto unreserve_bo; if (pasid) { - unsigned long flags; - - spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); - r = idr_alloc(&adev->vm_manager.pasid_idr, vm, pasid, pasid + 1, - GFP_ATOMIC); - spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); - - if (r == -ENOSPC) + r = xa_insert_irq(&adev->vm_manager.vms, pasid, vm, GFP_KERNEL); + if (r < 0) goto unreserve_bo; - r = 0; } /* Check if PD needs to be reinitialized and do it before @@ -2851,7 +2839,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns vm->pte_support_ats = pte_support_ats; r = amdgpu_vm_clear_bo(adev, vm, vm->root.base.bo); if (r) - goto free_idr; + goto erase; } /* Update VM state */ @@ -2863,11 +2851,7 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns "CPU update of VM recommended only for large BAR system\n"); if (vm->pasid) { - unsigned long flags; - - spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); - idr_remove(&adev->vm_manager.pasid_idr, vm->pasid); - spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); + xa_erase_irq(&adev->vm_manager.vms, vm->pasid); /* Free the original amdgpu allocated pasid * Will be replaced with kfd allocated pasid @@ -2884,14 +2868,9 @@ int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm, uns goto unreserve_bo; -free_idr: - if (pasid) { - unsigned long flags; - - spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); - idr_remove(&adev->vm_manager.pasid_idr, pasid); - spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); - } +erase: + if (pasid) + xa_erase_irq(&adev->vm_manager.vms, pasid); unreserve_bo: amdgpu_bo_unreserve(vm->root.base.bo); return r; @@ -2910,9 +2889,9 @@ void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm) if (vm->pasid) { unsigned long flags; - spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); - idr_remove(&adev->vm_manager.pasid_idr, vm->pasid); - spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); + xa_lock_irqsave(&adev->vm_manager.vms, flags); + __xa_erase(&adev->vm_manager.vms, vm->pasid); + xa_unlock_irqrestore(&adev->vm_manager.vms, flags); } vm->pasid = 0; } @@ -2938,9 +2917,9 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) if (vm->pasid) { unsigned long flags; - spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); - idr_remove(&adev->vm_manager.pasid_idr, vm->pasid); - spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); + xa_lock_irqsave(&adev->vm_manager.vms, flags); + __xa_erase(&adev->vm_manager.vms, vm->pasid); + xa_unlock_irqrestore(&adev->vm_manager.vms, flags); } drm_sched_entity_destroy(&vm->entity); @@ -3018,8 +2997,8 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev) adev->vm_manager.vm_update_mode = 0; #endif - idr_init(&adev->vm_manager.pasid_idr); - spin_lock_init(&adev->vm_manager.pasid_lock); + xa_init_flags(&adev->vm_manager.vms, + XA_FLAGS_ALLOC | XA_FLAGS_LOCK_IRQ); adev->vm_manager.xgmi_map_counter = 0; mutex_init(&adev->vm_manager.lock_pstate); @@ -3034,8 +3013,7 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev) */ void amdgpu_vm_manager_fini(struct amdgpu_device *adev) { - WARN_ON(!idr_is_empty(&adev->vm_manager.pasid_idr)); - idr_destroy(&adev->vm_manager.pasid_idr); + WARN_ON(!xa_empty(&adev->vm_manager.vms)); amdgpu_vmid_mgr_fini(adev); } @@ -3087,13 +3065,11 @@ void amdgpu_vm_get_task_info(struct amdgpu_device *adev, unsigned int pasid, struct amdgpu_vm *vm; unsigned long flags; - spin_lock_irqsave(&adev->vm_manager.pasid_lock, flags); - - vm = idr_find(&adev->vm_manager.pasid_idr, pasid); + xa_lock_irqsave(&adev->vm_manager.vms, flags); + vm = xa_load(&adev->vm_manager.vms, pasid); if (vm) *task_info = vm->task_info; - - spin_unlock_irqrestore(&adev->vm_manager.pasid_lock, flags); + xa_unlock_irqrestore(&adev->vm_manager.vms, flags); } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 489a162ca620..9977ceb6d831 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -324,8 +324,7 @@ struct amdgpu_vm_manager { /* PASID to VM mapping, will be used in interrupt context to * look up VM of a page fault */ - struct idr pasid_idr; - spinlock_t pasid_lock; + struct xarray vms; /* counter of mapped memory through xgmi */ uint32_t xgmi_map_counter; -- 2.51.0