mirror of https://gitee.com/openkylin/linux.git
Merge branch 'drm-next-4.16' of git://people.freedesktop.org/~agd5f/linux into drm-next
Last few updates for 4.16: - Misc fixes for amdgpu - Enable swapout for reserved BOs during allocation for ttm - Misc cleanups for ttm * 'drm-next-4.16' of git://people.freedesktop.org/~agd5f/linux: (24 commits) drm/amdgpu: Correct the IB size of bo update mapping. drm/ttm: enable swapout for reserved BOs during allocation drm/ttm: add new function to check if bo is allowable to evict or swapout drm/ttm: use an operation ctx for ttm_tt_bind drm/ttm: use an operation ctx for ttm_tt_populate in ttm_bo_driver (v2) drm/ttm: use an operation ctx for ttm_mem_global_alloc_page drm/ttm: use an operation ctx for ttm_mem_global_alloc drm/ttm: call ttm_bo_swapout directly when ttm shrink drm/vmwgfx: remove the default io_mem_pfn set drm/virtio: remove the default io_mem_pfn set drm/radeon: remove the default io_mem_pfn set drm/qxl: remove the default io_mem_pfn set drm/nouveau: remove the default io_mem_pfn set drm/mgag200: remove the default io_mem_pfn set drm/cirrus: remove the default io_mem_pfn set drm/bochs: remove the default io_mem_pfn set drm/ast: remove the default io_mem_pfn set drm/ttm: add ttm_bo_io_mem_pfn to check io_mem_pfn drm/amdgpu: fix VM faults with per VM BOs drm/ttm: drop the spin in delayed delete if the trylock doesn't work ...
This commit is contained in:
commit
bd3c0094a1
|
@ -52,7 +52,8 @@ amdgpu-y += amdgpu_device.o amdgpu_kms.o \
|
|||
amdgpu_prime.o amdgpu_vm.o amdgpu_ib.o amdgpu_pll.o \
|
||||
amdgpu_ucode.o amdgpu_bo_list.o amdgpu_ctx.o amdgpu_sync.o \
|
||||
amdgpu_gtt_mgr.o amdgpu_vram_mgr.o amdgpu_virt.o amdgpu_atomfirmware.o \
|
||||
amdgpu_queue_mgr.o amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o
|
||||
amdgpu_queue_mgr.o amdgpu_vf_error.o amdgpu_sched.o amdgpu_debugfs.o \
|
||||
amdgpu_ids.o
|
||||
|
||||
# add asic specific block
|
||||
amdgpu-$(CONFIG_DRM_AMDGPU_CIK)+= cik.o cik_ih.o kv_smc.o kv_dpm.o \
|
||||
|
|
|
@ -351,7 +351,7 @@ struct amdgpu_gart_funcs {
|
|||
/* get the pde for a given mc addr */
|
||||
void (*get_vm_pde)(struct amdgpu_device *adev, int level,
|
||||
u64 *dst, u64 *flags);
|
||||
uint32_t (*get_invalidate_req)(unsigned int vm_id);
|
||||
uint32_t (*get_invalidate_req)(unsigned int vmid);
|
||||
};
|
||||
|
||||
/* provided by the ih block */
|
||||
|
@ -1125,7 +1125,7 @@ struct amdgpu_job {
|
|||
void *owner;
|
||||
uint64_t fence_ctx; /* the fence_context this job uses */
|
||||
bool vm_needs_flush;
|
||||
unsigned vm_id;
|
||||
unsigned vmid;
|
||||
uint64_t vm_pd_addr;
|
||||
uint32_t gds_base, gds_size;
|
||||
uint32_t gws_base, gws_size;
|
||||
|
@ -1850,7 +1850,7 @@ amdgpu_get_sdma_instance(struct amdgpu_ring *ring)
|
|||
#define amdgpu_ring_get_rptr(r) (r)->funcs->get_rptr((r))
|
||||
#define amdgpu_ring_get_wptr(r) (r)->funcs->get_wptr((r))
|
||||
#define amdgpu_ring_set_wptr(r) (r)->funcs->set_wptr((r))
|
||||
#define amdgpu_ring_emit_ib(r, ib, vm_id, c) (r)->funcs->emit_ib((r), (ib), (vm_id), (c))
|
||||
#define amdgpu_ring_emit_ib(r, ib, vmid, c) (r)->funcs->emit_ib((r), (ib), (vmid), (c))
|
||||
#define amdgpu_ring_emit_pipeline_sync(r) (r)->funcs->emit_pipeline_sync((r))
|
||||
#define amdgpu_ring_emit_vm_flush(r, vmid, addr) (r)->funcs->emit_vm_flush((r), (vmid), (addr))
|
||||
#define amdgpu_ring_emit_fence(r, addr, seq, flags) (r)->funcs->emit_fence((r), (addr), (seq), (flags))
|
||||
|
|
|
@ -176,8 +176,8 @@ static const struct kfd2kgd_calls kfd2kgd = {
|
|||
.get_local_mem_info = get_local_mem_info,
|
||||
.get_gpu_clock_counter = get_gpu_clock_counter,
|
||||
.get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz,
|
||||
.alloc_pasid = amdgpu_vm_alloc_pasid,
|
||||
.free_pasid = amdgpu_vm_free_pasid,
|
||||
.alloc_pasid = amdgpu_pasid_alloc,
|
||||
.free_pasid = amdgpu_pasid_free,
|
||||
.program_sh_mem_settings = kgd_program_sh_mem_settings,
|
||||
.set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
|
||||
.init_pipeline = kgd_init_pipeline,
|
||||
|
|
|
@ -135,8 +135,8 @@ static const struct kfd2kgd_calls kfd2kgd = {
|
|||
.get_local_mem_info = get_local_mem_info,
|
||||
.get_gpu_clock_counter = get_gpu_clock_counter,
|
||||
.get_max_engine_clock_in_mhz = get_max_engine_clock_in_mhz,
|
||||
.alloc_pasid = amdgpu_vm_alloc_pasid,
|
||||
.free_pasid = amdgpu_vm_free_pasid,
|
||||
.alloc_pasid = amdgpu_pasid_alloc,
|
||||
.free_pasid = amdgpu_pasid_free,
|
||||
.program_sh_mem_settings = kgd_program_sh_mem_settings,
|
||||
.set_pasid_vmid_mapping = kgd_set_pasid_vmid_mapping,
|
||||
.init_pipeline = kgd_init_pipeline,
|
||||
|
|
|
@ -801,6 +801,8 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device,
|
|||
else
|
||||
strcpy(fw_name, "amdgpu/vega10_smc.bin");
|
||||
break;
|
||||
case CHIP_CARRIZO:
|
||||
case CHIP_STONEY:
|
||||
case CHIP_RAVEN:
|
||||
adev->pm.fw_version = info->version;
|
||||
return 0;
|
||||
|
|
|
@ -149,7 +149,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vm && !job->vm_id) {
|
||||
if (vm && !job->vmid) {
|
||||
dev_err(adev->dev, "VM IB without ID\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
!amdgpu_sriov_vf(adev)) /* for SRIOV preemption, Preamble CE ib must be inserted anyway */
|
||||
continue;
|
||||
|
||||
amdgpu_ring_emit_ib(ring, ib, job ? job->vm_id : 0,
|
||||
amdgpu_ring_emit_ib(ring, ib, job ? job->vmid : 0,
|
||||
need_ctx_switch);
|
||||
need_ctx_switch = false;
|
||||
}
|
||||
|
@ -229,9 +229,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
r = amdgpu_fence_emit(ring, f);
|
||||
if (r) {
|
||||
dev_err(adev->dev, "failed to emit fence (%d)\n", r);
|
||||
if (job && job->vm_id)
|
||||
amdgpu_vm_reset_id(adev, ring->funcs->vmhub,
|
||||
job->vm_id);
|
||||
if (job && job->vmid)
|
||||
amdgpu_vmid_reset(adev, ring->funcs->vmhub, job->vmid);
|
||||
amdgpu_ring_undo(ring);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
* Copyright 2017 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include "amdgpu_ids.h"
|
||||
|
||||
#include <linux/idr.h>
|
||||
#include <linux/dma-fence-array.h>
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_trace.h"
|
||||
|
||||
/*
|
||||
* PASID manager
|
||||
*
|
||||
* PASIDs are global address space identifiers that can be shared
|
||||
* between the GPU, an IOMMU and the driver. VMs on different devices
|
||||
* may use the same PASID if they share the same address
|
||||
* space. Therefore PASIDs are allocated using a global IDA. VMs are
|
||||
* looked up from the PASID per amdgpu_device.
|
||||
*/
|
||||
static DEFINE_IDA(amdgpu_pasid_ida);
|
||||
|
||||
/**
|
||||
* amdgpu_pasid_alloc - Allocate a PASID
|
||||
* @bits: Maximum width of the PASID in bits, must be at least 1
|
||||
*
|
||||
* Allocates a PASID of the given width while keeping smaller PASIDs
|
||||
* available if possible.
|
||||
*
|
||||
* Returns a positive integer on success. Returns %-EINVAL if bits==0.
|
||||
* Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on
|
||||
* memory allocation failure.
|
||||
*/
|
||||
int amdgpu_pasid_alloc(unsigned int bits)
|
||||
{
|
||||
int pasid = -EINVAL;
|
||||
|
||||
for (bits = min(bits, 31U); bits > 0; bits--) {
|
||||
pasid = ida_simple_get(&amdgpu_pasid_ida,
|
||||
1U << (bits - 1), 1U << bits,
|
||||
GFP_KERNEL);
|
||||
if (pasid != -ENOSPC)
|
||||
break;
|
||||
}
|
||||
|
||||
return pasid;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_pasid_free - Free a PASID
|
||||
* @pasid: PASID to free
|
||||
*/
|
||||
void amdgpu_pasid_free(unsigned int pasid)
|
||||
{
|
||||
ida_simple_remove(&amdgpu_pasid_ida, pasid);
|
||||
}
|
||||
|
||||
/*
|
||||
* VMID manager
|
||||
*
|
||||
* VMIDs are a per VMHUB identifier for page tables handling.
|
||||
*/
|
||||
|
||||
/**
|
||||
* amdgpu_vmid_had_gpu_reset - check if reset occured since last use
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @id: VMID structure
|
||||
*
|
||||
* Check if GPU reset occured since last use of the VMID.
|
||||
*/
|
||||
bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev,
|
||||
struct amdgpu_vmid *id)
|
||||
{
|
||||
return id->current_gpu_reset_count !=
|
||||
atomic_read(&adev->gpu_reset_counter);
|
||||
}
|
||||
|
||||
/* idr_mgr->lock must be held */
|
||||
static int amdgpu_vmid_grab_reserved_locked(struct amdgpu_vm *vm,
|
||||
struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync,
|
||||
struct dma_fence *fence,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned vmhub = ring->funcs->vmhub;
|
||||
uint64_t fence_context = adev->fence_context + ring->idx;
|
||||
struct amdgpu_vmid *id = vm->reserved_vmid[vmhub];
|
||||
struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct dma_fence *updates = sync->last_vm_update;
|
||||
int r = 0;
|
||||
struct dma_fence *flushed, *tmp;
|
||||
bool needs_flush = vm->use_cpu_for_update;
|
||||
|
||||
flushed = id->flushed_updates;
|
||||
if ((amdgpu_vmid_had_gpu_reset(adev, id)) ||
|
||||
(atomic64_read(&id->owner) != vm->entity.fence_context) ||
|
||||
(job->vm_pd_addr != id->pd_gpu_addr) ||
|
||||
(updates && (!flushed || updates->context != flushed->context ||
|
||||
dma_fence_is_later(updates, flushed))) ||
|
||||
(!id->last_flush || (id->last_flush->context != fence_context &&
|
||||
!dma_fence_is_signaled(id->last_flush)))) {
|
||||
needs_flush = true;
|
||||
/* to prevent one context starved by another context */
|
||||
id->pd_gpu_addr = 0;
|
||||
tmp = amdgpu_sync_peek_fence(&id->active, ring);
|
||||
if (tmp) {
|
||||
r = amdgpu_sync_fence(adev, sync, tmp, false);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* Good we can use this VMID. Remember this submission as
|
||||
* user of the VMID.
|
||||
*/
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
if (updates && (!flushed || updates->context != flushed->context ||
|
||||
dma_fence_is_later(updates, flushed))) {
|
||||
dma_fence_put(id->flushed_updates);
|
||||
id->flushed_updates = dma_fence_get(updates);
|
||||
}
|
||||
id->pd_gpu_addr = job->vm_pd_addr;
|
||||
atomic64_set(&id->owner, vm->entity.fence_context);
|
||||
job->vm_needs_flush = needs_flush;
|
||||
if (needs_flush) {
|
||||
dma_fence_put(id->last_flush);
|
||||
id->last_flush = NULL;
|
||||
}
|
||||
job->vmid = id - id_mgr->ids;
|
||||
trace_amdgpu_vm_grab_id(vm, ring, job);
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_grab_id - allocate the next free VMID
|
||||
*
|
||||
* @vm: vm to allocate id for
|
||||
* @ring: ring we want to submit job to
|
||||
* @sync: sync object where we add dependencies
|
||||
* @fence: fence protecting ID from reuse
|
||||
*
|
||||
* Allocate an id for the vm, adding fences to the sync obj as necessary.
|
||||
*/
|
||||
int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync, struct dma_fence *fence,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
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;
|
||||
struct dma_fence *updates = sync->last_vm_update;
|
||||
struct amdgpu_vmid *id, *idle;
|
||||
struct dma_fence **fences;
|
||||
unsigned i;
|
||||
int r = 0;
|
||||
|
||||
mutex_lock(&id_mgr->lock);
|
||||
if (vm->reserved_vmid[vmhub]) {
|
||||
r = amdgpu_vmid_grab_reserved_locked(vm, ring, sync, fence, job);
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return r;
|
||||
}
|
||||
fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL);
|
||||
if (!fences) {
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Check if we have an idle VMID */
|
||||
i = 0;
|
||||
list_for_each_entry(idle, &id_mgr->ids_lru, list) {
|
||||
fences[i] = amdgpu_sync_peek_fence(&idle->active, ring);
|
||||
if (!fences[i])
|
||||
break;
|
||||
++i;
|
||||
}
|
||||
|
||||
/* If we can't find a idle VMID to use, wait till one becomes available */
|
||||
if (&idle->list == &id_mgr->ids_lru) {
|
||||
u64 fence_context = adev->vm_manager.fence_context + ring->idx;
|
||||
unsigned seqno = ++adev->vm_manager.seqno[ring->idx];
|
||||
struct dma_fence_array *array;
|
||||
unsigned j;
|
||||
|
||||
for (j = 0; j < i; ++j)
|
||||
dma_fence_get(fences[j]);
|
||||
|
||||
array = dma_fence_array_create(i, fences, fence_context,
|
||||
seqno, true);
|
||||
if (!array) {
|
||||
for (j = 0; j < i; ++j)
|
||||
dma_fence_put(fences[j]);
|
||||
kfree(fences);
|
||||
r = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
r = amdgpu_sync_fence(ring->adev, sync, &array->base, false);
|
||||
dma_fence_put(&array->base);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return 0;
|
||||
|
||||
}
|
||||
kfree(fences);
|
||||
|
||||
job->vm_needs_flush = vm->use_cpu_for_update;
|
||||
/* Check if we can use a VMID already assigned to this VM */
|
||||
list_for_each_entry_reverse(id, &id_mgr->ids_lru, list) {
|
||||
struct dma_fence *flushed;
|
||||
bool needs_flush = vm->use_cpu_for_update;
|
||||
|
||||
/* Check all the prerequisites to using this VMID */
|
||||
if (amdgpu_vmid_had_gpu_reset(adev, id))
|
||||
continue;
|
||||
|
||||
if (atomic64_read(&id->owner) != vm->entity.fence_context)
|
||||
continue;
|
||||
|
||||
if (job->vm_pd_addr != id->pd_gpu_addr)
|
||||
continue;
|
||||
|
||||
if (!id->last_flush ||
|
||||
(id->last_flush->context != fence_context &&
|
||||
!dma_fence_is_signaled(id->last_flush)))
|
||||
needs_flush = true;
|
||||
|
||||
flushed = id->flushed_updates;
|
||||
if (updates && (!flushed || dma_fence_is_later(updates, flushed)))
|
||||
needs_flush = true;
|
||||
|
||||
/* Concurrent flushes are only possible starting with Vega10 */
|
||||
if (adev->asic_type < CHIP_VEGA10 && needs_flush)
|
||||
continue;
|
||||
|
||||
/* Good we can use this VMID. Remember this submission as
|
||||
* user of the VMID.
|
||||
*/
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
if (updates && (!flushed || dma_fence_is_later(updates, flushed))) {
|
||||
dma_fence_put(id->flushed_updates);
|
||||
id->flushed_updates = dma_fence_get(updates);
|
||||
}
|
||||
|
||||
if (needs_flush)
|
||||
goto needs_flush;
|
||||
else
|
||||
goto no_flush_needed;
|
||||
|
||||
};
|
||||
|
||||
/* Still no ID to use? Then use the idle one found earlier */
|
||||
id = idle;
|
||||
|
||||
/* Remember this submission as user of the VMID */
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
id->pd_gpu_addr = job->vm_pd_addr;
|
||||
dma_fence_put(id->flushed_updates);
|
||||
id->flushed_updates = dma_fence_get(updates);
|
||||
atomic64_set(&id->owner, vm->entity.fence_context);
|
||||
|
||||
needs_flush:
|
||||
job->vm_needs_flush = true;
|
||||
dma_fence_put(id->last_flush);
|
||||
id->last_flush = NULL;
|
||||
|
||||
no_flush_needed:
|
||||
list_move_tail(&id->list, &id_mgr->ids_lru);
|
||||
|
||||
job->vmid = id - id_mgr->ids;
|
||||
trace_amdgpu_vm_grab_id(vm, ring, job);
|
||||
|
||||
error:
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
/* 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);
|
||||
|
||||
return 0;
|
||||
unlock:
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
void amdgpu_vmid_free_reserved(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
unsigned vmhub)
|
||||
{
|
||||
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);
|
||||
}
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vmid_reset - reset VMID to zero
|
||||
*
|
||||
* @adev: amdgpu device structure
|
||||
* @vmid: vmid number to use
|
||||
*
|
||||
* Reset saved GDW, GWS and OA to force switch on next flush.
|
||||
*/
|
||||
void amdgpu_vmid_reset(struct amdgpu_device *adev, unsigned vmhub,
|
||||
unsigned vmid)
|
||||
{
|
||||
struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct amdgpu_vmid *id = &id_mgr->ids[vmid];
|
||||
|
||||
atomic64_set(&id->owner, 0);
|
||||
id->gds_base = 0;
|
||||
id->gds_size = 0;
|
||||
id->gws_base = 0;
|
||||
id->gws_size = 0;
|
||||
id->oa_base = 0;
|
||||
id->oa_size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vmid_reset_all - reset VMID to zero
|
||||
*
|
||||
* @adev: amdgpu device structure
|
||||
*
|
||||
* Reset VMID to force flush on next use
|
||||
*/
|
||||
void amdgpu_vmid_reset_all(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
|
||||
struct amdgpu_vmid_mgr *id_mgr =
|
||||
&adev->vm_manager.id_mgr[i];
|
||||
|
||||
for (j = 1; j < id_mgr->num_ids; ++j)
|
||||
amdgpu_vmid_reset(adev, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vmid_mgr_init - init the VMID manager
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Initialize the VM manager structures
|
||||
*/
|
||||
void amdgpu_vmid_mgr_init(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
|
||||
struct amdgpu_vmid_mgr *id_mgr =
|
||||
&adev->vm_manager.id_mgr[i];
|
||||
|
||||
mutex_init(&id_mgr->lock);
|
||||
INIT_LIST_HEAD(&id_mgr->ids_lru);
|
||||
atomic_set(&id_mgr->reserved_vmid_num, 0);
|
||||
|
||||
/* skip over VMID 0, since it is the system VM */
|
||||
for (j = 1; j < id_mgr->num_ids; ++j) {
|
||||
amdgpu_vmid_reset(adev, i, j);
|
||||
amdgpu_sync_create(&id_mgr->ids[i].active);
|
||||
list_add_tail(&id_mgr->ids[j].list, &id_mgr->ids_lru);
|
||||
}
|
||||
}
|
||||
|
||||
adev->vm_manager.fence_context =
|
||||
dma_fence_context_alloc(AMDGPU_MAX_RINGS);
|
||||
for (i = 0; i < AMDGPU_MAX_RINGS; ++i)
|
||||
adev->vm_manager.seqno[i] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vmid_mgr_fini - cleanup VM manager
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
*
|
||||
* Cleanup the VM manager and free resources.
|
||||
*/
|
||||
void amdgpu_vmid_mgr_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
|
||||
struct amdgpu_vmid_mgr *id_mgr =
|
||||
&adev->vm_manager.id_mgr[i];
|
||||
|
||||
mutex_destroy(&id_mgr->lock);
|
||||
for (j = 0; j < AMDGPU_NUM_VMID; ++j) {
|
||||
struct amdgpu_vmid *id = &id_mgr->ids[j];
|
||||
|
||||
amdgpu_sync_free(&id->active);
|
||||
dma_fence_put(id->flushed_updates);
|
||||
dma_fence_put(id->last_flush);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright 2017 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef __AMDGPU_IDS_H__
|
||||
#define __AMDGPU_IDS_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/dma-fence.h>
|
||||
|
||||
#include "amdgpu_sync.h"
|
||||
|
||||
/* maximum number of VMIDs */
|
||||
#define AMDGPU_NUM_VMID 16
|
||||
|
||||
struct amdgpu_device;
|
||||
struct amdgpu_vm;
|
||||
struct amdgpu_ring;
|
||||
struct amdgpu_sync;
|
||||
struct amdgpu_job;
|
||||
|
||||
struct amdgpu_vmid {
|
||||
struct list_head list;
|
||||
struct amdgpu_sync active;
|
||||
struct dma_fence *last_flush;
|
||||
atomic64_t owner;
|
||||
|
||||
uint64_t pd_gpu_addr;
|
||||
/* last flushed PD/PT update */
|
||||
struct dma_fence *flushed_updates;
|
||||
|
||||
uint32_t current_gpu_reset_count;
|
||||
|
||||
uint32_t gds_base;
|
||||
uint32_t gds_size;
|
||||
uint32_t gws_base;
|
||||
uint32_t gws_size;
|
||||
uint32_t oa_base;
|
||||
uint32_t oa_size;
|
||||
};
|
||||
|
||||
struct amdgpu_vmid_mgr {
|
||||
struct mutex lock;
|
||||
unsigned num_ids;
|
||||
struct list_head ids_lru;
|
||||
struct amdgpu_vmid ids[AMDGPU_NUM_VMID];
|
||||
atomic_t reserved_vmid_num;
|
||||
};
|
||||
|
||||
int amdgpu_pasid_alloc(unsigned int bits);
|
||||
void amdgpu_pasid_free(unsigned int pasid);
|
||||
|
||||
bool amdgpu_vmid_had_gpu_reset(struct amdgpu_device *adev,
|
||||
struct amdgpu_vmid *id);
|
||||
int amdgpu_vmid_alloc_reserved(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
unsigned vmhub);
|
||||
void amdgpu_vmid_free_reserved(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
unsigned vmhub);
|
||||
int amdgpu_vmid_grab(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync, struct dma_fence *fence,
|
||||
struct amdgpu_job *job);
|
||||
void amdgpu_vmid_reset(struct amdgpu_device *adev, unsigned vmhub,
|
||||
unsigned vmid);
|
||||
void amdgpu_vmid_reset_all(struct amdgpu_device *adev);
|
||||
|
||||
void amdgpu_vmid_mgr_init(struct amdgpu_device *adev);
|
||||
void amdgpu_vmid_mgr_fini(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
|
@ -105,8 +105,8 @@ struct amdgpu_iv_entry {
|
|||
unsigned client_id;
|
||||
unsigned src_id;
|
||||
unsigned ring_id;
|
||||
unsigned vm_id;
|
||||
unsigned vm_id_src;
|
||||
unsigned vmid;
|
||||
unsigned vmid_src;
|
||||
uint64_t timestamp;
|
||||
unsigned timestamp_src;
|
||||
unsigned pas_id;
|
||||
|
|
|
@ -158,12 +158,12 @@ static struct dma_fence *amdgpu_job_dependency(struct drm_sched_job *sched_job,
|
|||
}
|
||||
}
|
||||
|
||||
while (fence == NULL && vm && !job->vm_id) {
|
||||
while (fence == NULL && vm && !job->vmid) {
|
||||
struct amdgpu_ring *ring = job->ring;
|
||||
|
||||
r = amdgpu_vm_grab_id(vm, ring, &job->sync,
|
||||
&job->base.s_fence->finished,
|
||||
job);
|
||||
r = amdgpu_vmid_grab(vm, ring, &job->sync,
|
||||
&job->base.s_fence->finished,
|
||||
job);
|
||||
if (r)
|
||||
DRM_ERROR("Error getting VM ID (%d)\n", r);
|
||||
|
||||
|
|
|
@ -121,11 +121,11 @@ struct amdgpu_ring_funcs {
|
|||
/* command emit functions */
|
||||
void (*emit_ib)(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch);
|
||||
unsigned vmid, bool ctx_switch);
|
||||
void (*emit_fence)(struct amdgpu_ring *ring, uint64_t addr,
|
||||
uint64_t seq, unsigned flags);
|
||||
void (*emit_pipeline_sync)(struct amdgpu_ring *ring);
|
||||
void (*emit_vm_flush)(struct amdgpu_ring *ring, unsigned vm_id,
|
||||
void (*emit_vm_flush)(struct amdgpu_ring *ring, unsigned vmid,
|
||||
uint64_t pd_addr);
|
||||
void (*emit_hdp_flush)(struct amdgpu_ring *ring);
|
||||
void (*emit_hdp_invalidate)(struct amdgpu_ring *ring);
|
||||
|
|
|
@ -82,8 +82,8 @@ TRACE_EVENT(amdgpu_iv,
|
|||
__field(unsigned, client_id)
|
||||
__field(unsigned, src_id)
|
||||
__field(unsigned, ring_id)
|
||||
__field(unsigned, vm_id)
|
||||
__field(unsigned, vm_id_src)
|
||||
__field(unsigned, vmid)
|
||||
__field(unsigned, vmid_src)
|
||||
__field(uint64_t, timestamp)
|
||||
__field(unsigned, timestamp_src)
|
||||
__field(unsigned, pas_id)
|
||||
|
@ -93,8 +93,8 @@ TRACE_EVENT(amdgpu_iv,
|
|||
__entry->client_id = iv->client_id;
|
||||
__entry->src_id = iv->src_id;
|
||||
__entry->ring_id = iv->ring_id;
|
||||
__entry->vm_id = iv->vm_id;
|
||||
__entry->vm_id_src = iv->vm_id_src;
|
||||
__entry->vmid = iv->vmid;
|
||||
__entry->vmid_src = iv->vmid_src;
|
||||
__entry->timestamp = iv->timestamp;
|
||||
__entry->timestamp_src = iv->timestamp_src;
|
||||
__entry->pas_id = iv->pas_id;
|
||||
|
@ -103,9 +103,9 @@ TRACE_EVENT(amdgpu_iv,
|
|||
__entry->src_data[2] = iv->src_data[2];
|
||||
__entry->src_data[3] = iv->src_data[3];
|
||||
),
|
||||
TP_printk("client_id:%u src_id:%u ring:%u vm_id:%u timestamp: %llu pas_id:%u src_data: %08x %08x %08x %08x\n",
|
||||
TP_printk("client_id:%u src_id:%u ring:%u vmid:%u timestamp: %llu pas_id:%u src_data: %08x %08x %08x %08x\n",
|
||||
__entry->client_id, __entry->src_id,
|
||||
__entry->ring_id, __entry->vm_id,
|
||||
__entry->ring_id, __entry->vmid,
|
||||
__entry->timestamp, __entry->pas_id,
|
||||
__entry->src_data[0], __entry->src_data[1],
|
||||
__entry->src_data[2], __entry->src_data[3])
|
||||
|
@ -219,7 +219,7 @@ TRACE_EVENT(amdgpu_vm_grab_id,
|
|||
TP_STRUCT__entry(
|
||||
__field(struct amdgpu_vm *, vm)
|
||||
__field(u32, ring)
|
||||
__field(u32, vm_id)
|
||||
__field(u32, vmid)
|
||||
__field(u32, vm_hub)
|
||||
__field(u64, pd_addr)
|
||||
__field(u32, needs_flush)
|
||||
|
@ -228,13 +228,13 @@ TRACE_EVENT(amdgpu_vm_grab_id,
|
|||
TP_fast_assign(
|
||||
__entry->vm = vm;
|
||||
__entry->ring = ring->idx;
|
||||
__entry->vm_id = job->vm_id;
|
||||
__entry->vmid = job->vmid;
|
||||
__entry->vm_hub = ring->funcs->vmhub,
|
||||
__entry->pd_addr = job->vm_pd_addr;
|
||||
__entry->needs_flush = job->vm_needs_flush;
|
||||
),
|
||||
TP_printk("vm=%p, ring=%u, id=%u, hub=%u, pd_addr=%010Lx needs_flush=%u",
|
||||
__entry->vm, __entry->ring, __entry->vm_id,
|
||||
__entry->vm, __entry->ring, __entry->vmid,
|
||||
__entry->vm_hub, __entry->pd_addr, __entry->needs_flush)
|
||||
);
|
||||
|
||||
|
@ -357,24 +357,24 @@ TRACE_EVENT(amdgpu_vm_copy_ptes,
|
|||
);
|
||||
|
||||
TRACE_EVENT(amdgpu_vm_flush,
|
||||
TP_PROTO(struct amdgpu_ring *ring, unsigned vm_id,
|
||||
TP_PROTO(struct amdgpu_ring *ring, unsigned vmid,
|
||||
uint64_t pd_addr),
|
||||
TP_ARGS(ring, vm_id, pd_addr),
|
||||
TP_ARGS(ring, vmid, pd_addr),
|
||||
TP_STRUCT__entry(
|
||||
__field(u32, ring)
|
||||
__field(u32, vm_id)
|
||||
__field(u32, vmid)
|
||||
__field(u32, vm_hub)
|
||||
__field(u64, pd_addr)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__entry->ring = ring->idx;
|
||||
__entry->vm_id = vm_id;
|
||||
__entry->vmid = vmid;
|
||||
__entry->vm_hub = ring->funcs->vmhub;
|
||||
__entry->pd_addr = pd_addr;
|
||||
),
|
||||
TP_printk("ring=%u, id=%u, hub=%u, pd_addr=%010Lx",
|
||||
__entry->ring, __entry->vm_id,
|
||||
__entry->ring, __entry->vmid,
|
||||
__entry->vm_hub,__entry->pd_addr)
|
||||
);
|
||||
|
||||
|
|
|
@ -497,7 +497,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,
|
|||
goto out_cleanup;
|
||||
}
|
||||
|
||||
r = ttm_tt_bind(bo->ttm, &tmp_mem);
|
||||
r = ttm_tt_bind(bo->ttm, &tmp_mem, ctx);
|
||||
if (unlikely(r)) {
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
@ -990,7 +990,8 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_bo_device *bdev,
|
|||
return >t->ttm.ttm;
|
||||
}
|
||||
|
||||
static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
|
||||
struct amdgpu_ttm_tt *gtt = (void *)ttm;
|
||||
|
@ -1018,11 +1019,11 @@ static int amdgpu_ttm_tt_populate(struct ttm_tt *ttm)
|
|||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
if (swiotlb_nr_tbl()) {
|
||||
return ttm_dma_populate(>t->ttm, adev->dev);
|
||||
return ttm_dma_populate(>t->ttm, adev->dev, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ttm_populate_and_map_pages(adev->dev, >t->ttm);
|
||||
return ttm_populate_and_map_pages(adev->dev, >t->ttm, ctx);
|
||||
}
|
||||
|
||||
static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||
|
|
|
@ -991,7 +991,7 @@ int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx)
|
|||
*
|
||||
*/
|
||||
void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
amdgpu_ring_write(ring, VCE_CMD_IB);
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
|
||||
|
|
|
@ -63,7 +63,7 @@ void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp);
|
|||
int amdgpu_vce_ring_parse_cs(struct amdgpu_cs_parser *p, uint32_t ib_idx);
|
||||
int amdgpu_vce_ring_parse_cs_vm(struct amdgpu_cs_parser *p, uint32_t ib_idx);
|
||||
void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch);
|
||||
unsigned vmid, bool ctx_switch);
|
||||
void amdgpu_vce_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
|
||||
unsigned flags);
|
||||
int amdgpu_vce_ring_test_ring(struct amdgpu_ring *ring);
|
||||
|
|
|
@ -33,52 +33,6 @@
|
|||
#include "amdgpu.h"
|
||||
#include "amdgpu_trace.h"
|
||||
|
||||
/*
|
||||
* PASID manager
|
||||
*
|
||||
* PASIDs are global address space identifiers that can be shared
|
||||
* between the GPU, an IOMMU and the driver. VMs on different devices
|
||||
* may use the same PASID if they share the same address
|
||||
* space. Therefore PASIDs are allocated using a global IDA. VMs are
|
||||
* looked up from the PASID per amdgpu_device.
|
||||
*/
|
||||
static DEFINE_IDA(amdgpu_vm_pasid_ida);
|
||||
|
||||
/**
|
||||
* amdgpu_vm_alloc_pasid - Allocate a PASID
|
||||
* @bits: Maximum width of the PASID in bits, must be at least 1
|
||||
*
|
||||
* Allocates a PASID of the given width while keeping smaller PASIDs
|
||||
* available if possible.
|
||||
*
|
||||
* Returns a positive integer on success. Returns %-EINVAL if bits==0.
|
||||
* Returns %-ENOSPC if no PASID was available. Returns %-ENOMEM on
|
||||
* memory allocation failure.
|
||||
*/
|
||||
int amdgpu_vm_alloc_pasid(unsigned int bits)
|
||||
{
|
||||
int pasid = -EINVAL;
|
||||
|
||||
for (bits = min(bits, 31U); bits > 0; bits--) {
|
||||
pasid = ida_simple_get(&amdgpu_vm_pasid_ida,
|
||||
1U << (bits - 1), 1U << bits,
|
||||
GFP_KERNEL);
|
||||
if (pasid != -ENOSPC)
|
||||
break;
|
||||
}
|
||||
|
||||
return pasid;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_free_pasid - Free a PASID
|
||||
* @pasid: PASID to free
|
||||
*/
|
||||
void amdgpu_vm_free_pasid(unsigned int pasid)
|
||||
{
|
||||
ida_simple_remove(&amdgpu_vm_pasid_ida, pasid);
|
||||
}
|
||||
|
||||
/*
|
||||
* GPUVM
|
||||
* GPUVM is similar to the legacy gart on older asics, however
|
||||
|
@ -447,286 +401,6 @@ int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
|
|||
adev->vm_manager.root_level);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_had_gpu_reset - check if reset occured since last use
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @id: VMID structure
|
||||
*
|
||||
* Check if GPU reset occured since last use of the VMID.
|
||||
*/
|
||||
static bool amdgpu_vm_had_gpu_reset(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm_id *id)
|
||||
{
|
||||
return id->current_gpu_reset_count !=
|
||||
atomic_read(&adev->gpu_reset_counter);
|
||||
}
|
||||
|
||||
static bool amdgpu_vm_reserved_vmid_ready(struct amdgpu_vm *vm, unsigned vmhub)
|
||||
{
|
||||
return !!vm->reserved_vmid[vmhub];
|
||||
}
|
||||
|
||||
/* idr_mgr->lock must be held */
|
||||
static int amdgpu_vm_grab_reserved_vmid_locked(struct amdgpu_vm *vm,
|
||||
struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync,
|
||||
struct dma_fence *fence,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned vmhub = ring->funcs->vmhub;
|
||||
uint64_t fence_context = adev->fence_context + ring->idx;
|
||||
struct amdgpu_vm_id *id = vm->reserved_vmid[vmhub];
|
||||
struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct dma_fence *updates = sync->last_vm_update;
|
||||
int r = 0;
|
||||
struct dma_fence *flushed, *tmp;
|
||||
bool needs_flush = vm->use_cpu_for_update;
|
||||
|
||||
flushed = id->flushed_updates;
|
||||
if ((amdgpu_vm_had_gpu_reset(adev, id)) ||
|
||||
(atomic64_read(&id->owner) != vm->client_id) ||
|
||||
(job->vm_pd_addr != id->pd_gpu_addr) ||
|
||||
(updates && (!flushed || updates->context != flushed->context ||
|
||||
dma_fence_is_later(updates, flushed))) ||
|
||||
(!id->last_flush || (id->last_flush->context != fence_context &&
|
||||
!dma_fence_is_signaled(id->last_flush)))) {
|
||||
needs_flush = true;
|
||||
/* to prevent one context starved by another context */
|
||||
id->pd_gpu_addr = 0;
|
||||
tmp = amdgpu_sync_peek_fence(&id->active, ring);
|
||||
if (tmp) {
|
||||
r = amdgpu_sync_fence(adev, sync, tmp, false);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
/* Good we can use this VMID. Remember this submission as
|
||||
* user of the VMID.
|
||||
*/
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
|
||||
if (r)
|
||||
goto out;
|
||||
|
||||
if (updates && (!flushed || updates->context != flushed->context ||
|
||||
dma_fence_is_later(updates, flushed))) {
|
||||
dma_fence_put(id->flushed_updates);
|
||||
id->flushed_updates = dma_fence_get(updates);
|
||||
}
|
||||
id->pd_gpu_addr = job->vm_pd_addr;
|
||||
atomic64_set(&id->owner, vm->client_id);
|
||||
job->vm_needs_flush = needs_flush;
|
||||
if (needs_flush) {
|
||||
dma_fence_put(id->last_flush);
|
||||
id->last_flush = NULL;
|
||||
}
|
||||
job->vm_id = id - id_mgr->ids;
|
||||
trace_amdgpu_vm_grab_id(vm, ring, job);
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_grab_id - allocate the next free VMID
|
||||
*
|
||||
* @vm: vm to allocate id for
|
||||
* @ring: ring we want to submit job to
|
||||
* @sync: sync object where we add dependencies
|
||||
* @fence: fence protecting ID from reuse
|
||||
*
|
||||
* Allocate an id for the vm, adding fences to the sync obj as necessary.
|
||||
*/
|
||||
int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync, struct dma_fence *fence,
|
||||
struct amdgpu_job *job)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned vmhub = ring->funcs->vmhub;
|
||||
struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
uint64_t fence_context = adev->fence_context + ring->idx;
|
||||
struct dma_fence *updates = sync->last_vm_update;
|
||||
struct amdgpu_vm_id *id, *idle;
|
||||
struct dma_fence **fences;
|
||||
unsigned i;
|
||||
int r = 0;
|
||||
|
||||
mutex_lock(&id_mgr->lock);
|
||||
if (amdgpu_vm_reserved_vmid_ready(vm, vmhub)) {
|
||||
r = amdgpu_vm_grab_reserved_vmid_locked(vm, ring, sync, fence, job);
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return r;
|
||||
}
|
||||
fences = kmalloc_array(sizeof(void *), id_mgr->num_ids, GFP_KERNEL);
|
||||
if (!fences) {
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Check if we have an idle VMID */
|
||||
i = 0;
|
||||
list_for_each_entry(idle, &id_mgr->ids_lru, list) {
|
||||
fences[i] = amdgpu_sync_peek_fence(&idle->active, ring);
|
||||
if (!fences[i])
|
||||
break;
|
||||
++i;
|
||||
}
|
||||
|
||||
/* If we can't find a idle VMID to use, wait till one becomes available */
|
||||
if (&idle->list == &id_mgr->ids_lru) {
|
||||
u64 fence_context = adev->vm_manager.fence_context + ring->idx;
|
||||
unsigned seqno = ++adev->vm_manager.seqno[ring->idx];
|
||||
struct dma_fence_array *array;
|
||||
unsigned j;
|
||||
|
||||
for (j = 0; j < i; ++j)
|
||||
dma_fence_get(fences[j]);
|
||||
|
||||
array = dma_fence_array_create(i, fences, fence_context,
|
||||
seqno, true);
|
||||
if (!array) {
|
||||
for (j = 0; j < i; ++j)
|
||||
dma_fence_put(fences[j]);
|
||||
kfree(fences);
|
||||
r = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
r = amdgpu_sync_fence(ring->adev, sync, &array->base, false);
|
||||
dma_fence_put(&array->base);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return 0;
|
||||
|
||||
}
|
||||
kfree(fences);
|
||||
|
||||
job->vm_needs_flush = vm->use_cpu_for_update;
|
||||
/* Check if we can use a VMID already assigned to this VM */
|
||||
list_for_each_entry_reverse(id, &id_mgr->ids_lru, list) {
|
||||
struct dma_fence *flushed;
|
||||
bool needs_flush = vm->use_cpu_for_update;
|
||||
|
||||
/* Check all the prerequisites to using this VMID */
|
||||
if (amdgpu_vm_had_gpu_reset(adev, id))
|
||||
continue;
|
||||
|
||||
if (atomic64_read(&id->owner) != vm->client_id)
|
||||
continue;
|
||||
|
||||
if (job->vm_pd_addr != id->pd_gpu_addr)
|
||||
continue;
|
||||
|
||||
if (!id->last_flush ||
|
||||
(id->last_flush->context != fence_context &&
|
||||
!dma_fence_is_signaled(id->last_flush)))
|
||||
needs_flush = true;
|
||||
|
||||
flushed = id->flushed_updates;
|
||||
if (updates && (!flushed || dma_fence_is_later(updates, flushed)))
|
||||
needs_flush = true;
|
||||
|
||||
/* Concurrent flushes are only possible starting with Vega10 */
|
||||
if (adev->asic_type < CHIP_VEGA10 && needs_flush)
|
||||
continue;
|
||||
|
||||
/* Good we can use this VMID. Remember this submission as
|
||||
* user of the VMID.
|
||||
*/
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
if (updates && (!flushed || dma_fence_is_later(updates, flushed))) {
|
||||
dma_fence_put(id->flushed_updates);
|
||||
id->flushed_updates = dma_fence_get(updates);
|
||||
}
|
||||
|
||||
if (needs_flush)
|
||||
goto needs_flush;
|
||||
else
|
||||
goto no_flush_needed;
|
||||
|
||||
};
|
||||
|
||||
/* Still no ID to use? Then use the idle one found earlier */
|
||||
id = idle;
|
||||
|
||||
/* Remember this submission as user of the VMID */
|
||||
r = amdgpu_sync_fence(ring->adev, &id->active, fence, false);
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
id->pd_gpu_addr = job->vm_pd_addr;
|
||||
dma_fence_put(id->flushed_updates);
|
||||
id->flushed_updates = dma_fence_get(updates);
|
||||
atomic64_set(&id->owner, vm->client_id);
|
||||
|
||||
needs_flush:
|
||||
job->vm_needs_flush = true;
|
||||
dma_fence_put(id->last_flush);
|
||||
id->last_flush = NULL;
|
||||
|
||||
no_flush_needed:
|
||||
list_move_tail(&id->list, &id_mgr->ids_lru);
|
||||
|
||||
job->vm_id = id - id_mgr->ids;
|
||||
trace_amdgpu_vm_grab_id(vm, ring, job);
|
||||
|
||||
error:
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
static void amdgpu_vm_free_reserved_vmid(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
unsigned vmhub)
|
||||
{
|
||||
struct amdgpu_vm_id_manager *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);
|
||||
}
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
}
|
||||
|
||||
static int amdgpu_vm_alloc_reserved_vmid(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
unsigned vmhub)
|
||||
{
|
||||
struct amdgpu_vm_id_manager *id_mgr;
|
||||
struct amdgpu_vm_id *idle;
|
||||
int r = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
/* Select the first entry VMID */
|
||||
idle = list_first_entry(&id_mgr->ids_lru, struct amdgpu_vm_id, list);
|
||||
list_del_init(&idle->list);
|
||||
vm->reserved_vmid[vmhub] = idle;
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
|
||||
return 0;
|
||||
unlock:
|
||||
mutex_unlock(&id_mgr->lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_check_compute_bug - check whether asic has compute vm bug
|
||||
*
|
||||
|
@ -767,14 +441,14 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring,
|
|||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned vmhub = ring->funcs->vmhub;
|
||||
struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct amdgpu_vm_id *id;
|
||||
struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct amdgpu_vmid *id;
|
||||
bool gds_switch_needed;
|
||||
bool vm_flush_needed = job->vm_needs_flush || ring->has_compute_vm_bug;
|
||||
|
||||
if (job->vm_id == 0)
|
||||
if (job->vmid == 0)
|
||||
return false;
|
||||
id = &id_mgr->ids[job->vm_id];
|
||||
id = &id_mgr->ids[job->vmid];
|
||||
gds_switch_needed = ring->funcs->emit_gds_switch && (
|
||||
id->gds_base != job->gds_base ||
|
||||
id->gds_size != job->gds_size ||
|
||||
|
@ -783,7 +457,7 @@ bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring,
|
|||
id->oa_base != job->oa_base ||
|
||||
id->oa_size != job->oa_size);
|
||||
|
||||
if (amdgpu_vm_had_gpu_reset(adev, id))
|
||||
if (amdgpu_vmid_had_gpu_reset(adev, id))
|
||||
return true;
|
||||
|
||||
return vm_flush_needed || gds_switch_needed;
|
||||
|
@ -798,7 +472,7 @@ static bool amdgpu_vm_is_large_bar(struct amdgpu_device *adev)
|
|||
* amdgpu_vm_flush - hardware flush the vm
|
||||
*
|
||||
* @ring: ring to use for flush
|
||||
* @vm_id: vmid number to use
|
||||
* @vmid: vmid number to use
|
||||
* @pd_addr: address of the page directory
|
||||
*
|
||||
* Emit a VM flush when it is necessary.
|
||||
|
@ -807,8 +481,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
|
|||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
unsigned vmhub = ring->funcs->vmhub;
|
||||
struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct amdgpu_vm_id *id = &id_mgr->ids[job->vm_id];
|
||||
struct amdgpu_vmid_mgr *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct amdgpu_vmid *id = &id_mgr->ids[job->vmid];
|
||||
bool gds_switch_needed = ring->funcs->emit_gds_switch && (
|
||||
id->gds_base != job->gds_base ||
|
||||
id->gds_size != job->gds_size ||
|
||||
|
@ -820,7 +494,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
|
|||
unsigned patch_offset = 0;
|
||||
int r;
|
||||
|
||||
if (amdgpu_vm_had_gpu_reset(adev, id)) {
|
||||
if (amdgpu_vmid_had_gpu_reset(adev, id)) {
|
||||
gds_switch_needed = true;
|
||||
vm_flush_needed = true;
|
||||
}
|
||||
|
@ -837,8 +511,8 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
|
|||
if (ring->funcs->emit_vm_flush && vm_flush_needed) {
|
||||
struct dma_fence *fence;
|
||||
|
||||
trace_amdgpu_vm_flush(ring, job->vm_id, job->vm_pd_addr);
|
||||
amdgpu_ring_emit_vm_flush(ring, job->vm_id, job->vm_pd_addr);
|
||||
trace_amdgpu_vm_flush(ring, job->vmid, job->vm_pd_addr);
|
||||
amdgpu_ring_emit_vm_flush(ring, job->vmid, job->vm_pd_addr);
|
||||
|
||||
r = amdgpu_fence_emit(ring, &fence);
|
||||
if (r)
|
||||
|
@ -858,7 +532,7 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
|
|||
id->gws_size = job->gws_size;
|
||||
id->oa_base = job->oa_base;
|
||||
id->oa_size = job->oa_size;
|
||||
amdgpu_ring_emit_gds_switch(ring, job->vm_id, job->gds_base,
|
||||
amdgpu_ring_emit_gds_switch(ring, job->vmid, job->gds_base,
|
||||
job->gds_size, job->gws_base,
|
||||
job->gws_size, job->oa_base,
|
||||
job->oa_size);
|
||||
|
@ -875,49 +549,6 @@ int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_reset_id - reset VMID to zero
|
||||
*
|
||||
* @adev: amdgpu device structure
|
||||
* @vm_id: vmid number to use
|
||||
*
|
||||
* Reset saved GDW, GWS and OA to force switch on next flush.
|
||||
*/
|
||||
void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub,
|
||||
unsigned vmid)
|
||||
{
|
||||
struct amdgpu_vm_id_manager *id_mgr = &adev->vm_manager.id_mgr[vmhub];
|
||||
struct amdgpu_vm_id *id = &id_mgr->ids[vmid];
|
||||
|
||||
atomic64_set(&id->owner, 0);
|
||||
id->gds_base = 0;
|
||||
id->gds_size = 0;
|
||||
id->gws_base = 0;
|
||||
id->gws_size = 0;
|
||||
id->oa_base = 0;
|
||||
id->oa_size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_reset_all_id - reset VMID to zero
|
||||
*
|
||||
* @adev: amdgpu device structure
|
||||
*
|
||||
* Reset VMID to force flush on next use
|
||||
*/
|
||||
void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
|
||||
struct amdgpu_vm_id_manager *id_mgr =
|
||||
&adev->vm_manager.id_mgr[i];
|
||||
|
||||
for (j = 1; j < id_mgr->num_ids; ++j)
|
||||
amdgpu_vm_reset_id(adev, i, j);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_bo_find - find the bo_va for a specific vm & bo
|
||||
*
|
||||
|
@ -1569,13 +1200,19 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev,
|
|||
*
|
||||
* The second command is for the shadow pagetables.
|
||||
*/
|
||||
ncmds = ((nptes >> min(adev->vm_manager.block_size, 11u)) + 1) * 2;
|
||||
if (vm->root.base.bo->shadow)
|
||||
ncmds = ((nptes >> min(adev->vm_manager.block_size, 11u)) + 1) * 2;
|
||||
else
|
||||
ncmds = ((nptes >> min(adev->vm_manager.block_size, 11u)) + 1);
|
||||
|
||||
/* padding, etc. */
|
||||
ndw = 64;
|
||||
|
||||
/* one PDE write for each huge page */
|
||||
ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 6;
|
||||
if (vm->root.base.bo->shadow)
|
||||
ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 6 * 2;
|
||||
else
|
||||
ndw += ((nptes >> adev->vm_manager.block_size) + 1) * 6;
|
||||
|
||||
if (pages_addr) {
|
||||
/* copy commands needed */
|
||||
|
@ -2114,8 +1751,26 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
|
|||
INIT_LIST_HEAD(&bo_va->valids);
|
||||
INIT_LIST_HEAD(&bo_va->invalids);
|
||||
|
||||
if (bo)
|
||||
list_add_tail(&bo_va->base.bo_list, &bo->va);
|
||||
if (!bo)
|
||||
return bo_va;
|
||||
|
||||
list_add_tail(&bo_va->base.bo_list, &bo->va);
|
||||
|
||||
if (bo->tbo.resv != vm->root.base.bo->tbo.resv)
|
||||
return bo_va;
|
||||
|
||||
if (bo->preferred_domains &
|
||||
amdgpu_mem_type_to_domain(bo->tbo.mem.mem_type))
|
||||
return bo_va;
|
||||
|
||||
/*
|
||||
* We checked all the prerequisites, but it looks like this per VM BO
|
||||
* is currently evicted. add the BO to the evicted list to make sure it
|
||||
* is validated on next VM use to avoid fault.
|
||||
* */
|
||||
spin_lock(&vm->status_lock);
|
||||
list_move_tail(&bo_va->base.vm_status, &vm->evicted);
|
||||
spin_unlock(&vm->status_lock);
|
||||
|
||||
return bo_va;
|
||||
}
|
||||
|
@ -2625,7 +2280,6 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
uint64_t init_pde_value = 0;
|
||||
|
||||
vm->va = RB_ROOT_CACHED;
|
||||
vm->client_id = atomic64_inc_return(&adev->vm_manager.client_counter);
|
||||
for (i = 0; i < AMDGPU_MAX_VMHUBS; i++)
|
||||
vm->reserved_vmid[i] = NULL;
|
||||
spin_lock_init(&vm->status_lock);
|
||||
|
@ -2819,7 +2473,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
|
|||
amdgpu_bo_unref(&root);
|
||||
dma_fence_put(vm->last_update);
|
||||
for (i = 0; i < AMDGPU_MAX_VMHUBS; i++)
|
||||
amdgpu_vm_free_reserved_vmid(adev, vm, i);
|
||||
amdgpu_vmid_free_reserved(adev, vm, i);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2861,23 +2515,9 @@ bool amdgpu_vm_pasid_fault_credit(struct amdgpu_device *adev,
|
|||
*/
|
||||
void amdgpu_vm_manager_init(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned i, j;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
|
||||
struct amdgpu_vm_id_manager *id_mgr =
|
||||
&adev->vm_manager.id_mgr[i];
|
||||
|
||||
mutex_init(&id_mgr->lock);
|
||||
INIT_LIST_HEAD(&id_mgr->ids_lru);
|
||||
atomic_set(&id_mgr->reserved_vmid_num, 0);
|
||||
|
||||
/* skip over VMID 0, since it is the system VM */
|
||||
for (j = 1; j < id_mgr->num_ids; ++j) {
|
||||
amdgpu_vm_reset_id(adev, i, j);
|
||||
amdgpu_sync_create(&id_mgr->ids[i].active);
|
||||
list_add_tail(&id_mgr->ids[j].list, &id_mgr->ids_lru);
|
||||
}
|
||||
}
|
||||
amdgpu_vmid_mgr_init(adev);
|
||||
|
||||
adev->vm_manager.fence_context =
|
||||
dma_fence_context_alloc(AMDGPU_MAX_RINGS);
|
||||
|
@ -2885,7 +2525,6 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
|
|||
adev->vm_manager.seqno[i] = 0;
|
||||
|
||||
atomic_set(&adev->vm_manager.vm_pte_next_ring, 0);
|
||||
atomic64_set(&adev->vm_manager.client_counter, 0);
|
||||
spin_lock_init(&adev->vm_manager.prt_lock);
|
||||
atomic_set(&adev->vm_manager.num_prt_users, 0);
|
||||
|
||||
|
@ -2918,24 +2557,10 @@ void amdgpu_vm_manager_init(struct amdgpu_device *adev)
|
|||
*/
|
||||
void amdgpu_vm_manager_fini(struct amdgpu_device *adev)
|
||||
{
|
||||
unsigned i, j;
|
||||
|
||||
WARN_ON(!idr_is_empty(&adev->vm_manager.pasid_idr));
|
||||
idr_destroy(&adev->vm_manager.pasid_idr);
|
||||
|
||||
for (i = 0; i < AMDGPU_MAX_VMHUBS; ++i) {
|
||||
struct amdgpu_vm_id_manager *id_mgr =
|
||||
&adev->vm_manager.id_mgr[i];
|
||||
|
||||
mutex_destroy(&id_mgr->lock);
|
||||
for (j = 0; j < AMDGPU_NUM_VM; ++j) {
|
||||
struct amdgpu_vm_id *id = &id_mgr->ids[j];
|
||||
|
||||
amdgpu_sync_free(&id->active);
|
||||
dma_fence_put(id->flushed_updates);
|
||||
dma_fence_put(id->last_flush);
|
||||
}
|
||||
}
|
||||
amdgpu_vmid_mgr_fini(adev);
|
||||
}
|
||||
|
||||
int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
||||
|
@ -2948,13 +2573,12 @@ int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|||
switch (args->in.op) {
|
||||
case AMDGPU_VM_OP_RESERVE_VMID:
|
||||
/* current, we only have requirement to reserve vmid from gfxhub */
|
||||
r = amdgpu_vm_alloc_reserved_vmid(adev, &fpriv->vm,
|
||||
AMDGPU_GFXHUB);
|
||||
r = amdgpu_vmid_alloc_reserved(adev, &fpriv->vm, AMDGPU_GFXHUB);
|
||||
if (r)
|
||||
return r;
|
||||
break;
|
||||
case AMDGPU_VM_OP_UNRESERVE_VMID:
|
||||
amdgpu_vm_free_reserved_vmid(adev, &fpriv->vm, AMDGPU_GFXHUB);
|
||||
amdgpu_vmid_free_reserved(adev, &fpriv->vm, AMDGPU_GFXHUB);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "amdgpu_sync.h"
|
||||
#include "amdgpu_ring.h"
|
||||
#include "amdgpu_ids.h"
|
||||
|
||||
struct amdgpu_bo_va;
|
||||
struct amdgpu_job;
|
||||
|
@ -40,9 +41,6 @@ struct amdgpu_bo_list_entry;
|
|||
* GPUVM handling
|
||||
*/
|
||||
|
||||
/* maximum number of VMIDs */
|
||||
#define AMDGPU_NUM_VM 16
|
||||
|
||||
/* Maximum number of PTEs the hardware can write with one command */
|
||||
#define AMDGPU_VM_MAX_UPDATE_SIZE 0x3FFFF
|
||||
|
||||
|
@ -193,11 +191,9 @@ struct amdgpu_vm {
|
|||
/* Scheduler entity for page table updates */
|
||||
struct drm_sched_entity entity;
|
||||
|
||||
/* client id and PASID (TODO: replace client_id with PASID) */
|
||||
u64 client_id;
|
||||
unsigned int pasid;
|
||||
/* dedicated to vm */
|
||||
struct amdgpu_vm_id *reserved_vmid[AMDGPU_MAX_VMHUBS];
|
||||
struct amdgpu_vmid *reserved_vmid[AMDGPU_MAX_VMHUBS];
|
||||
|
||||
/* Flag to indicate if VM tables are updated by CPU or GPU (SDMA) */
|
||||
bool use_cpu_for_update;
|
||||
|
@ -212,37 +208,9 @@ struct amdgpu_vm {
|
|||
unsigned int fault_credit;
|
||||
};
|
||||
|
||||
struct amdgpu_vm_id {
|
||||
struct list_head list;
|
||||
struct amdgpu_sync active;
|
||||
struct dma_fence *last_flush;
|
||||
atomic64_t owner;
|
||||
|
||||
uint64_t pd_gpu_addr;
|
||||
/* last flushed PD/PT update */
|
||||
struct dma_fence *flushed_updates;
|
||||
|
||||
uint32_t current_gpu_reset_count;
|
||||
|
||||
uint32_t gds_base;
|
||||
uint32_t gds_size;
|
||||
uint32_t gws_base;
|
||||
uint32_t gws_size;
|
||||
uint32_t oa_base;
|
||||
uint32_t oa_size;
|
||||
};
|
||||
|
||||
struct amdgpu_vm_id_manager {
|
||||
struct mutex lock;
|
||||
unsigned num_ids;
|
||||
struct list_head ids_lru;
|
||||
struct amdgpu_vm_id ids[AMDGPU_NUM_VM];
|
||||
atomic_t reserved_vmid_num;
|
||||
};
|
||||
|
||||
struct amdgpu_vm_manager {
|
||||
/* Handling of VMIDs */
|
||||
struct amdgpu_vm_id_manager id_mgr[AMDGPU_MAX_VMHUBS];
|
||||
struct amdgpu_vmid_mgr id_mgr[AMDGPU_MAX_VMHUBS];
|
||||
|
||||
/* Handling of VM fences */
|
||||
u64 fence_context;
|
||||
|
@ -260,8 +228,6 @@ struct amdgpu_vm_manager {
|
|||
struct amdgpu_ring *vm_pte_rings[AMDGPU_MAX_RINGS];
|
||||
unsigned vm_pte_num_rings;
|
||||
atomic_t vm_pte_next_ring;
|
||||
/* client id counter */
|
||||
atomic64_t client_counter;
|
||||
|
||||
/* partial resident texture handling */
|
||||
spinlock_t prt_lock;
|
||||
|
@ -280,8 +246,6 @@ struct amdgpu_vm_manager {
|
|||
spinlock_t pasid_lock;
|
||||
};
|
||||
|
||||
int amdgpu_vm_alloc_pasid(unsigned int bits);
|
||||
void amdgpu_vm_free_pasid(unsigned int pasid);
|
||||
void amdgpu_vm_manager_init(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,
|
||||
|
@ -299,13 +263,7 @@ int amdgpu_vm_validate_pt_bos(struct amdgpu_device *adev, struct amdgpu_vm *vm,
|
|||
int amdgpu_vm_alloc_pts(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm,
|
||||
uint64_t saddr, uint64_t size);
|
||||
int amdgpu_vm_grab_id(struct amdgpu_vm *vm, struct amdgpu_ring *ring,
|
||||
struct amdgpu_sync *sync, struct dma_fence *fence,
|
||||
struct amdgpu_job *job);
|
||||
int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
|
||||
void amdgpu_vm_reset_id(struct amdgpu_device *adev, unsigned vmhub,
|
||||
unsigned vmid);
|
||||
void amdgpu_vm_reset_all_ids(struct amdgpu_device *adev);
|
||||
int amdgpu_vm_update_directories(struct amdgpu_device *adev,
|
||||
struct amdgpu_vm *vm);
|
||||
int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
|
||||
|
|
|
@ -280,7 +280,7 @@ static void cik_ih_decode_iv(struct amdgpu_device *adev,
|
|||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
entry->vm_id = (dw[2] >> 8) & 0xff;
|
||||
entry->vmid = (dw[2] >> 8) & 0xff;
|
||||
entry->pas_id = (dw[2] >> 16) & 0xffff;
|
||||
|
||||
/* wptr/rptr are in bytes! */
|
||||
|
|
|
@ -221,9 +221,9 @@ static void cik_sdma_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
|
|||
*/
|
||||
static void cik_sdma_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 extra_bits = vm_id & 0xf;
|
||||
u32 extra_bits = vmid & 0xf;
|
||||
|
||||
/* IB packet must end on a 8 DW boundary */
|
||||
cik_sdma_ring_insert_nop(ring, (12 - (lower_32_bits(ring->wptr) & 7)) % 8);
|
||||
|
@ -880,23 +880,23 @@ static void cik_sdma_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
* using sDMA (CIK).
|
||||
*/
|
||||
static void cik_sdma_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
u32 extra_bits = (SDMA_POLL_REG_MEM_EXTRA_OP(0) |
|
||||
SDMA_POLL_REG_MEM_EXTRA_FUNC(0)); /* always */
|
||||
|
||||
amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
|
||||
if (vm_id < 8) {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vm_id));
|
||||
if (vmid < 8) {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vmid));
|
||||
} else {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vm_id - 8));
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8));
|
||||
}
|
||||
amdgpu_ring_write(ring, pd_addr >> 12);
|
||||
|
||||
/* flush TLB */
|
||||
amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_SRBM_WRITE, 0, 0xf000));
|
||||
amdgpu_ring_write(ring, mmVM_INVALIDATE_REQUEST);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
|
||||
amdgpu_ring_write(ring, SDMA_PACKET(SDMA_OPCODE_POLL_REG_MEM, 0, extra_bits));
|
||||
amdgpu_ring_write(ring, mmVM_INVALIDATE_REQUEST << 2);
|
||||
|
|
|
@ -259,7 +259,7 @@ static void cz_ih_decode_iv(struct amdgpu_device *adev,
|
|||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
entry->vm_id = (dw[2] >> 8) & 0xff;
|
||||
entry->vmid = (dw[2] >> 8) & 0xff;
|
||||
entry->pas_id = (dw[2] >> 16) & 0xffff;
|
||||
|
||||
/* wptr/rptr are in bytes! */
|
||||
|
|
|
@ -1874,7 +1874,7 @@ static void gfx_v6_0_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,
|
|||
|
||||
static void gfx_v6_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 header, control = 0;
|
||||
|
||||
|
@ -1889,7 +1889,7 @@ static void gfx_v6_0_ring_emit_ib(struct amdgpu_ring *ring,
|
|||
else
|
||||
header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
|
||||
|
||||
control |= ib->length_dw | (vm_id << 24);
|
||||
control |= ib->length_dw | (vmid << 24);
|
||||
|
||||
amdgpu_ring_write(ring, header);
|
||||
amdgpu_ring_write(ring,
|
||||
|
@ -2354,7 +2354,7 @@ static void gfx_v6_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
static void gfx_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
|
||||
|
||||
|
@ -2362,10 +2362,10 @@ static void gfx_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
|
||||
amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
|
||||
WRITE_DATA_DST_SEL(0)));
|
||||
if (vm_id < 8) {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vm_id ));
|
||||
if (vmid < 8) {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vmid ));
|
||||
} else {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + (vm_id - 8)));
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + (vmid - 8)));
|
||||
}
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, pd_addr >> 12);
|
||||
|
@ -2376,7 +2376,7 @@ static void gfx_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
WRITE_DATA_DST_SEL(0)));
|
||||
amdgpu_ring_write(ring, mmVM_INVALIDATE_REQUEST);
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
|
||||
/* wait for the invalidate to complete */
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
|
||||
|
|
|
@ -2254,7 +2254,7 @@ static void gfx_v7_0_ring_emit_fence_compute(struct amdgpu_ring *ring,
|
|||
*/
|
||||
static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 header, control = 0;
|
||||
|
||||
|
@ -2269,7 +2269,7 @@ static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
|||
else
|
||||
header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
|
||||
|
||||
control |= ib->length_dw | (vm_id << 24);
|
||||
control |= ib->length_dw | (vmid << 24);
|
||||
|
||||
amdgpu_ring_write(ring, header);
|
||||
amdgpu_ring_write(ring,
|
||||
|
@ -2283,9 +2283,9 @@ static void gfx_v7_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
|||
|
||||
static void gfx_v7_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vm_id << 24);
|
||||
u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24);
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
|
||||
amdgpu_ring_write(ring,
|
||||
|
@ -3239,19 +3239,19 @@ static void gfx_v7_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
* using the CP (CIK).
|
||||
*/
|
||||
static void gfx_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
|
||||
amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) |
|
||||
WRITE_DATA_DST_SEL(0)));
|
||||
if (vm_id < 8) {
|
||||
if (vmid < 8) {
|
||||
amdgpu_ring_write(ring,
|
||||
(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vm_id));
|
||||
(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vmid));
|
||||
} else {
|
||||
amdgpu_ring_write(ring,
|
||||
(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vm_id - 8));
|
||||
(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8));
|
||||
}
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, pd_addr >> 12);
|
||||
|
@ -3262,7 +3262,7 @@ static void gfx_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
WRITE_DATA_DST_SEL(0)));
|
||||
amdgpu_ring_write(ring, mmVM_INVALIDATE_REQUEST);
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
|
||||
/* wait for the invalidate to complete */
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
|
||||
|
|
|
@ -6245,7 +6245,7 @@ static void gfx_v8_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring)
|
|||
|
||||
static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 header, control = 0;
|
||||
|
||||
|
@ -6254,7 +6254,7 @@ static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
|||
else
|
||||
header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
|
||||
|
||||
control |= ib->length_dw | (vm_id << 24);
|
||||
control |= ib->length_dw | (vmid << 24);
|
||||
|
||||
if (amdgpu_sriov_vf(ring->adev) && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) {
|
||||
control |= INDIRECT_BUFFER_PRE_ENB(1);
|
||||
|
@ -6275,9 +6275,9 @@ static void gfx_v8_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
|||
|
||||
static void gfx_v8_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vm_id << 24);
|
||||
u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24);
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
|
||||
amdgpu_ring_write(ring,
|
||||
|
@ -6328,7 +6328,7 @@ static void gfx_v8_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
|
||||
|
||||
|
@ -6336,12 +6336,12 @@ static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
amdgpu_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) |
|
||||
WRITE_DATA_DST_SEL(0)) |
|
||||
WR_CONFIRM);
|
||||
if (vm_id < 8) {
|
||||
if (vmid < 8) {
|
||||
amdgpu_ring_write(ring,
|
||||
(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vm_id));
|
||||
(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vmid));
|
||||
} else {
|
||||
amdgpu_ring_write(ring,
|
||||
(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vm_id - 8));
|
||||
(mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8));
|
||||
}
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, pd_addr >> 12);
|
||||
|
@ -6353,7 +6353,7 @@ static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
WRITE_DATA_DST_SEL(0)));
|
||||
amdgpu_ring_write(ring, mmVM_INVALIDATE_REQUEST);
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
|
||||
/* wait for the invalidate to complete */
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
|
||||
|
|
|
@ -3594,7 +3594,7 @@ static void gfx_v9_0_ring_emit_hdp_invalidate(struct amdgpu_ring *ring)
|
|||
|
||||
static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 header, control = 0;
|
||||
|
||||
|
@ -3603,7 +3603,7 @@ static void gfx_v9_0_ring_emit_ib_gfx(struct amdgpu_ring *ring,
|
|||
else
|
||||
header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
|
||||
|
||||
control |= ib->length_dw | (vm_id << 24);
|
||||
control |= ib->length_dw | (vmid << 24);
|
||||
|
||||
if (amdgpu_sriov_vf(ring->adev) && (ib->flags & AMDGPU_IB_FLAG_PREEMPT)) {
|
||||
control |= INDIRECT_BUFFER_PRE_ENB(1);
|
||||
|
@ -3625,9 +3625,9 @@ BUG_ON(ib->gpu_addr & 0x3); /* Dword align */
|
|||
|
||||
static void gfx_v9_0_ring_emit_ib_compute(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vm_id << 24);
|
||||
u32 control = INDIRECT_BUFFER_VALID | ib->length_dw | (vmid << 24);
|
||||
|
||||
amdgpu_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
|
||||
BUG_ON(ib->gpu_addr & 0x3); /* Dword align */
|
||||
|
@ -3683,11 +3683,11 @@ static void gfx_v9_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
static void gfx_v9_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
|
||||
int usepfp = (ring->funcs->type == AMDGPU_RING_TYPE_GFX);
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vm_id);
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vmid);
|
||||
uint64_t flags = AMDGPU_PTE_VALID;
|
||||
unsigned eng = ring->vm_inv_eng;
|
||||
|
||||
|
@ -3695,11 +3695,11 @@ static void gfx_v9_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
pd_addr |= flags;
|
||||
|
||||
gfx_v9_0_write_data_to_reg(ring, usepfp, true,
|
||||
hub->ctx0_ptb_addr_lo32 + (2 * vm_id),
|
||||
hub->ctx0_ptb_addr_lo32 + (2 * vmid),
|
||||
lower_32_bits(pd_addr));
|
||||
|
||||
gfx_v9_0_write_data_to_reg(ring, usepfp, true,
|
||||
hub->ctx0_ptb_addr_hi32 + (2 * vm_id),
|
||||
hub->ctx0_ptb_addr_hi32 + (2 * vmid),
|
||||
upper_32_bits(pd_addr));
|
||||
|
||||
gfx_v9_0_write_data_to_reg(ring, usepfp, true,
|
||||
|
@ -3707,7 +3707,7 @@ static void gfx_v9_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
|
||||
/* wait for the invalidate to complete */
|
||||
gfx_v9_0_wait_reg_mem(ring, 0, 0, 0, hub->vm_inv_eng0_ack +
|
||||
eng, 0, 1 << vm_id, 1 << vm_id, 0x20);
|
||||
eng, 0, 1 << vmid, 1 << vmid, 0x20);
|
||||
|
||||
/* compute doesn't have PFP */
|
||||
if (usepfp) {
|
||||
|
|
|
@ -956,7 +956,7 @@ static int gmc_v6_0_resume(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_vm_reset_all_ids(adev);
|
||||
amdgpu_vmid_reset_all(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1107,7 +1107,7 @@ static int gmc_v7_0_resume(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_vm_reset_all_ids(adev);
|
||||
amdgpu_vmid_reset_all(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1212,7 +1212,7 @@ static int gmc_v8_0_resume(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_vm_reset_all_ids(adev);
|
||||
amdgpu_vmid_reset_all(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -248,7 +248,7 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
|
|||
struct amdgpu_irq_src *source,
|
||||
struct amdgpu_iv_entry *entry)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[entry->vm_id_src];
|
||||
struct amdgpu_vmhub *hub = &adev->vmhub[entry->vmid_src];
|
||||
uint32_t status = 0;
|
||||
u64 addr;
|
||||
|
||||
|
@ -262,9 +262,9 @@ static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
|
|||
|
||||
if (printk_ratelimit()) {
|
||||
dev_err(adev->dev,
|
||||
"[%s] VMC page fault (src_id:%u ring:%u vm_id:%u pas_id:%u)\n",
|
||||
entry->vm_id_src ? "mmhub" : "gfxhub",
|
||||
entry->src_id, entry->ring_id, entry->vm_id,
|
||||
"[%s] VMC page fault (src_id:%u ring:%u vmid:%u pas_id:%u)\n",
|
||||
entry->vmid_src ? "mmhub" : "gfxhub",
|
||||
entry->src_id, entry->ring_id, entry->vmid,
|
||||
entry->pas_id);
|
||||
dev_err(adev->dev, " at page 0x%016llx from %d\n",
|
||||
addr, entry->client_id);
|
||||
|
@ -288,13 +288,13 @@ static void gmc_v9_0_set_irq_funcs(struct amdgpu_device *adev)
|
|||
adev->mc.vm_fault.funcs = &gmc_v9_0_irq_funcs;
|
||||
}
|
||||
|
||||
static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vm_id)
|
||||
static uint32_t gmc_v9_0_get_invalidate_req(unsigned int vmid)
|
||||
{
|
||||
u32 req = 0;
|
||||
|
||||
/* invalidate using legacy mode on vm_id*/
|
||||
/* invalidate using legacy mode on vmid*/
|
||||
req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ,
|
||||
PER_VMID_INVALIDATE_REQ, 1 << vm_id);
|
||||
PER_VMID_INVALIDATE_REQ, 1 << vmid);
|
||||
req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, FLUSH_TYPE, 0);
|
||||
req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PTES, 1);
|
||||
req = REG_SET_FIELD(req, VM_INVALIDATE_ENG0_REQ, INVALIDATE_L2_PDE0, 1);
|
||||
|
@ -1056,7 +1056,7 @@ static int gmc_v9_0_resume(void *handle)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
amdgpu_vm_reset_all_ids(adev);
|
||||
amdgpu_vmid_reset_all(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ static void iceland_ih_decode_iv(struct amdgpu_device *adev,
|
|||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
entry->vm_id = (dw[2] >> 8) & 0xff;
|
||||
entry->vmid = (dw[2] >> 8) & 0xff;
|
||||
entry->pas_id = (dw[2] >> 16) & 0xffff;
|
||||
|
||||
/* wptr/rptr are in bytes! */
|
||||
|
|
|
@ -246,15 +246,13 @@ static void sdma_v2_4_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
|
|||
*/
|
||||
static void sdma_v2_4_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 vmid = vm_id & 0xf;
|
||||
|
||||
/* IB packet must end on a 8 DW boundary */
|
||||
sdma_v2_4_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8);
|
||||
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_INDIRECT) |
|
||||
SDMA_PKT_INDIRECT_HEADER_VMID(vmid));
|
||||
SDMA_PKT_INDIRECT_HEADER_VMID(vmid & 0xf));
|
||||
/* base must be 32 byte aligned */
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr) & 0xffffffe0);
|
||||
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
|
||||
|
@ -861,14 +859,14 @@ static void sdma_v2_4_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
* using sDMA (VI).
|
||||
*/
|
||||
static void sdma_v2_4_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) |
|
||||
SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf));
|
||||
if (vm_id < 8) {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vm_id));
|
||||
if (vmid < 8) {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vmid));
|
||||
} else {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vm_id - 8));
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8));
|
||||
}
|
||||
amdgpu_ring_write(ring, pd_addr >> 12);
|
||||
|
||||
|
@ -876,7 +874,7 @@ static void sdma_v2_4_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) |
|
||||
SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf));
|
||||
amdgpu_ring_write(ring, mmVM_INVALIDATE_REQUEST);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
|
||||
/* wait for flush */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) |
|
||||
|
|
|
@ -417,15 +417,13 @@ static void sdma_v3_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
|
|||
*/
|
||||
static void sdma_v3_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 vmid = vm_id & 0xf;
|
||||
|
||||
/* IB packet must end on a 8 DW boundary */
|
||||
sdma_v3_0_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8);
|
||||
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_INDIRECT) |
|
||||
SDMA_PKT_INDIRECT_HEADER_VMID(vmid));
|
||||
SDMA_PKT_INDIRECT_HEADER_VMID(vmid & 0xf));
|
||||
/* base must be 32 byte aligned */
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr) & 0xffffffe0);
|
||||
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
|
||||
|
@ -1127,14 +1125,14 @@ static void sdma_v3_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
* using sDMA (VI).
|
||||
*/
|
||||
static void sdma_v3_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) |
|
||||
SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf));
|
||||
if (vm_id < 8) {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vm_id));
|
||||
if (vmid < 8) {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vmid));
|
||||
} else {
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vm_id - 8));
|
||||
amdgpu_ring_write(ring, (mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8));
|
||||
}
|
||||
amdgpu_ring_write(ring, pd_addr >> 12);
|
||||
|
||||
|
@ -1142,7 +1140,7 @@ static void sdma_v3_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) |
|
||||
SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf));
|
||||
amdgpu_ring_write(ring, mmVM_INVALIDATE_REQUEST);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
|
||||
/* wait for flush */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_POLL_REGMEM) |
|
||||
|
|
|
@ -330,15 +330,13 @@ static void sdma_v4_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
|
|||
*/
|
||||
static void sdma_v4_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
u32 vmid = vm_id & 0xf;
|
||||
|
||||
/* IB packet must end on a 8 DW boundary */
|
||||
sdma_v4_0_ring_insert_nop(ring, (10 - (lower_32_bits(ring->wptr) & 7)) % 8);
|
||||
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_INDIRECT) |
|
||||
SDMA_PKT_INDIRECT_HEADER_VMID(vmid));
|
||||
SDMA_PKT_INDIRECT_HEADER_VMID(vmid & 0xf));
|
||||
/* base must be 32 byte aligned */
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr) & 0xffffffe0);
|
||||
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
|
||||
|
@ -1135,10 +1133,10 @@ static void sdma_v4_0_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
* using sDMA (VEGA10).
|
||||
*/
|
||||
static void sdma_v4_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vm_id);
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vmid);
|
||||
uint64_t flags = AMDGPU_PTE_VALID;
|
||||
unsigned eng = ring->vm_inv_eng;
|
||||
|
||||
|
@ -1147,12 +1145,12 @@ static void sdma_v4_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) |
|
||||
SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf));
|
||||
amdgpu_ring_write(ring, hub->ctx0_ptb_addr_lo32 + vm_id * 2);
|
||||
amdgpu_ring_write(ring, hub->ctx0_ptb_addr_lo32 + vmid * 2);
|
||||
amdgpu_ring_write(ring, lower_32_bits(pd_addr));
|
||||
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_SRBM_WRITE) |
|
||||
SDMA_PKT_SRBM_WRITE_HEADER_BYTE_EN(0xf));
|
||||
amdgpu_ring_write(ring, hub->ctx0_ptb_addr_hi32 + vm_id * 2);
|
||||
amdgpu_ring_write(ring, hub->ctx0_ptb_addr_hi32 + vmid * 2);
|
||||
amdgpu_ring_write(ring, upper_32_bits(pd_addr));
|
||||
|
||||
/* flush TLB */
|
||||
|
@ -1167,8 +1165,8 @@ static void sdma_v4_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
SDMA_PKT_POLL_REGMEM_HEADER_FUNC(3)); /* equal */
|
||||
amdgpu_ring_write(ring, (hub->vm_inv_eng0_ack + eng) << 2);
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, 1 << vm_id); /* reference */
|
||||
amdgpu_ring_write(ring, 1 << vm_id); /* mask */
|
||||
amdgpu_ring_write(ring, 1 << vmid); /* reference */
|
||||
amdgpu_ring_write(ring, 1 << vmid); /* mask */
|
||||
amdgpu_ring_write(ring, SDMA_PKT_POLL_REGMEM_DW5_RETRY_COUNT(0xfff) |
|
||||
SDMA_PKT_POLL_REGMEM_DW5_INTERVAL(10));
|
||||
}
|
||||
|
|
|
@ -61,14 +61,14 @@ static void si_dma_ring_set_wptr(struct amdgpu_ring *ring)
|
|||
|
||||
static void si_dma_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
/* The indirect buffer packet must end on an 8 DW boundary in the DMA ring.
|
||||
* Pad as necessary with NOPs.
|
||||
*/
|
||||
while ((lower_32_bits(ring->wptr) & 7) != 5)
|
||||
amdgpu_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
|
||||
amdgpu_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, vm_id, 0));
|
||||
amdgpu_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, vmid, 0));
|
||||
amdgpu_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0));
|
||||
amdgpu_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF));
|
||||
|
||||
|
@ -473,25 +473,25 @@ static void si_dma_ring_emit_pipeline_sync(struct amdgpu_ring *ring)
|
|||
* using sDMA (VI).
|
||||
*/
|
||||
static void si_dma_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
amdgpu_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0));
|
||||
if (vm_id < 8)
|
||||
amdgpu_ring_write(ring, (0xf << 16) | (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vm_id));
|
||||
if (vmid < 8)
|
||||
amdgpu_ring_write(ring, (0xf << 16) | (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vmid));
|
||||
else
|
||||
amdgpu_ring_write(ring, (0xf << 16) | (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + (vm_id - 8)));
|
||||
amdgpu_ring_write(ring, (0xf << 16) | (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + (vmid - 8)));
|
||||
amdgpu_ring_write(ring, pd_addr >> 12);
|
||||
|
||||
/* bits 0-7 are the VM contexts0-7 */
|
||||
amdgpu_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0, 0));
|
||||
amdgpu_ring_write(ring, (0xf << 16) | (VM_INVALIDATE_REQUEST));
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
|
||||
/* wait for invalidate to complete */
|
||||
amdgpu_ring_write(ring, DMA_PACKET(DMA_PACKET_POLL_REG_MEM, 0, 0, 0, 0));
|
||||
amdgpu_ring_write(ring, VM_INVALIDATE_REQUEST);
|
||||
amdgpu_ring_write(ring, 0xff << 16); /* retry */
|
||||
amdgpu_ring_write(ring, 1 << vm_id); /* mask */
|
||||
amdgpu_ring_write(ring, 1 << vmid); /* mask */
|
||||
amdgpu_ring_write(ring, 0); /* value */
|
||||
amdgpu_ring_write(ring, (0 << 28) | 0x20); /* func(always) | poll interval */
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ static void si_ih_decode_iv(struct amdgpu_device *adev,
|
|||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
entry->vm_id = (dw[2] >> 8) & 0xff;
|
||||
entry->vmid = (dw[2] >> 8) & 0xff;
|
||||
|
||||
adev->irq.ih.rptr += 16;
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ static void tonga_ih_decode_iv(struct amdgpu_device *adev,
|
|||
entry->src_id = dw[0] & 0xff;
|
||||
entry->src_data[0] = dw[1] & 0xfffffff;
|
||||
entry->ring_id = dw[2] & 0xff;
|
||||
entry->vm_id = (dw[2] >> 8) & 0xff;
|
||||
entry->vmid = (dw[2] >> 8) & 0xff;
|
||||
entry->pas_id = (dw[2] >> 16) & 0xffff;
|
||||
|
||||
/* wptr/rptr are in bytes! */
|
||||
|
|
|
@ -541,7 +541,7 @@ static int uvd_v4_2_ring_test_ring(struct amdgpu_ring *ring)
|
|||
*/
|
||||
static void uvd_v4_2_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_RBC_IB_BASE, 0));
|
||||
amdgpu_ring_write(ring, ib->gpu_addr);
|
||||
|
|
|
@ -556,7 +556,7 @@ static int uvd_v5_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
*/
|
||||
static void uvd_v5_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_64BIT_BAR_LOW, 0));
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
|
||||
|
|
|
@ -1028,10 +1028,10 @@ static int uvd_v6_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
*/
|
||||
static void uvd_v6_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_VMID, 0));
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_LMI_RBC_IB_64BIT_BAR_LOW, 0));
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
|
||||
|
@ -1050,24 +1050,24 @@ static void uvd_v6_0_ring_emit_ib(struct amdgpu_ring *ring,
|
|||
* Write enc ring commands to execute the indirect buffer
|
||||
*/
|
||||
static void uvd_v6_0_enc_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib, unsigned int vm_id, bool ctx_switch)
|
||||
struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch)
|
||||
{
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_IB_VM);
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, ib->length_dw);
|
||||
}
|
||||
|
||||
static void uvd_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
uint32_t reg;
|
||||
|
||||
if (vm_id < 8)
|
||||
reg = mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vm_id;
|
||||
if (vmid < 8)
|
||||
reg = mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR + vmid;
|
||||
else
|
||||
reg = mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vm_id - 8;
|
||||
reg = mmVM_CONTEXT8_PAGE_TABLE_BASE_ADDR + vmid - 8;
|
||||
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0));
|
||||
amdgpu_ring_write(ring, reg << 2);
|
||||
|
@ -1079,7 +1079,7 @@ static void uvd_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA0, 0));
|
||||
amdgpu_ring_write(ring, mmVM_INVALIDATE_REQUEST << 2);
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1, 0));
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD, 0));
|
||||
amdgpu_ring_write(ring, 0x8);
|
||||
|
||||
|
@ -1088,7 +1088,7 @@ static void uvd_v6_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_DATA1, 0));
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GP_SCRATCH8, 0));
|
||||
amdgpu_ring_write(ring, 1 << vm_id); /* mask */
|
||||
amdgpu_ring_write(ring, 1 << vmid); /* mask */
|
||||
amdgpu_ring_write(ring, PACKET0(mmUVD_GPCOM_VCPU_CMD, 0));
|
||||
amdgpu_ring_write(ring, 0xC);
|
||||
}
|
||||
|
@ -1127,14 +1127,14 @@ static void uvd_v6_0_enc_ring_insert_end(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
static void uvd_v6_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned int vm_id, uint64_t pd_addr)
|
||||
unsigned int vmid, uint64_t pd_addr)
|
||||
{
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_UPDATE_PTB);
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
amdgpu_ring_write(ring, pd_addr >> 12);
|
||||
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_FLUSH_TLB);
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
}
|
||||
|
||||
static bool uvd_v6_0_is_idle(void *handle)
|
||||
|
|
|
@ -1218,13 +1218,13 @@ static int uvd_v7_0_ring_test_ring(struct amdgpu_ring *ring)
|
|||
*/
|
||||
static void uvd_v7_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
amdgpu_ring_write(ring,
|
||||
PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0));
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
|
||||
amdgpu_ring_write(ring,
|
||||
PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0));
|
||||
|
@ -1246,10 +1246,10 @@ static void uvd_v7_0_ring_emit_ib(struct amdgpu_ring *ring,
|
|||
* Write enc ring commands to execute the indirect buffer
|
||||
*/
|
||||
static void uvd_v7_0_enc_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib, unsigned int vm_id, bool ctx_switch)
|
||||
struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch)
|
||||
{
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_IB_VM);
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, ib->length_dw);
|
||||
|
@ -1291,10 +1291,10 @@ static void uvd_v7_0_vm_reg_wait(struct amdgpu_ring *ring,
|
|||
}
|
||||
|
||||
static void uvd_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vm_id);
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vmid);
|
||||
uint64_t flags = AMDGPU_PTE_VALID;
|
||||
unsigned eng = ring->vm_inv_eng;
|
||||
uint32_t data0, data1, mask;
|
||||
|
@ -1302,15 +1302,15 @@ static void uvd_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
amdgpu_gart_get_vm_pde(ring->adev, -1, &pd_addr, &flags);
|
||||
pd_addr |= flags;
|
||||
|
||||
data0 = (hub->ctx0_ptb_addr_hi32 + vm_id * 2) << 2;
|
||||
data0 = (hub->ctx0_ptb_addr_hi32 + vmid * 2) << 2;
|
||||
data1 = upper_32_bits(pd_addr);
|
||||
uvd_v7_0_vm_reg_write(ring, data0, data1);
|
||||
|
||||
data0 = (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2;
|
||||
data0 = (hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2;
|
||||
data1 = lower_32_bits(pd_addr);
|
||||
uvd_v7_0_vm_reg_write(ring, data0, data1);
|
||||
|
||||
data0 = (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2;
|
||||
data0 = (hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2;
|
||||
data1 = lower_32_bits(pd_addr);
|
||||
mask = 0xffffffff;
|
||||
uvd_v7_0_vm_reg_wait(ring, data0, data1, mask);
|
||||
|
@ -1322,8 +1322,8 @@ static void uvd_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
|
||||
/* wait for flush */
|
||||
data0 = (hub->vm_inv_eng0_ack + eng) << 2;
|
||||
data1 = 1 << vm_id;
|
||||
mask = 1 << vm_id;
|
||||
data1 = 1 << vmid;
|
||||
mask = 1 << vmid;
|
||||
uvd_v7_0_vm_reg_wait(ring, data0, data1, mask);
|
||||
}
|
||||
|
||||
|
@ -1343,10 +1343,10 @@ static void uvd_v7_0_enc_ring_insert_end(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
static void uvd_v7_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned int vm_id, uint64_t pd_addr)
|
||||
unsigned int vmid, uint64_t pd_addr)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vm_id);
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vmid);
|
||||
uint64_t flags = AMDGPU_PTE_VALID;
|
||||
unsigned eng = ring->vm_inv_eng;
|
||||
|
||||
|
@ -1354,15 +1354,15 @@ static void uvd_v7_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
pd_addr |= flags;
|
||||
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_REG_WRITE);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_hi32 + vm_id * 2) << 2);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_hi32 + vmid * 2) << 2);
|
||||
amdgpu_ring_write(ring, upper_32_bits(pd_addr));
|
||||
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_REG_WRITE);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2);
|
||||
amdgpu_ring_write(ring, lower_32_bits(pd_addr));
|
||||
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_REG_WAIT);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2);
|
||||
amdgpu_ring_write(ring, 0xffffffff);
|
||||
amdgpu_ring_write(ring, lower_32_bits(pd_addr));
|
||||
|
||||
|
@ -1374,8 +1374,8 @@ static void uvd_v7_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
/* wait for flush */
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_REG_WAIT);
|
||||
amdgpu_ring_write(ring, (hub->vm_inv_eng0_ack + eng) << 2);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
|
|
@ -834,24 +834,24 @@ static void vce_v3_0_get_clockgating_state(void *handle, u32 *flags)
|
|||
}
|
||||
|
||||
static void vce_v3_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib, unsigned int vm_id, bool ctx_switch)
|
||||
struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch)
|
||||
{
|
||||
amdgpu_ring_write(ring, VCE_CMD_IB_VM);
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, ib->length_dw);
|
||||
}
|
||||
|
||||
static void vce_v3_0_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned int vm_id, uint64_t pd_addr)
|
||||
unsigned int vmid, uint64_t pd_addr)
|
||||
{
|
||||
amdgpu_ring_write(ring, VCE_CMD_UPDATE_PTB);
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
amdgpu_ring_write(ring, pd_addr >> 12);
|
||||
|
||||
amdgpu_ring_write(ring, VCE_CMD_FLUSH_TLB);
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
amdgpu_ring_write(ring, VCE_CMD_END);
|
||||
}
|
||||
|
||||
|
|
|
@ -938,10 +938,10 @@ static int vce_v4_0_set_powergating_state(void *handle,
|
|||
#endif
|
||||
|
||||
static void vce_v4_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib, unsigned int vm_id, bool ctx_switch)
|
||||
struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch)
|
||||
{
|
||||
amdgpu_ring_write(ring, VCE_CMD_IB_VM);
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, ib->length_dw);
|
||||
|
@ -965,10 +965,10 @@ static void vce_v4_0_ring_insert_end(struct amdgpu_ring *ring)
|
|||
}
|
||||
|
||||
static void vce_v4_0_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned int vm_id, uint64_t pd_addr)
|
||||
unsigned int vmid, uint64_t pd_addr)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vm_id);
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vmid);
|
||||
uint64_t flags = AMDGPU_PTE_VALID;
|
||||
unsigned eng = ring->vm_inv_eng;
|
||||
|
||||
|
@ -976,15 +976,15 @@ static void vce_v4_0_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
pd_addr |= flags;
|
||||
|
||||
amdgpu_ring_write(ring, VCE_CMD_REG_WRITE);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_hi32 + vm_id * 2) << 2);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_hi32 + vmid * 2) << 2);
|
||||
amdgpu_ring_write(ring, upper_32_bits(pd_addr));
|
||||
|
||||
amdgpu_ring_write(ring, VCE_CMD_REG_WRITE);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2);
|
||||
amdgpu_ring_write(ring, lower_32_bits(pd_addr));
|
||||
|
||||
amdgpu_ring_write(ring, VCE_CMD_REG_WAIT);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2);
|
||||
amdgpu_ring_write(ring, (hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2);
|
||||
amdgpu_ring_write(ring, 0xffffffff);
|
||||
amdgpu_ring_write(ring, lower_32_bits(pd_addr));
|
||||
|
||||
|
@ -996,8 +996,8 @@ static void vce_v4_0_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
/* wait for flush */
|
||||
amdgpu_ring_write(ring, VCE_CMD_REG_WAIT);
|
||||
amdgpu_ring_write(ring, (hub->vm_inv_eng0_ack + eng) << 2);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
}
|
||||
|
||||
static int vce_v4_0_set_interrupt_state(struct amdgpu_device *adev,
|
||||
|
|
|
@ -833,13 +833,13 @@ static void vcn_v1_0_dec_ring_emit_hdp_invalidate(struct amdgpu_ring *ring)
|
|||
*/
|
||||
static void vcn_v1_0_dec_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib,
|
||||
unsigned vm_id, bool ctx_switch)
|
||||
unsigned vmid, bool ctx_switch)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
|
||||
amdgpu_ring_write(ring,
|
||||
PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_VMID), 0));
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
|
||||
amdgpu_ring_write(ring,
|
||||
PACKET0(SOC15_REG_OFFSET(UVD, 0, mmUVD_LMI_RBC_IB_64BIT_BAR_LOW), 0));
|
||||
|
@ -888,10 +888,10 @@ static void vcn_v1_0_dec_vm_reg_wait(struct amdgpu_ring *ring,
|
|||
}
|
||||
|
||||
static void vcn_v1_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned vm_id, uint64_t pd_addr)
|
||||
unsigned vmid, uint64_t pd_addr)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vm_id);
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vmid);
|
||||
uint64_t flags = AMDGPU_PTE_VALID;
|
||||
unsigned eng = ring->vm_inv_eng;
|
||||
uint32_t data0, data1, mask;
|
||||
|
@ -899,15 +899,15 @@ static void vcn_v1_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
amdgpu_gart_get_vm_pde(ring->adev, -1, &pd_addr, &flags);
|
||||
pd_addr |= flags;
|
||||
|
||||
data0 = (hub->ctx0_ptb_addr_hi32 + vm_id * 2) << 2;
|
||||
data0 = (hub->ctx0_ptb_addr_hi32 + vmid * 2) << 2;
|
||||
data1 = upper_32_bits(pd_addr);
|
||||
vcn_v1_0_dec_vm_reg_write(ring, data0, data1);
|
||||
|
||||
data0 = (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2;
|
||||
data0 = (hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2;
|
||||
data1 = lower_32_bits(pd_addr);
|
||||
vcn_v1_0_dec_vm_reg_write(ring, data0, data1);
|
||||
|
||||
data0 = (hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2;
|
||||
data0 = (hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2;
|
||||
data1 = lower_32_bits(pd_addr);
|
||||
mask = 0xffffffff;
|
||||
vcn_v1_0_dec_vm_reg_wait(ring, data0, data1, mask);
|
||||
|
@ -919,8 +919,8 @@ static void vcn_v1_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
|
||||
/* wait for flush */
|
||||
data0 = (hub->vm_inv_eng0_ack + eng) << 2;
|
||||
data1 = 1 << vm_id;
|
||||
mask = 1 << vm_id;
|
||||
data1 = 1 << vmid;
|
||||
mask = 1 << vmid;
|
||||
vcn_v1_0_dec_vm_reg_wait(ring, data0, data1, mask);
|
||||
}
|
||||
|
||||
|
@ -1011,20 +1011,20 @@ static void vcn_v1_0_enc_ring_insert_end(struct amdgpu_ring *ring)
|
|||
* Write enc ring commands to execute the indirect buffer
|
||||
*/
|
||||
static void vcn_v1_0_enc_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
struct amdgpu_ib *ib, unsigned int vm_id, bool ctx_switch)
|
||||
struct amdgpu_ib *ib, unsigned int vmid, bool ctx_switch)
|
||||
{
|
||||
amdgpu_ring_write(ring, VCN_ENC_CMD_IB);
|
||||
amdgpu_ring_write(ring, vm_id);
|
||||
amdgpu_ring_write(ring, vmid);
|
||||
amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
|
||||
amdgpu_ring_write(ring, ib->length_dw);
|
||||
}
|
||||
|
||||
static void vcn_v1_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
||||
unsigned int vm_id, uint64_t pd_addr)
|
||||
unsigned int vmid, uint64_t pd_addr)
|
||||
{
|
||||
struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vm_id);
|
||||
uint32_t req = ring->adev->gart.gart_funcs->get_invalidate_req(vmid);
|
||||
uint64_t flags = AMDGPU_PTE_VALID;
|
||||
unsigned eng = ring->vm_inv_eng;
|
||||
|
||||
|
@ -1033,17 +1033,17 @@ static void vcn_v1_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
|
||||
amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WRITE);
|
||||
amdgpu_ring_write(ring,
|
||||
(hub->ctx0_ptb_addr_hi32 + vm_id * 2) << 2);
|
||||
(hub->ctx0_ptb_addr_hi32 + vmid * 2) << 2);
|
||||
amdgpu_ring_write(ring, upper_32_bits(pd_addr));
|
||||
|
||||
amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WRITE);
|
||||
amdgpu_ring_write(ring,
|
||||
(hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2);
|
||||
(hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2);
|
||||
amdgpu_ring_write(ring, lower_32_bits(pd_addr));
|
||||
|
||||
amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WAIT);
|
||||
amdgpu_ring_write(ring,
|
||||
(hub->ctx0_ptb_addr_lo32 + vm_id * 2) << 2);
|
||||
(hub->ctx0_ptb_addr_lo32 + vmid * 2) << 2);
|
||||
amdgpu_ring_write(ring, 0xffffffff);
|
||||
amdgpu_ring_write(ring, lower_32_bits(pd_addr));
|
||||
|
||||
|
@ -1055,8 +1055,8 @@ static void vcn_v1_0_enc_ring_emit_vm_flush(struct amdgpu_ring *ring,
|
|||
/* wait for flush */
|
||||
amdgpu_ring_write(ring, VCN_ENC_CMD_REG_WAIT);
|
||||
amdgpu_ring_write(ring, (hub->vm_inv_eng0_ack + eng) << 2);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vm_id);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
amdgpu_ring_write(ring, 1 << vmid);
|
||||
}
|
||||
|
||||
static int vcn_v1_0_set_interrupt_state(struct amdgpu_device *adev,
|
||||
|
|
|
@ -327,8 +327,8 @@ static void vega10_ih_decode_iv(struct amdgpu_device *adev,
|
|||
entry->client_id = dw[0] & 0xff;
|
||||
entry->src_id = (dw[0] >> 8) & 0xff;
|
||||
entry->ring_id = (dw[0] >> 16) & 0xff;
|
||||
entry->vm_id = (dw[0] >> 24) & 0xf;
|
||||
entry->vm_id_src = (dw[0] >> 31);
|
||||
entry->vmid = (dw[0] >> 24) & 0xf;
|
||||
entry->vmid_src = (dw[0] >> 31);
|
||||
entry->timestamp = dw[1] | ((u64)(dw[2] & 0xffff) << 32);
|
||||
entry->timestamp_src = dw[2] >> 31;
|
||||
entry->pas_id = dw[3] & 0xffff;
|
||||
|
|
|
@ -709,6 +709,19 @@ static int cz_start_smu(struct pp_hwmgr *hwmgr)
|
|||
{
|
||||
int ret = 0;
|
||||
uint32_t fw_to_check = 0;
|
||||
struct cgs_firmware_info info = {0};
|
||||
uint32_t index = SMN_MP1_SRAM_START_ADDR +
|
||||
SMU8_FIRMWARE_HEADER_LOCATION +
|
||||
offsetof(struct SMU8_Firmware_Header, Version);
|
||||
|
||||
|
||||
if (hwmgr == NULL || hwmgr->device == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
cgs_write_register(hwmgr->device, mmMP0PUB_IND_INDEX, index);
|
||||
hwmgr->smu_version = cgs_read_register(hwmgr->device, mmMP0PUB_IND_DATA);
|
||||
info.version = hwmgr->smu_version >> 8;
|
||||
cgs_get_firmware_info(hwmgr->device, CGS_UCODE_ID_SMU, &info);
|
||||
|
||||
fw_to_check = UCODE_ID_RLC_G_MASK |
|
||||
UCODE_ID_SDMA0_MASK |
|
||||
|
|
|
@ -216,9 +216,10 @@ static struct ttm_tt *ast_ttm_tt_create(struct ttm_bo_device *bdev,
|
|||
return tt;
|
||||
}
|
||||
|
||||
static int ast_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
static int ast_ttm_tt_populate(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
return ttm_pool_populate(ttm);
|
||||
return ttm_pool_populate(ttm, ctx);
|
||||
}
|
||||
|
||||
static void ast_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||
|
@ -237,7 +238,6 @@ struct ttm_bo_driver ast_bo_driver = {
|
|||
.verify_access = ast_bo_verify_access,
|
||||
.io_mem_reserve = &ast_ttm_io_mem_reserve,
|
||||
.io_mem_free = &ast_ttm_io_mem_free,
|
||||
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
|
||||
};
|
||||
|
||||
int ast_mm_init(struct ast_private *ast)
|
||||
|
|
|
@ -205,7 +205,6 @@ struct ttm_bo_driver bochs_bo_driver = {
|
|||
.verify_access = bochs_bo_verify_access,
|
||||
.io_mem_reserve = &bochs_ttm_io_mem_reserve,
|
||||
.io_mem_free = &bochs_ttm_io_mem_free,
|
||||
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
|
||||
};
|
||||
|
||||
int bochs_mm_init(struct bochs_device *bochs)
|
||||
|
|
|
@ -216,9 +216,10 @@ static struct ttm_tt *cirrus_ttm_tt_create(struct ttm_bo_device *bdev,
|
|||
return tt;
|
||||
}
|
||||
|
||||
static int cirrus_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
static int cirrus_ttm_tt_populate(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
return ttm_pool_populate(ttm);
|
||||
return ttm_pool_populate(ttm, ctx);
|
||||
}
|
||||
|
||||
static void cirrus_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||
|
@ -237,7 +238,6 @@ struct ttm_bo_driver cirrus_bo_driver = {
|
|||
.verify_access = cirrus_bo_verify_access,
|
||||
.io_mem_reserve = &cirrus_ttm_io_mem_reserve,
|
||||
.io_mem_free = &cirrus_ttm_io_mem_free,
|
||||
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
|
||||
};
|
||||
|
||||
int cirrus_mm_init(struct cirrus_device *cirrus)
|
||||
|
|
|
@ -223,9 +223,10 @@ static struct ttm_tt *hibmc_ttm_tt_create(struct ttm_bo_device *bdev,
|
|||
return tt;
|
||||
}
|
||||
|
||||
static int hibmc_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
static int hibmc_ttm_tt_populate(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
return ttm_pool_populate(ttm);
|
||||
return ttm_pool_populate(ttm, ctx);
|
||||
}
|
||||
|
||||
static void hibmc_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||
|
|
|
@ -216,9 +216,10 @@ static struct ttm_tt *mgag200_ttm_tt_create(struct ttm_bo_device *bdev,
|
|||
return tt;
|
||||
}
|
||||
|
||||
static int mgag200_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
static int mgag200_ttm_tt_populate(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
return ttm_pool_populate(ttm);
|
||||
return ttm_pool_populate(ttm, ctx);
|
||||
}
|
||||
|
||||
static void mgag200_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||
|
@ -237,7 +238,6 @@ struct ttm_bo_driver mgag200_bo_driver = {
|
|||
.verify_access = mgag200_bo_verify_access,
|
||||
.io_mem_reserve = &mgag200_ttm_io_mem_reserve,
|
||||
.io_mem_free = &mgag200_ttm_io_mem_free,
|
||||
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
|
||||
};
|
||||
|
||||
int mgag200_mm_init(struct mga_device *mdev)
|
||||
|
|
|
@ -1218,7 +1218,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = ttm_tt_bind(bo->ttm, &tmp_reg);
|
||||
ret = ttm_tt_bind(bo->ttm, &tmp_reg, &ctx);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
@ -1547,7 +1547,7 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
|
|||
}
|
||||
|
||||
static int
|
||||
nouveau_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
nouveau_ttm_tt_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
struct ttm_dma_tt *ttm_dma = (void *)ttm;
|
||||
struct nouveau_drm *drm;
|
||||
|
@ -1572,17 +1572,17 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm)
|
|||
|
||||
#if IS_ENABLED(CONFIG_AGP)
|
||||
if (drm->agp.bridge) {
|
||||
return ttm_agp_tt_populate(ttm);
|
||||
return ttm_agp_tt_populate(ttm, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_SWIOTLB) && IS_ENABLED(CONFIG_X86)
|
||||
if (swiotlb_nr_tbl()) {
|
||||
return ttm_dma_populate((void *)ttm, dev);
|
||||
return ttm_dma_populate((void *)ttm, dev, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
r = ttm_pool_populate(ttm);
|
||||
r = ttm_pool_populate(ttm, ctx);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
@ -1672,5 +1672,4 @@ struct ttm_bo_driver nouveau_bo_driver = {
|
|||
.fault_reserve_notify = &nouveau_ttm_fault_reserve_notify,
|
||||
.io_mem_reserve = &nouveau_ttm_io_mem_reserve,
|
||||
.io_mem_free = &nouveau_ttm_io_mem_free,
|
||||
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
|
||||
};
|
||||
|
|
|
@ -291,14 +291,15 @@ static struct ttm_backend_func qxl_backend_func = {
|
|||
.destroy = &qxl_ttm_backend_destroy,
|
||||
};
|
||||
|
||||
static int qxl_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
static int qxl_ttm_tt_populate(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (ttm->state != tt_unpopulated)
|
||||
return 0;
|
||||
|
||||
r = ttm_pool_populate(ttm);
|
||||
r = ttm_pool_populate(ttm, ctx);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
@ -388,7 +389,6 @@ static struct ttm_bo_driver qxl_bo_driver = {
|
|||
.verify_access = &qxl_verify_access,
|
||||
.io_mem_reserve = &qxl_ttm_io_mem_reserve,
|
||||
.io_mem_free = &qxl_ttm_io_mem_free,
|
||||
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
|
||||
.move_notify = &qxl_bo_move_notify,
|
||||
};
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
|
|||
goto out_cleanup;
|
||||
}
|
||||
|
||||
r = ttm_tt_bind(bo->ttm, &tmp_mem);
|
||||
r = ttm_tt_bind(bo->ttm, &tmp_mem, &ctx);
|
||||
if (unlikely(r)) {
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
@ -721,7 +721,8 @@ static struct radeon_ttm_tt *radeon_ttm_tt_to_gtt(struct ttm_tt *ttm)
|
|||
return (struct radeon_ttm_tt *)ttm;
|
||||
}
|
||||
|
||||
static int radeon_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
static int radeon_ttm_tt_populate(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
struct radeon_ttm_tt *gtt = radeon_ttm_tt_to_gtt(ttm);
|
||||
struct radeon_device *rdev;
|
||||
|
@ -750,17 +751,17 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm)
|
|||
rdev = radeon_get_rdev(ttm->bdev);
|
||||
#if IS_ENABLED(CONFIG_AGP)
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
return ttm_agp_tt_populate(ttm);
|
||||
return ttm_agp_tt_populate(ttm, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
if (swiotlb_nr_tbl()) {
|
||||
return ttm_dma_populate(>t->ttm, rdev->dev);
|
||||
return ttm_dma_populate(>t->ttm, rdev->dev, ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ttm_populate_and_map_pages(rdev->dev, >t->ttm);
|
||||
return ttm_populate_and_map_pages(rdev->dev, >t->ttm, ctx);
|
||||
}
|
||||
|
||||
static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||
|
@ -844,7 +845,6 @@ static struct ttm_bo_driver radeon_bo_driver = {
|
|||
.fault_reserve_notify = &radeon_bo_fault_reserve_notify,
|
||||
.io_mem_reserve = &radeon_ttm_io_mem_reserve,
|
||||
.io_mem_free = &radeon_ttm_io_mem_free,
|
||||
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
|
||||
};
|
||||
|
||||
int radeon_ttm_init(struct radeon_device *rdev)
|
||||
|
|
|
@ -133,12 +133,12 @@ struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev,
|
|||
}
|
||||
EXPORT_SYMBOL(ttm_agp_tt_create);
|
||||
|
||||
int ttm_agp_tt_populate(struct ttm_tt *ttm)
|
||||
int ttm_agp_tt_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
if (ttm->state != tt_unpopulated)
|
||||
return 0;
|
||||
|
||||
return ttm_pool_populate(ttm);
|
||||
return ttm_pool_populate(ttm, ctx);
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_agp_tt_populate);
|
||||
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include <linux/atomic.h>
|
||||
#include <linux/reservation.h>
|
||||
|
||||
static int ttm_bo_swapout(struct ttm_mem_shrink *shrink);
|
||||
static void ttm_bo_global_kobj_release(struct kobject *kobj);
|
||||
|
||||
static struct attribute ttm_bo_count = {
|
||||
|
@ -301,7 +300,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
|
|||
goto out_err;
|
||||
|
||||
if (mem->mem_type != TTM_PL_SYSTEM) {
|
||||
ret = ttm_tt_bind(bo->ttm, mem);
|
||||
ret = ttm_tt_bind(bo->ttm, mem, ctx);
|
||||
if (ret)
|
||||
goto out_err;
|
||||
}
|
||||
|
@ -592,6 +591,8 @@ static bool ttm_bo_delayed_delete(struct ttm_bo_device *bdev, bool remove_all)
|
|||
|
||||
} else if (reservation_object_trylock(bo->resv)) {
|
||||
ttm_bo_cleanup_refs(bo, false, !remove_all, true);
|
||||
} else {
|
||||
spin_unlock(&glob->lru_lock);
|
||||
}
|
||||
|
||||
kref_put(&bo->list_kref, ttm_bo_release_list);
|
||||
|
@ -707,6 +708,34 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo,
|
|||
}
|
||||
EXPORT_SYMBOL(ttm_bo_eviction_valuable);
|
||||
|
||||
/**
|
||||
* Check the target bo is allowable to be evicted or swapout, including cases:
|
||||
*
|
||||
* a. if share same reservation object with ctx->resv, have assumption
|
||||
* reservation objects should already be locked, so not lock again and
|
||||
* return true directly when either the opreation allow_reserved_eviction
|
||||
* or the target bo already is in delayed free list;
|
||||
*
|
||||
* b. Otherwise, trylock it.
|
||||
*/
|
||||
static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
|
||||
struct ttm_operation_ctx *ctx, bool *locked)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
*locked = false;
|
||||
if (bo->resv == ctx->resv) {
|
||||
reservation_object_assert_held(bo->resv);
|
||||
if (ctx->allow_reserved_eviction || !list_empty(&bo->ddestroy))
|
||||
ret = true;
|
||||
} else {
|
||||
*locked = reservation_object_trylock(bo->resv);
|
||||
ret = *locked;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
|
||||
uint32_t mem_type,
|
||||
const struct ttm_place *place,
|
||||
|
@ -722,21 +751,13 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
|
|||
spin_lock(&glob->lru_lock);
|
||||
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
|
||||
list_for_each_entry(bo, &man->lru[i], lru) {
|
||||
if (bo->resv == ctx->resv) {
|
||||
if (!ctx->allow_reserved_eviction &&
|
||||
list_empty(&bo->ddestroy))
|
||||
continue;
|
||||
} else {
|
||||
locked = reservation_object_trylock(bo->resv);
|
||||
if (!locked)
|
||||
continue;
|
||||
}
|
||||
if (!ttm_bo_evict_swapout_allowable(bo, ctx, &locked))
|
||||
continue;
|
||||
|
||||
if (place && !bdev->driver->eviction_valuable(bo,
|
||||
place)) {
|
||||
if (locked)
|
||||
reservation_object_unlock(bo->resv);
|
||||
locked = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
@ -1134,7 +1155,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev,
|
|||
struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
|
||||
bool locked;
|
||||
|
||||
ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
|
||||
ret = ttm_mem_global_alloc(mem_glob, acc_size, ctx);
|
||||
if (ret) {
|
||||
pr_err("Out of kernel memory\n");
|
||||
if (destroy)
|
||||
|
@ -1454,7 +1475,6 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj)
|
|||
struct ttm_bo_global *glob =
|
||||
container_of(kobj, struct ttm_bo_global, kobj);
|
||||
|
||||
ttm_mem_unregister_shrink(glob->mem_glob, &glob->shrink);
|
||||
__free_page(glob->dummy_read_page);
|
||||
kfree(glob);
|
||||
}
|
||||
|
@ -1479,6 +1499,7 @@ int ttm_bo_global_init(struct drm_global_reference *ref)
|
|||
mutex_init(&glob->device_list_mutex);
|
||||
spin_lock_init(&glob->lru_lock);
|
||||
glob->mem_glob = bo_ref->mem_glob;
|
||||
glob->mem_glob->bo_glob = glob;
|
||||
glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32);
|
||||
|
||||
if (unlikely(glob->dummy_read_page == NULL)) {
|
||||
|
@ -1489,14 +1510,6 @@ int ttm_bo_global_init(struct drm_global_reference *ref)
|
|||
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
|
||||
INIT_LIST_HEAD(&glob->swap_lru[i]);
|
||||
INIT_LIST_HEAD(&glob->device_list);
|
||||
|
||||
ttm_mem_init_shrink(&glob->shrink, ttm_bo_swapout);
|
||||
ret = ttm_mem_register_shrink(glob->mem_glob, &glob->shrink);
|
||||
if (unlikely(ret != 0)) {
|
||||
pr_err("Could not register buffer object swapout\n");
|
||||
goto out_no_shrink;
|
||||
}
|
||||
|
||||
atomic_set(&glob->bo_count, 0);
|
||||
|
||||
ret = kobject_init_and_add(
|
||||
|
@ -1504,8 +1517,6 @@ int ttm_bo_global_init(struct drm_global_reference *ref)
|
|||
if (unlikely(ret != 0))
|
||||
kobject_put(&glob->kobj);
|
||||
return ret;
|
||||
out_no_shrink:
|
||||
__free_page(glob->dummy_read_page);
|
||||
out_no_drp:
|
||||
kfree(glob);
|
||||
return ret;
|
||||
|
@ -1688,21 +1699,20 @@ EXPORT_SYMBOL(ttm_bo_synccpu_write_release);
|
|||
* A buffer object shrink method that tries to swap out the first
|
||||
* buffer object on the bo_global::swap_lru list.
|
||||
*/
|
||||
|
||||
static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
|
||||
int ttm_bo_swapout(struct ttm_bo_global *glob, struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
struct ttm_bo_global *glob =
|
||||
container_of(shrink, struct ttm_bo_global, shrink);
|
||||
struct ttm_buffer_object *bo;
|
||||
int ret = -EBUSY;
|
||||
bool locked;
|
||||
unsigned i;
|
||||
|
||||
spin_lock(&glob->lru_lock);
|
||||
for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
|
||||
list_for_each_entry(bo, &glob->swap_lru[i], swap) {
|
||||
ret = reservation_object_trylock(bo->resv) ? 0 : -EBUSY;
|
||||
if (!ret)
|
||||
if (ttm_bo_evict_swapout_allowable(bo, ctx, &locked)) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ret)
|
||||
break;
|
||||
|
@ -1774,10 +1784,16 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink)
|
|||
kref_put(&bo->list_kref, ttm_bo_release_list);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_bo_swapout);
|
||||
|
||||
void ttm_bo_swapout_all(struct ttm_bo_device *bdev)
|
||||
{
|
||||
while (ttm_bo_swapout(&bdev->glob->shrink) == 0)
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
|
||||
while (ttm_bo_swapout(bdev->glob, &ctx) == 0)
|
||||
;
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_bo_swapout_all);
|
||||
|
|
|
@ -73,7 +73,7 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
|
|||
return ret;
|
||||
|
||||
if (new_mem->mem_type != TTM_PL_SYSTEM) {
|
||||
ret = ttm_tt_bind(ttm, new_mem);
|
||||
ret = ttm_tt_bind(ttm, new_mem, ctx);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
|
|||
* TTM might be null for moves within the same region.
|
||||
*/
|
||||
if (ttm && ttm->state == tt_unpopulated) {
|
||||
ret = ttm->bdev->driver->ttm_tt_populate(ttm);
|
||||
ret = ttm->bdev->driver->ttm_tt_populate(ttm, ctx);
|
||||
if (ret)
|
||||
goto out1;
|
||||
}
|
||||
|
@ -545,14 +545,19 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
|
|||
unsigned long num_pages,
|
||||
struct ttm_bo_kmap_obj *map)
|
||||
{
|
||||
struct ttm_mem_reg *mem = &bo->mem; pgprot_t prot;
|
||||
struct ttm_mem_reg *mem = &bo->mem;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
struct ttm_tt *ttm = bo->ttm;
|
||||
pgprot_t prot;
|
||||
int ret;
|
||||
|
||||
BUG_ON(!ttm);
|
||||
|
||||
if (ttm->state == tt_unpopulated) {
|
||||
ret = ttm->bdev->driver->ttm_tt_populate(ttm);
|
||||
ret = ttm->bdev->driver->ttm_tt_populate(ttm, &ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -92,6 +92,17 @@ static int ttm_bo_vm_fault_idle(struct ttm_buffer_object *bo,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static unsigned long ttm_bo_io_mem_pfn(struct ttm_buffer_object *bo,
|
||||
unsigned long page_offset)
|
||||
{
|
||||
struct ttm_bo_device *bdev = bo->bdev;
|
||||
|
||||
if (bdev->driver->io_mem_pfn)
|
||||
return bdev->driver->io_mem_pfn(bo, page_offset);
|
||||
|
||||
return ttm_bo_default_io_mem_pfn(bo, page_offset);
|
||||
}
|
||||
|
||||
static int ttm_bo_vm_fault(struct vm_fault *vmf)
|
||||
{
|
||||
struct vm_area_struct *vma = vmf->vma;
|
||||
|
@ -215,12 +226,17 @@ static int ttm_bo_vm_fault(struct vm_fault *vmf)
|
|||
cvma.vm_page_prot = ttm_io_prot(bo->mem.placement,
|
||||
cvma.vm_page_prot);
|
||||
} else {
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
|
||||
ttm = bo->ttm;
|
||||
cvma.vm_page_prot = ttm_io_prot(bo->mem.placement,
|
||||
cvma.vm_page_prot);
|
||||
|
||||
/* Allocate all page at once, most common usage */
|
||||
if (ttm->bdev->driver->ttm_tt_populate(ttm)) {
|
||||
if (ttm->bdev->driver->ttm_tt_populate(ttm, &ctx)) {
|
||||
retval = VM_FAULT_OOM;
|
||||
goto out_io_unlock;
|
||||
}
|
||||
|
@ -234,7 +250,7 @@ static int ttm_bo_vm_fault(struct vm_fault *vmf)
|
|||
if (bo->mem.bus.is_iomem) {
|
||||
/* Iomem should not be marked encrypted */
|
||||
cvma.vm_page_prot = pgprot_decrypted(cvma.vm_page_prot);
|
||||
pfn = bdev->driver->io_mem_pfn(bo, page_offset);
|
||||
pfn = ttm_bo_io_mem_pfn(bo, page_offset);
|
||||
} else {
|
||||
page = ttm->pages[page_offset];
|
||||
if (unlikely(!page && i == 0)) {
|
||||
|
|
|
@ -211,35 +211,33 @@ static bool ttm_zones_above_swap_target(struct ttm_mem_global *glob,
|
|||
*/
|
||||
|
||||
static void ttm_shrink(struct ttm_mem_global *glob, bool from_wq,
|
||||
uint64_t extra)
|
||||
uint64_t extra, struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
int ret;
|
||||
struct ttm_mem_shrink *shrink;
|
||||
|
||||
spin_lock(&glob->lock);
|
||||
if (glob->shrink == NULL)
|
||||
goto out;
|
||||
|
||||
while (ttm_zones_above_swap_target(glob, from_wq, extra)) {
|
||||
shrink = glob->shrink;
|
||||
spin_unlock(&glob->lock);
|
||||
ret = shrink->do_shrink(shrink);
|
||||
ret = ttm_bo_swapout(glob->bo_glob, ctx);
|
||||
spin_lock(&glob->lock);
|
||||
if (unlikely(ret != 0))
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
out:
|
||||
|
||||
spin_unlock(&glob->lock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ttm_shrink_work(struct work_struct *work)
|
||||
{
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
struct ttm_mem_global *glob =
|
||||
container_of(work, struct ttm_mem_global, work);
|
||||
|
||||
ttm_shrink(glob, true, 0ULL);
|
||||
ttm_shrink(glob, true, 0ULL, &ctx);
|
||||
}
|
||||
|
||||
static int ttm_mem_init_kernel_zone(struct ttm_mem_global *glob,
|
||||
|
@ -514,7 +512,7 @@ static int ttm_mem_global_reserve(struct ttm_mem_global *glob,
|
|||
static int ttm_mem_global_alloc_zone(struct ttm_mem_global *glob,
|
||||
struct ttm_mem_zone *single_zone,
|
||||
uint64_t memory,
|
||||
bool no_wait, bool interruptible)
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
int count = TTM_MEMORY_ALLOC_RETRIES;
|
||||
|
||||
|
@ -522,33 +520,32 @@ static int ttm_mem_global_alloc_zone(struct ttm_mem_global *glob,
|
|||
single_zone,
|
||||
memory, true)
|
||||
!= 0)) {
|
||||
if (no_wait)
|
||||
if (ctx->no_wait_gpu)
|
||||
return -ENOMEM;
|
||||
if (unlikely(count-- == 0))
|
||||
return -ENOMEM;
|
||||
ttm_shrink(glob, false, memory + (memory >> 2) + 16);
|
||||
ttm_shrink(glob, false, memory + (memory >> 2) + 16, ctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
|
||||
bool no_wait, bool interruptible)
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
/**
|
||||
* Normal allocations of kernel memory are registered in
|
||||
* all zones.
|
||||
*/
|
||||
|
||||
return ttm_mem_global_alloc_zone(glob, NULL, memory, no_wait,
|
||||
interruptible);
|
||||
return ttm_mem_global_alloc_zone(glob, NULL, memory, ctx);
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_mem_global_alloc);
|
||||
|
||||
int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
|
||||
struct page *page, uint64_t size)
|
||||
struct page *page, uint64_t size,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
|
||||
struct ttm_mem_zone *zone = NULL;
|
||||
|
||||
/**
|
||||
|
@ -563,7 +560,7 @@ int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
|
|||
if (glob->zone_dma32 && page_to_pfn(page) > 0x00100000UL)
|
||||
zone = glob->zone_kernel;
|
||||
#endif
|
||||
return ttm_mem_global_alloc_zone(glob, zone, size, false, false);
|
||||
return ttm_mem_global_alloc_zone(glob, zone, size, ctx);
|
||||
}
|
||||
|
||||
void ttm_mem_global_free_page(struct ttm_mem_global *glob, struct page *page,
|
||||
|
|
|
@ -325,6 +325,10 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
|
|||
struct ttm_ref_object *ref;
|
||||
struct drm_hash_item *hash;
|
||||
struct ttm_mem_global *mem_glob = tfile->tdev->mem_glob;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (base->tfile != tfile && !base->shareable)
|
||||
|
@ -350,7 +354,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile,
|
|||
return -EPERM;
|
||||
|
||||
ret = ttm_mem_global_alloc(mem_glob, sizeof(*ref),
|
||||
false, false);
|
||||
&ctx);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
ref = kmalloc(sizeof(*ref), GFP_KERNEL);
|
||||
|
@ -686,7 +690,10 @@ int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,
|
|||
dma_buf = prime->dma_buf;
|
||||
if (!dma_buf || !get_dma_buf_unless_doomed(dma_buf)) {
|
||||
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
|
||||
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
exp_info.ops = &tdev->ops;
|
||||
exp_info.size = prime->size;
|
||||
exp_info.flags = flags;
|
||||
|
@ -696,7 +703,7 @@ int ttm_prime_handle_to_fd(struct ttm_object_file *tfile,
|
|||
* Need to create a new dma_buf, with memory accounting.
|
||||
*/
|
||||
ret = ttm_mem_global_alloc(tdev->mem_glob, tdev->dma_buf_size,
|
||||
false, true);
|
||||
&ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
mutex_unlock(&prime->mutex);
|
||||
goto out_unref;
|
||||
|
|
|
@ -1058,7 +1058,7 @@ void ttm_page_alloc_fini(void)
|
|||
_manager = NULL;
|
||||
}
|
||||
|
||||
int ttm_pool_populate(struct ttm_tt *ttm)
|
||||
int ttm_pool_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
|
||||
unsigned i;
|
||||
|
@ -1076,7 +1076,7 @@ int ttm_pool_populate(struct ttm_tt *ttm)
|
|||
|
||||
for (i = 0; i < ttm->num_pages; ++i) {
|
||||
ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
|
||||
PAGE_SIZE);
|
||||
PAGE_SIZE, ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
ttm_pool_unpopulate(ttm);
|
||||
return -ENOMEM;
|
||||
|
@ -1113,12 +1113,13 @@ void ttm_pool_unpopulate(struct ttm_tt *ttm)
|
|||
}
|
||||
EXPORT_SYMBOL(ttm_pool_unpopulate);
|
||||
|
||||
int ttm_populate_and_map_pages(struct device *dev, struct ttm_dma_tt *tt)
|
||||
int ttm_populate_and_map_pages(struct device *dev, struct ttm_dma_tt *tt,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
unsigned i, j;
|
||||
int r;
|
||||
|
||||
r = ttm_pool_populate(&tt->ttm);
|
||||
r = ttm_pool_populate(&tt->ttm, ctx);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
|
|
|
@ -923,7 +923,8 @@ static gfp_t ttm_dma_pool_gfp_flags(struct ttm_dma_tt *ttm_dma, bool huge)
|
|||
* On success pages list will hold count number of correctly
|
||||
* cached pages. On failure will hold the negative return value (-ENOMEM, etc).
|
||||
*/
|
||||
int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev)
|
||||
int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
struct ttm_tt *ttm = &ttm_dma->ttm;
|
||||
struct ttm_mem_global *mem_glob = ttm->glob->mem_glob;
|
||||
|
@ -962,7 +963,7 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev)
|
|||
break;
|
||||
|
||||
ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
|
||||
pool->size);
|
||||
pool->size, ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
ttm_dma_unpopulate(ttm_dma, dev);
|
||||
return -ENOMEM;
|
||||
|
@ -998,7 +999,7 @@ int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev)
|
|||
}
|
||||
|
||||
ret = ttm_mem_global_alloc_page(mem_glob, ttm->pages[i],
|
||||
pool->size);
|
||||
pool->size, ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
ttm_dma_unpopulate(ttm_dma, dev);
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -261,7 +261,8 @@ void ttm_tt_unbind(struct ttm_tt *ttm)
|
|||
}
|
||||
}
|
||||
|
||||
int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
|
||||
int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
@ -271,7 +272,7 @@ int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)
|
|||
if (ttm->state == tt_bound)
|
||||
return 0;
|
||||
|
||||
ret = ttm->bdev->driver->ttm_tt_populate(ttm);
|
||||
ret = ttm->bdev->driver->ttm_tt_populate(ttm, ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -124,13 +124,17 @@ int virtio_gpu_object_get_sg_table(struct virtio_gpu_device *qdev,
|
|||
int ret;
|
||||
struct page **pages = bo->tbo.ttm->pages;
|
||||
int nr_pages = bo->tbo.num_pages;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
|
||||
/* wtf swapping */
|
||||
if (bo->pages)
|
||||
return 0;
|
||||
|
||||
if (bo->tbo.ttm->state == tt_unpopulated)
|
||||
bo->tbo.ttm->bdev->driver->ttm_tt_populate(bo->tbo.ttm);
|
||||
bo->tbo.ttm->bdev->driver->ttm_tt_populate(bo->tbo.ttm, &ctx);
|
||||
bo->pages = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
|
||||
if (!bo->pages)
|
||||
goto out;
|
||||
|
|
|
@ -324,12 +324,13 @@ static struct ttm_backend_func virtio_gpu_backend_func = {
|
|||
.destroy = &virtio_gpu_ttm_backend_destroy,
|
||||
};
|
||||
|
||||
static int virtio_gpu_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
static int virtio_gpu_ttm_tt_populate(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
if (ttm->state != tt_unpopulated)
|
||||
return 0;
|
||||
|
||||
return ttm_pool_populate(ttm);
|
||||
return ttm_pool_populate(ttm, ctx);
|
||||
}
|
||||
|
||||
static void virtio_gpu_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||
|
@ -430,7 +431,6 @@ static struct ttm_bo_driver virtio_gpu_bo_driver = {
|
|||
.verify_access = &virtio_gpu_verify_access,
|
||||
.io_mem_reserve = &virtio_gpu_ttm_io_mem_reserve,
|
||||
.io_mem_free = &virtio_gpu_ttm_io_mem_free,
|
||||
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
|
||||
.move_notify = &virtio_gpu_bo_move_notify,
|
||||
.swap_notify = &virtio_gpu_bo_swap_notify,
|
||||
};
|
||||
|
|
|
@ -1202,10 +1202,14 @@ struct vmw_ctx_binding_state *
|
|||
vmw_binding_state_alloc(struct vmw_private *dev_priv)
|
||||
{
|
||||
struct vmw_ctx_binding_state *cbs;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), sizeof(*cbs),
|
||||
false, false);
|
||||
&ctx);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
|
|
|
@ -394,6 +394,10 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
|
|||
struct vmw_private *dev_priv = vmw_tt->dev_priv;
|
||||
struct ttm_mem_global *glob = vmw_mem_glob(dev_priv);
|
||||
struct vmw_sg_table *vsgt = &vmw_tt->vsgt;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
struct vmw_piter iter;
|
||||
dma_addr_t old;
|
||||
int ret = 0;
|
||||
|
@ -417,8 +421,7 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
|
|||
sgt_size = ttm_round_pot(sizeof(struct sg_table));
|
||||
}
|
||||
vmw_tt->sg_alloc_size = sgt_size + sgl_size * vsgt->num_pages;
|
||||
ret = ttm_mem_global_alloc(glob, vmw_tt->sg_alloc_size, false,
|
||||
true);
|
||||
ret = ttm_mem_global_alloc(glob, vmw_tt->sg_alloc_size, &ctx);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
|
||||
|
@ -632,7 +635,7 @@ static void vmw_ttm_destroy(struct ttm_tt *ttm)
|
|||
}
|
||||
|
||||
|
||||
static int vmw_ttm_populate(struct ttm_tt *ttm)
|
||||
static int vmw_ttm_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
struct vmw_ttm_tt *vmw_tt =
|
||||
container_of(ttm, struct vmw_ttm_tt, dma_ttm.ttm);
|
||||
|
@ -646,15 +649,16 @@ static int vmw_ttm_populate(struct ttm_tt *ttm)
|
|||
if (dev_priv->map_mode == vmw_dma_alloc_coherent) {
|
||||
size_t size =
|
||||
ttm_round_pot(ttm->num_pages * sizeof(dma_addr_t));
|
||||
ret = ttm_mem_global_alloc(glob, size, false, true);
|
||||
ret = ttm_mem_global_alloc(glob, size, ctx);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
|
||||
ret = ttm_dma_populate(&vmw_tt->dma_ttm, dev_priv->dev->dev);
|
||||
ret = ttm_dma_populate(&vmw_tt->dma_ttm, dev_priv->dev->dev,
|
||||
ctx);
|
||||
if (unlikely(ret != 0))
|
||||
ttm_mem_global_free(glob, size);
|
||||
} else
|
||||
ret = ttm_pool_populate(ttm);
|
||||
ret = ttm_pool_populate(ttm, ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -859,5 +863,4 @@ struct ttm_bo_driver vmw_bo_driver = {
|
|||
.fault_reserve_notify = &vmw_ttm_fault_reserve_notify,
|
||||
.io_mem_reserve = &vmw_ttm_io_mem_reserve,
|
||||
.io_mem_free = &vmw_ttm_io_mem_free,
|
||||
.io_mem_pfn = ttm_bo_default_io_mem_pfn,
|
||||
};
|
||||
|
|
|
@ -746,6 +746,10 @@ static int vmw_context_define(struct drm_device *dev, void *data,
|
|||
struct vmw_resource *tmp;
|
||||
struct drm_vmw_context_arg *arg = (struct drm_vmw_context_arg *)data;
|
||||
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
|
||||
struct ttm_operation_ctx ttm_opt_ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!dev_priv->has_dx && dx) {
|
||||
|
@ -768,7 +772,7 @@ static int vmw_context_define(struct drm_device *dev, void *data,
|
|||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
|
||||
vmw_user_context_size,
|
||||
false, true);
|
||||
&ttm_opt_ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("Out of graphics memory for context"
|
||||
|
|
|
@ -573,6 +573,10 @@ struct vmw_resource *vmw_cotable_alloc(struct vmw_private *dev_priv,
|
|||
u32 type)
|
||||
{
|
||||
struct vmw_cotable *vcotbl;
|
||||
struct ttm_operation_ctx ttm_opt_ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
int ret;
|
||||
u32 num_entries;
|
||||
|
||||
|
@ -580,7 +584,7 @@ struct vmw_resource *vmw_cotable_alloc(struct vmw_private *dev_priv,
|
|||
cotable_acc_size = ttm_round_pot(sizeof(struct vmw_cotable));
|
||||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
|
||||
cotable_acc_size, false, true);
|
||||
cotable_acc_size, &ttm_opt_ctx);
|
||||
if (unlikely(ret))
|
||||
return ERR_PTR(ret);
|
||||
|
||||
|
|
|
@ -588,6 +588,10 @@ int vmw_user_fence_create(struct drm_file *file_priv,
|
|||
struct vmw_user_fence *ufence;
|
||||
struct vmw_fence_obj *tmp;
|
||||
struct ttm_mem_global *mem_glob = vmw_mem_glob(fman->dev_priv);
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -596,7 +600,7 @@ int vmw_user_fence_create(struct drm_file *file_priv,
|
|||
*/
|
||||
|
||||
ret = ttm_mem_global_alloc(mem_glob, fman->user_fence_size,
|
||||
false, false);
|
||||
&ctx);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -240,6 +240,10 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv,
|
|||
unsigned long offset;
|
||||
unsigned long bo_size;
|
||||
struct vmw_otable *otables = batch->otables;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
SVGAOTableType i;
|
||||
int ret;
|
||||
|
||||
|
@ -264,7 +268,7 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv,
|
|||
|
||||
ret = ttm_bo_reserve(batch->otable_bo, false, true, NULL);
|
||||
BUG_ON(ret != 0);
|
||||
ret = vmw_bo_driver.ttm_tt_populate(batch->otable_bo->ttm);
|
||||
ret = vmw_bo_driver.ttm_tt_populate(batch->otable_bo->ttm, &ctx);
|
||||
if (unlikely(ret != 0))
|
||||
goto out_unreserve;
|
||||
ret = vmw_bo_map_dma(batch->otable_bo);
|
||||
|
@ -430,6 +434,11 @@ static int vmw_mob_pt_populate(struct vmw_private *dev_priv,
|
|||
struct vmw_mob *mob)
|
||||
{
|
||||
int ret;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = false,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
|
||||
BUG_ON(mob->pt_bo != NULL);
|
||||
|
||||
ret = ttm_bo_create(&dev_priv->bdev, mob->num_pages * PAGE_SIZE,
|
||||
|
@ -442,7 +451,7 @@ static int vmw_mob_pt_populate(struct vmw_private *dev_priv,
|
|||
ret = ttm_bo_reserve(mob->pt_bo, false, true, NULL);
|
||||
|
||||
BUG_ON(ret != 0);
|
||||
ret = vmw_bo_driver.ttm_tt_populate(mob->pt_bo->ttm);
|
||||
ret = vmw_bo_driver.ttm_tt_populate(mob->pt_bo->ttm, &ctx);
|
||||
if (unlikely(ret != 0))
|
||||
goto out_unreserve;
|
||||
ret = vmw_bo_map_dma(mob->pt_bo);
|
||||
|
|
|
@ -607,6 +607,10 @@ int vmw_dx_shader_add(struct vmw_cmdbuf_res_manager *man,
|
|||
struct vmw_dx_shader *shader;
|
||||
struct vmw_resource *res;
|
||||
struct vmw_private *dev_priv = ctx->dev_priv;
|
||||
struct ttm_operation_ctx ttm_opt_ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
int ret;
|
||||
|
||||
if (!vmw_shader_dx_size)
|
||||
|
@ -616,7 +620,7 @@ int vmw_dx_shader_add(struct vmw_cmdbuf_res_manager *man,
|
|||
return -EINVAL;
|
||||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), vmw_shader_dx_size,
|
||||
false, true);
|
||||
&ttm_opt_ctx);
|
||||
if (ret) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("Out of graphics memory for shader "
|
||||
|
@ -730,6 +734,10 @@ static int vmw_user_shader_alloc(struct vmw_private *dev_priv,
|
|||
{
|
||||
struct vmw_user_shader *ushader;
|
||||
struct vmw_resource *res, *tmp;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -742,7 +750,7 @@ static int vmw_user_shader_alloc(struct vmw_private *dev_priv,
|
|||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
|
||||
vmw_user_shader_size,
|
||||
false, true);
|
||||
&ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("Out of graphics memory for shader "
|
||||
|
@ -800,6 +808,10 @@ static struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv,
|
|||
{
|
||||
struct vmw_shader *shader;
|
||||
struct vmw_resource *res;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -812,7 +824,7 @@ static struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv,
|
|||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
|
||||
vmw_shader_size,
|
||||
false, true);
|
||||
&ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("Out of graphics memory for shader "
|
||||
|
|
|
@ -149,6 +149,10 @@ vmw_simple_resource_create_ioctl(struct drm_device *dev, void *data,
|
|||
struct vmw_resource *res;
|
||||
struct vmw_resource *tmp;
|
||||
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
size_t alloc_size;
|
||||
size_t account_size;
|
||||
int ret;
|
||||
|
@ -162,7 +166,7 @@ vmw_simple_resource_create_ioctl(struct drm_device *dev, void *data,
|
|||
return ret;
|
||||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), account_size,
|
||||
false, true);
|
||||
&ctx);
|
||||
ttm_read_unlock(&dev_priv->reservation_sem);
|
||||
if (ret) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
|
|
|
@ -329,6 +329,10 @@ int vmw_view_add(struct vmw_cmdbuf_res_manager *man,
|
|||
struct vmw_private *dev_priv = ctx->dev_priv;
|
||||
struct vmw_resource *res;
|
||||
struct vmw_view *view;
|
||||
struct ttm_operation_ctx ttm_opt_ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
size_t size;
|
||||
int ret;
|
||||
|
||||
|
@ -345,7 +349,7 @@ int vmw_view_add(struct vmw_cmdbuf_res_manager *man,
|
|||
|
||||
size = offsetof(struct vmw_view, cmd) + cmd_size;
|
||||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), size, false, true);
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), size, &ttm_opt_ctx);
|
||||
if (ret) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("Out of graphics memory for view"
|
||||
|
|
|
@ -700,6 +700,10 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
|
|||
struct drm_vmw_surface_create_req *req = &arg->req;
|
||||
struct drm_vmw_surface_arg *rep = &arg->rep;
|
||||
struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
int ret;
|
||||
int i, j;
|
||||
uint32_t cur_bo_offset;
|
||||
|
@ -741,7 +745,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
|
|||
return ret;
|
||||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
|
||||
size, false, true);
|
||||
size, &ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("Out of graphics memory for surface"
|
||||
|
@ -1479,6 +1483,10 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
|
|||
{
|
||||
struct vmw_private *dev_priv = vmw_priv(dev);
|
||||
struct vmw_user_surface *user_srf;
|
||||
struct ttm_operation_ctx ctx = {
|
||||
.interruptible = true,
|
||||
.no_wait_gpu = false
|
||||
};
|
||||
struct vmw_surface *srf;
|
||||
int ret;
|
||||
u32 num_layers;
|
||||
|
@ -1525,7 +1533,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
|
|||
return ret;
|
||||
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
|
||||
user_accounting_size, false, true);
|
||||
user_accounting_size, &ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("Out of graphics memory for surface"
|
||||
|
|
|
@ -213,9 +213,10 @@ static struct ttm_tt *vbox_ttm_tt_create(struct ttm_bo_device *bdev,
|
|||
return tt;
|
||||
}
|
||||
|
||||
static int vbox_ttm_tt_populate(struct ttm_tt *ttm)
|
||||
static int vbox_ttm_tt_populate(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
return ttm_pool_populate(ttm);
|
||||
return ttm_pool_populate(ttm, ctx);
|
||||
}
|
||||
|
||||
static void vbox_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
||||
|
|
|
@ -752,6 +752,8 @@ ssize_t ttm_bo_io(struct ttm_bo_device *bdev, struct file *filp,
|
|||
const char __user *wbuf, char __user *rbuf,
|
||||
size_t count, loff_t *f_pos, bool write);
|
||||
|
||||
int ttm_bo_swapout(struct ttm_bo_global *glob,
|
||||
struct ttm_operation_ctx *ctx);
|
||||
void ttm_bo_swapout_all(struct ttm_bo_device *bdev);
|
||||
int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo);
|
||||
#endif
|
||||
|
|
|
@ -352,7 +352,8 @@ struct ttm_bo_driver {
|
|||
* Returns:
|
||||
* -ENOMEM: Out of memory.
|
||||
*/
|
||||
int (*ttm_tt_populate)(struct ttm_tt *ttm);
|
||||
int (*ttm_tt_populate)(struct ttm_tt *ttm,
|
||||
struct ttm_operation_ctx *ctx);
|
||||
|
||||
/**
|
||||
* ttm_tt_unpopulate
|
||||
|
@ -522,7 +523,6 @@ struct ttm_bo_global {
|
|||
struct kobject kobj;
|
||||
struct ttm_mem_global *mem_glob;
|
||||
struct page *dummy_read_page;
|
||||
struct ttm_mem_shrink shrink;
|
||||
struct mutex device_list_mutex;
|
||||
spinlock_t lru_lock;
|
||||
|
||||
|
@ -650,7 +650,8 @@ void ttm_dma_tt_fini(struct ttm_dma_tt *ttm_dma);
|
|||
*
|
||||
* Bind the pages of @ttm to an aperture location identified by @bo_mem
|
||||
*/
|
||||
int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem);
|
||||
int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem,
|
||||
struct ttm_operation_ctx *ctx);
|
||||
|
||||
/**
|
||||
* ttm_ttm_destroy:
|
||||
|
@ -1078,7 +1079,7 @@ struct ttm_tt *ttm_agp_tt_create(struct ttm_bo_device *bdev,
|
|||
struct agp_bridge_data *bridge,
|
||||
unsigned long size, uint32_t page_flags,
|
||||
struct page *dummy_read_page);
|
||||
int ttm_agp_tt_populate(struct ttm_tt *ttm);
|
||||
int ttm_agp_tt_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx);
|
||||
void ttm_agp_tt_unpopulate(struct ttm_tt *ttm);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -35,20 +35,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
/**
|
||||
* struct ttm_mem_shrink - callback to shrink TTM memory usage.
|
||||
*
|
||||
* @do_shrink: The callback function.
|
||||
*
|
||||
* Arguments to the do_shrink functions are intended to be passed using
|
||||
* inheritance. That is, the argument class derives from struct ttm_mem_shrink,
|
||||
* and can be accessed using container_of().
|
||||
*/
|
||||
|
||||
struct ttm_mem_shrink {
|
||||
int (*do_shrink) (struct ttm_mem_shrink *);
|
||||
};
|
||||
#include "ttm_bo_api.h"
|
||||
|
||||
/**
|
||||
* struct ttm_mem_global - Global memory accounting structure.
|
||||
|
@ -76,7 +63,7 @@ struct ttm_mem_shrink {
|
|||
struct ttm_mem_zone;
|
||||
struct ttm_mem_global {
|
||||
struct kobject kobj;
|
||||
struct ttm_mem_shrink *shrink;
|
||||
struct ttm_bo_global *bo_glob;
|
||||
struct workqueue_struct *swap_queue;
|
||||
struct work_struct work;
|
||||
spinlock_t lock;
|
||||
|
@ -90,67 +77,15 @@ struct ttm_mem_global {
|
|||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* ttm_mem_init_shrink - initialize a struct ttm_mem_shrink object
|
||||
*
|
||||
* @shrink: The object to initialize.
|
||||
* @func: The callback function.
|
||||
*/
|
||||
|
||||
static inline void ttm_mem_init_shrink(struct ttm_mem_shrink *shrink,
|
||||
int (*func) (struct ttm_mem_shrink *))
|
||||
{
|
||||
shrink->do_shrink = func;
|
||||
}
|
||||
|
||||
/**
|
||||
* ttm_mem_register_shrink - register a struct ttm_mem_shrink object.
|
||||
*
|
||||
* @glob: The struct ttm_mem_global object to register with.
|
||||
* @shrink: An initialized struct ttm_mem_shrink object to register.
|
||||
*
|
||||
* Returns:
|
||||
* -EBUSY: There's already a callback registered. (May change).
|
||||
*/
|
||||
|
||||
static inline int ttm_mem_register_shrink(struct ttm_mem_global *glob,
|
||||
struct ttm_mem_shrink *shrink)
|
||||
{
|
||||
spin_lock(&glob->lock);
|
||||
if (glob->shrink != NULL) {
|
||||
spin_unlock(&glob->lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
glob->shrink = shrink;
|
||||
spin_unlock(&glob->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ttm_mem_unregister_shrink - unregister a struct ttm_mem_shrink object.
|
||||
*
|
||||
* @glob: The struct ttm_mem_global object to unregister from.
|
||||
* @shrink: A previously registert struct ttm_mem_shrink object.
|
||||
*
|
||||
*/
|
||||
|
||||
static inline void ttm_mem_unregister_shrink(struct ttm_mem_global *glob,
|
||||
struct ttm_mem_shrink *shrink)
|
||||
{
|
||||
spin_lock(&glob->lock);
|
||||
BUG_ON(glob->shrink != shrink);
|
||||
glob->shrink = NULL;
|
||||
spin_unlock(&glob->lock);
|
||||
}
|
||||
|
||||
extern int ttm_mem_global_init(struct ttm_mem_global *glob);
|
||||
extern void ttm_mem_global_release(struct ttm_mem_global *glob);
|
||||
extern int ttm_mem_global_alloc(struct ttm_mem_global *glob, uint64_t memory,
|
||||
bool no_wait, bool interruptible);
|
||||
struct ttm_operation_ctx *ctx);
|
||||
extern void ttm_mem_global_free(struct ttm_mem_global *glob,
|
||||
uint64_t amount);
|
||||
extern int ttm_mem_global_alloc_page(struct ttm_mem_global *glob,
|
||||
struct page *page, uint64_t size);
|
||||
struct page *page, uint64_t size,
|
||||
struct ttm_operation_ctx *ctx);
|
||||
extern void ttm_mem_global_free_page(struct ttm_mem_global *glob,
|
||||
struct page *page, uint64_t size);
|
||||
extern size_t ttm_round_pot(size_t size);
|
||||
|
|
|
@ -47,7 +47,7 @@ void ttm_page_alloc_fini(void);
|
|||
*
|
||||
* Add backing pages to all of @ttm
|
||||
*/
|
||||
int ttm_pool_populate(struct ttm_tt *ttm);
|
||||
int ttm_pool_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx);
|
||||
|
||||
/**
|
||||
* ttm_pool_unpopulate:
|
||||
|
@ -61,7 +61,8 @@ void ttm_pool_unpopulate(struct ttm_tt *ttm);
|
|||
/**
|
||||
* Populates and DMA maps pages to fullfil a ttm_dma_populate() request
|
||||
*/
|
||||
int ttm_populate_and_map_pages(struct device *dev, struct ttm_dma_tt *tt);
|
||||
int ttm_populate_and_map_pages(struct device *dev, struct ttm_dma_tt *tt,
|
||||
struct ttm_operation_ctx *ctx);
|
||||
|
||||
/**
|
||||
* Unpopulates and DMA unmaps pages as part of a
|
||||
|
@ -89,7 +90,8 @@ void ttm_dma_page_alloc_fini(void);
|
|||
*/
|
||||
int ttm_dma_page_alloc_debugfs(struct seq_file *m, void *data);
|
||||
|
||||
int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev);
|
||||
int ttm_dma_populate(struct ttm_dma_tt *ttm_dma, struct device *dev,
|
||||
struct ttm_operation_ctx *ctx);
|
||||
void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev);
|
||||
|
||||
#else
|
||||
|
@ -106,7 +108,8 @@ static inline int ttm_dma_page_alloc_debugfs(struct seq_file *m, void *data)
|
|||
return 0;
|
||||
}
|
||||
static inline int ttm_dma_populate(struct ttm_dma_tt *ttm_dma,
|
||||
struct device *dev)
|
||||
struct device *dev,
|
||||
struct ttm_operation_ctx *ctx)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue