diff options
Diffstat (limited to 'drivers/gpu/drm')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 19 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 88 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 3 |
4 files changed, 55 insertions, 58 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 43b48eb6cf6e..3d4c2abfcfe8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
| @@ -925,18 +925,20 @@ struct amdgpu_vm { | |||
| 925 | spinlock_t freed_lock; | 925 | spinlock_t freed_lock; |
| 926 | }; | 926 | }; |
| 927 | 927 | ||
| 928 | struct amdgpu_vm_manager_id { | ||
| 929 | struct list_head list; | ||
| 930 | struct fence *active; | ||
| 931 | atomic_long_t owner; | ||
| 932 | }; | ||
| 933 | |||
| 928 | struct amdgpu_vm_manager { | 934 | struct amdgpu_vm_manager { |
| 929 | /* protecting IDs */ | 935 | /* Handling of VMIDs */ |
| 930 | struct mutex lock; | 936 | struct mutex lock; |
| 931 | 937 | unsigned num_ids; | |
| 932 | struct { | 938 | struct list_head ids_lru; |
| 933 | struct fence *active; | 939 | struct amdgpu_vm_manager_id ids[AMDGPU_NUM_VM]; |
| 934 | atomic_long_t owner; | ||
| 935 | } ids[AMDGPU_NUM_VM]; | ||
| 936 | 940 | ||
| 937 | uint32_t max_pfn; | 941 | uint32_t max_pfn; |
| 938 | /* number of VMIDs */ | ||
| 939 | unsigned nvm; | ||
| 940 | /* vram base address for page table entry */ | 942 | /* vram base address for page table entry */ |
| 941 | u64 vram_base_offset; | 943 | u64 vram_base_offset; |
| 942 | /* is vm enabled? */ | 944 | /* is vm enabled? */ |
| @@ -946,6 +948,7 @@ struct amdgpu_vm_manager { | |||
| 946 | struct amdgpu_ring *vm_pte_funcs_ring; | 948 | struct amdgpu_ring *vm_pte_funcs_ring; |
| 947 | }; | 949 | }; |
| 948 | 950 | ||
| 951 | void amdgpu_vm_manager_init(struct amdgpu_device *adev); | ||
| 949 | void amdgpu_vm_manager_fini(struct amdgpu_device *adev); | 952 | void amdgpu_vm_manager_fini(struct amdgpu_device *adev); |
| 950 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm); | 953 | int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm); |
| 951 | void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); | 954 | void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm); |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index d4718e1cd050..2dd73ca57221 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
| @@ -161,79 +161,52 @@ void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev, | |||
| 161 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, | 161 | int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring, |
| 162 | struct amdgpu_sync *sync, struct fence *fence) | 162 | struct amdgpu_sync *sync, struct fence *fence) |
| 163 | { | 163 | { |
| 164 | struct fence *best[AMDGPU_MAX_RINGS] = {}; | ||
| 165 | struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; | 164 | struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx]; |
| 166 | struct amdgpu_device *adev = ring->adev; | 165 | struct amdgpu_device *adev = ring->adev; |
| 167 | 166 | struct amdgpu_vm_manager_id *id; | |
| 168 | unsigned choices[2] = {}; | 167 | int r; |
| 169 | unsigned i; | ||
| 170 | 168 | ||
| 171 | mutex_lock(&adev->vm_manager.lock); | 169 | mutex_lock(&adev->vm_manager.lock); |
| 172 | 170 | ||
| 173 | /* check if the id is still valid */ | 171 | /* check if the id is still valid */ |
| 174 | if (vm_id->id) { | 172 | if (vm_id->id) { |
| 175 | unsigned id = vm_id->id; | ||
| 176 | long owner; | 173 | long owner; |
| 177 | 174 | ||
| 178 | owner = atomic_long_read(&adev->vm_manager.ids[id].owner); | 175 | id = &adev->vm_manager.ids[vm_id->id]; |
| 176 | owner = atomic_long_read(&id->owner); | ||
| 179 | if (owner == (long)vm) { | 177 | if (owner == (long)vm) { |
| 178 | list_move_tail(&id->list, &adev->vm_manager.ids_lru); | ||
| 180 | trace_amdgpu_vm_grab_id(vm, vm_id->id, ring->idx); | 179 | trace_amdgpu_vm_grab_id(vm, vm_id->id, ring->idx); |
| 181 | fence_put(adev->vm_manager.ids[id].active); | ||
| 182 | adev->vm_manager.ids[id].active = fence_get(fence); | ||
| 183 | mutex_unlock(&adev->vm_manager.lock); | ||
| 184 | return 0; | ||
| 185 | } | ||
| 186 | } | ||
| 187 | 180 | ||
| 188 | /* we definately need to flush */ | 181 | fence_put(id->active); |
| 189 | vm_id->pd_gpu_addr = ~0ll; | 182 | id->active = fence_get(fence); |
| 190 | 183 | ||
| 191 | /* skip over VMID 0, since it is the system VM */ | ||
| 192 | for (i = 1; i < adev->vm_manager.nvm; ++i) { | ||
| 193 | struct fence *fence = adev->vm_manager.ids[i].active; | ||
| 194 | struct amdgpu_ring *fring; | ||
| 195 | |||
| 196 | if (fence == NULL) { | ||
| 197 | /* found a free one */ | ||
| 198 | vm_id->id = i; | ||
| 199 | trace_amdgpu_vm_grab_id(vm, i, ring->idx); | ||
| 200 | mutex_unlock(&adev->vm_manager.lock); | 184 | mutex_unlock(&adev->vm_manager.lock); |
| 201 | return 0; | 185 | return 0; |
| 202 | } | 186 | } |
| 203 | |||
| 204 | fring = amdgpu_ring_from_fence(fence); | ||
| 205 | if (best[fring->idx] == NULL || | ||
| 206 | fence_is_later(best[fring->idx], fence)) { | ||
| 207 | best[fring->idx] = fence; | ||
| 208 | choices[fring == ring ? 0 : 1] = i; | ||
| 209 | } | ||
| 210 | } | 187 | } |
| 211 | 188 | ||
| 212 | for (i = 0; i < 2; ++i) { | 189 | /* we definately need to flush */ |
| 213 | struct fence *active; | 190 | vm_id->pd_gpu_addr = ~0ll; |
| 214 | int r; | ||
| 215 | |||
| 216 | if (!choices[i]) | ||
| 217 | continue; | ||
| 218 | 191 | ||
| 219 | vm_id->id = choices[i]; | 192 | id = list_first_entry(&adev->vm_manager.ids_lru, |
| 220 | active = adev->vm_manager.ids[vm_id->id].active; | 193 | struct amdgpu_vm_manager_id, |
| 221 | r = amdgpu_sync_fence(ring->adev, sync, active); | 194 | list); |
| 195 | list_move_tail(&id->list, &adev->vm_manager.ids_lru); | ||
| 196 | atomic_long_set(&id->owner, (long)vm); | ||
| 222 | 197 | ||
| 223 | trace_amdgpu_vm_grab_id(vm, choices[i], ring->idx); | 198 | vm_id->id = id - adev->vm_manager.ids; |
| 224 | atomic_long_set(&adev->vm_manager.ids[vm_id->id].owner, (long)vm); | 199 | trace_amdgpu_vm_grab_id(vm, vm_id->id, ring->idx); |
| 225 | 200 | ||
| 226 | fence_put(adev->vm_manager.ids[vm_id->id].active); | 201 | r = amdgpu_sync_fence(ring->adev, sync, id->active); |
| 227 | adev->vm_manager.ids[vm_id->id].active = fence_get(fence); | ||
| 228 | 202 | ||
| 229 | mutex_unlock(&adev->vm_manager.lock); | 203 | if (!r) { |
| 230 | return r; | 204 | fence_put(id->active); |
| 205 | id->active = fence_get(fence); | ||
| 231 | } | 206 | } |
| 232 | 207 | ||
| 233 | /* should never happen */ | ||
| 234 | BUG(); | ||
| 235 | mutex_unlock(&adev->vm_manager.lock); | 208 | mutex_unlock(&adev->vm_manager.lock); |
| 236 | return -EINVAL; | 209 | return r; |
| 237 | } | 210 | } |
| 238 | 211 | ||
| 239 | /** | 212 | /** |
| @@ -1359,6 +1332,25 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
| 1359 | } | 1332 | } |
| 1360 | 1333 | ||
| 1361 | /** | 1334 | /** |
| 1335 | * amdgpu_vm_manager_init - init the VM manager | ||
| 1336 | * | ||
| 1337 | * @adev: amdgpu_device pointer | ||
| 1338 | * | ||
| 1339 | * Initialize the VM manager structures | ||
| 1340 | */ | ||
| 1341 | void amdgpu_vm_manager_init(struct amdgpu_device *adev) | ||
| 1342 | { | ||
| 1343 | unsigned i; | ||
| 1344 | |||
| 1345 | INIT_LIST_HEAD(&adev->vm_manager.ids_lru); | ||
| 1346 | |||
| 1347 | /* skip over VMID 0, since it is the system VM */ | ||
| 1348 | for (i = 1; i < adev->vm_manager.num_ids; ++i) | ||
| 1349 | list_add_tail(&adev->vm_manager.ids[i].list, | ||
| 1350 | &adev->vm_manager.ids_lru); | ||
| 1351 | } | ||
| 1352 | |||
| 1353 | /** | ||
| 1362 | * amdgpu_vm_manager_fini - cleanup VM manager | 1354 | * amdgpu_vm_manager_fini - cleanup VM manager |
| 1363 | * | 1355 | * |
| 1364 | * @adev: amdgpu_device pointer | 1356 | * @adev: amdgpu_device pointer |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 8aa2991ab379..cceffe2288d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | |||
| @@ -694,7 +694,8 @@ static int gmc_v7_0_vm_init(struct amdgpu_device *adev) | |||
| 694 | * amdgpu graphics/compute will use VMIDs 1-7 | 694 | * amdgpu graphics/compute will use VMIDs 1-7 |
| 695 | * amdkfd will use VMIDs 8-15 | 695 | * amdkfd will use VMIDs 8-15 |
| 696 | */ | 696 | */ |
| 697 | adev->vm_manager.nvm = AMDGPU_NUM_OF_VMIDS; | 697 | adev->vm_manager.num_ids = AMDGPU_NUM_OF_VMIDS; |
| 698 | amdgpu_vm_manager_init(adev); | ||
| 698 | 699 | ||
| 699 | /* base offset of vram pages */ | 700 | /* base offset of vram pages */ |
| 700 | if (adev->flags & AMD_IS_APU) { | 701 | if (adev->flags & AMD_IS_APU) { |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 3efd45546241..7011f8b2971a 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | |||
| @@ -774,7 +774,8 @@ static int gmc_v8_0_vm_init(struct amdgpu_device *adev) | |||
| 774 | * amdgpu graphics/compute will use VMIDs 1-7 | 774 | * amdgpu graphics/compute will use VMIDs 1-7 |
| 775 | * amdkfd will use VMIDs 8-15 | 775 | * amdkfd will use VMIDs 8-15 |
| 776 | */ | 776 | */ |
| 777 | adev->vm_manager.nvm = AMDGPU_NUM_OF_VMIDS; | 777 | adev->vm_manager.num_ids = AMDGPU_NUM_OF_VMIDS; |
| 778 | amdgpu_vm_manager_init(adev); | ||
| 778 | 779 | ||
| 779 | /* base offset of vram pages */ | 780 | /* base offset of vram pages */ |
| 780 | if (adev->flags & AMD_IS_APU) { | 781 | if (adev->flags & AMD_IS_APU) { |
