mirror of https://gitee.com/openkylin/linux.git
drm/amdgpu: use a global LRU list for VMIDs
With the scheduler enabled managing per ring LRUs don't make much sense any more. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com> Acked-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
94dd0a4ae0
commit
a9a78b329a
|
@ -925,18 +925,20 @@ struct amdgpu_vm {
|
||||||
spinlock_t freed_lock;
|
spinlock_t freed_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct amdgpu_vm_manager {
|
struct amdgpu_vm_manager_id {
|
||||||
/* protecting IDs */
|
struct list_head list;
|
||||||
struct mutex lock;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct fence *active;
|
struct fence *active;
|
||||||
atomic_long_t owner;
|
atomic_long_t owner;
|
||||||
} ids[AMDGPU_NUM_VM];
|
};
|
||||||
|
|
||||||
|
struct amdgpu_vm_manager {
|
||||||
|
/* Handling of VMIDs */
|
||||||
|
struct mutex lock;
|
||||||
|
unsigned num_ids;
|
||||||
|
struct list_head ids_lru;
|
||||||
|
struct amdgpu_vm_manager_id ids[AMDGPU_NUM_VM];
|
||||||
|
|
||||||
uint32_t max_pfn;
|
uint32_t max_pfn;
|
||||||
/* number of VMIDs */
|
|
||||||
unsigned nvm;
|
|
||||||
/* vram base address for page table entry */
|
/* vram base address for page table entry */
|
||||||
u64 vram_base_offset;
|
u64 vram_base_offset;
|
||||||
/* is vm enabled? */
|
/* is vm enabled? */
|
||||||
|
@ -946,6 +948,7 @@ struct amdgpu_vm_manager {
|
||||||
struct amdgpu_ring *vm_pte_funcs_ring;
|
struct amdgpu_ring *vm_pte_funcs_ring;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void amdgpu_vm_manager_init(struct amdgpu_device *adev);
|
||||||
void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
|
void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
|
||||||
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
||||||
void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
|
||||||
|
|
|
@ -161,25 +161,26 @@ void amdgpu_vm_move_pt_bos_in_lru(struct amdgpu_device *adev,
|
||||||
int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||||
struct amdgpu_sync *sync, struct fence *fence)
|
struct amdgpu_sync *sync, struct fence *fence)
|
||||||
{
|
{
|
||||||
struct fence *best[AMDGPU_MAX_RINGS] = {};
|
|
||||||
struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx];
|
struct amdgpu_vm_id *vm_id = &vm->ids[ring->idx];
|
||||||
struct amdgpu_device *adev = ring->adev;
|
struct amdgpu_device *adev = ring->adev;
|
||||||
|
struct amdgpu_vm_manager_id *id;
|
||||||
unsigned choices[2] = {};
|
int r;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
mutex_lock(&adev->vm_manager.lock);
|
mutex_lock(&adev->vm_manager.lock);
|
||||||
|
|
||||||
/* check if the id is still valid */
|
/* check if the id is still valid */
|
||||||
if (vm_id->id) {
|
if (vm_id->id) {
|
||||||
unsigned id = vm_id->id;
|
|
||||||
long owner;
|
long owner;
|
||||||
|
|
||||||
owner = atomic_long_read(&adev->vm_manager.ids[id].owner);
|
id = &adev->vm_manager.ids[vm_id->id];
|
||||||
|
owner = atomic_long_read(&id->owner);
|
||||||
if (owner == (long)vm) {
|
if (owner == (long)vm) {
|
||||||
|
list_move_tail(&id->list, &adev->vm_manager.ids_lru);
|
||||||
trace_amdgpu_vm_grab_id(vm, vm_id->id, ring->idx);
|
trace_amdgpu_vm_grab_id(vm, vm_id->id, ring->idx);
|
||||||
fence_put(adev->vm_manager.ids[id].active);
|
|
||||||
adev->vm_manager.ids[id].active = fence_get(fence);
|
fence_put(id->active);
|
||||||
|
id->active = fence_get(fence);
|
||||||
|
|
||||||
mutex_unlock(&adev->vm_manager.lock);
|
mutex_unlock(&adev->vm_manager.lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -188,54 +189,26 @@ int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||||
/* we definately need to flush */
|
/* we definately need to flush */
|
||||||
vm_id->pd_gpu_addr = ~0ll;
|
vm_id->pd_gpu_addr = ~0ll;
|
||||||
|
|
||||||
/* skip over VMID 0, since it is the system VM */
|
id = list_first_entry(&adev->vm_manager.ids_lru,
|
||||||
for (i = 1; i < adev->vm_manager.nvm; ++i) {
|
struct amdgpu_vm_manager_id,
|
||||||
struct fence *fence = adev->vm_manager.ids[i].active;
|
list);
|
||||||
struct amdgpu_ring *fring;
|
list_move_tail(&id->list, &adev->vm_manager.ids_lru);
|
||||||
|
atomic_long_set(&id->owner, (long)vm);
|
||||||
|
|
||||||
if (fence == NULL) {
|
vm_id->id = id - adev->vm_manager.ids;
|
||||||
/* found a free one */
|
trace_amdgpu_vm_grab_id(vm, vm_id->id, ring->idx);
|
||||||
vm_id->id = i;
|
|
||||||
trace_amdgpu_vm_grab_id(vm, i, ring->idx);
|
r = amdgpu_sync_fence(ring->adev, sync, id->active);
|
||||||
mutex_unlock(&adev->vm_manager.lock);
|
|
||||||
return 0;
|
if (!r) {
|
||||||
|
fence_put(id->active);
|
||||||
|
id->active = fence_get(fence);
|
||||||
}
|
}
|
||||||
|
|
||||||
fring = amdgpu_ring_from_fence(fence);
|
|
||||||
if (best[fring->idx] == NULL ||
|
|
||||||
fence_is_later(best[fring->idx], fence)) {
|
|
||||||
best[fring->idx] = fence;
|
|
||||||
choices[fring == ring ? 0 : 1] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 2; ++i) {
|
|
||||||
struct fence *active;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (!choices[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
vm_id->id = choices[i];
|
|
||||||
active = adev->vm_manager.ids[vm_id->id].active;
|
|
||||||
r = amdgpu_sync_fence(ring->adev, sync, active);
|
|
||||||
|
|
||||||
trace_amdgpu_vm_grab_id(vm, choices[i], ring->idx);
|
|
||||||
atomic_long_set(&adev->vm_manager.ids[vm_id->id].owner, (long)vm);
|
|
||||||
|
|
||||||
fence_put(adev->vm_manager.ids[vm_id->id].active);
|
|
||||||
adev->vm_manager.ids[vm_id->id].active = fence_get(fence);
|
|
||||||
|
|
||||||
mutex_unlock(&adev->vm_manager.lock);
|
mutex_unlock(&adev->vm_manager.lock);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* should never happen */
|
|
||||||
BUG();
|
|
||||||
mutex_unlock(&adev->vm_manager.lock);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_vm_flush - hardware flush the vm
|
* amdgpu_vm_flush - hardware flush the vm
|
||||||
*
|
*
|
||||||
|
@ -1358,6 +1331,25 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* amdgpu_vm_manager_init - init the VM manager
|
||||||
|
*
|
||||||
|
* @adev: amdgpu_device pointer
|
||||||
|
*
|
||||||
|
* Initialize the VM manager structures
|
||||||
|
*/
|
||||||
|
void amdgpu_vm_manager_init(struct amdgpu_device *adev)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&adev->vm_manager.ids_lru);
|
||||||
|
|
||||||
|
/* skip over VMID 0, since it is the system VM */
|
||||||
|
for (i = 1; i < adev->vm_manager.num_ids; ++i)
|
||||||
|
list_add_tail(&adev->vm_manager.ids[i].list,
|
||||||
|
&adev->vm_manager.ids_lru);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* amdgpu_vm_manager_fini - cleanup VM manager
|
* amdgpu_vm_manager_fini - cleanup VM manager
|
||||||
*
|
*
|
||||||
|
|
|
@ -694,7 +694,8 @@ static int gmc_v7_0_vm_init(struct amdgpu_device *adev)
|
||||||
* amdgpu graphics/compute will use VMIDs 1-7
|
* amdgpu graphics/compute will use VMIDs 1-7
|
||||||
* amdkfd will use VMIDs 8-15
|
* amdkfd will use VMIDs 8-15
|
||||||
*/
|
*/
|
||||||
adev->vm_manager.nvm = AMDGPU_NUM_OF_VMIDS;
|
adev->vm_manager.num_ids = AMDGPU_NUM_OF_VMIDS;
|
||||||
|
amdgpu_vm_manager_init(adev);
|
||||||
|
|
||||||
/* base offset of vram pages */
|
/* base offset of vram pages */
|
||||||
if (adev->flags & AMD_IS_APU) {
|
if (adev->flags & AMD_IS_APU) {
|
||||||
|
|
|
@ -774,7 +774,8 @@ static int gmc_v8_0_vm_init(struct amdgpu_device *adev)
|
||||||
* amdgpu graphics/compute will use VMIDs 1-7
|
* amdgpu graphics/compute will use VMIDs 1-7
|
||||||
* amdkfd will use VMIDs 8-15
|
* amdkfd will use VMIDs 8-15
|
||||||
*/
|
*/
|
||||||
adev->vm_manager.nvm = AMDGPU_NUM_OF_VMIDS;
|
adev->vm_manager.num_ids = AMDGPU_NUM_OF_VMIDS;
|
||||||
|
amdgpu_vm_manager_init(adev);
|
||||||
|
|
||||||
/* base offset of vram pages */
|
/* base offset of vram pages */
|
||||||
if (adev->flags & AMD_IS_APU) {
|
if (adev->flags & AMD_IS_APU) {
|
||||||
|
|
Loading…
Reference in New Issue