/* * Copyright 2019 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.
*/
if (fence && !p->immediate) { /* * Most hw generations now have a separate queue for page table * updates, but when the queue is shared with userspace we need * the extra CPU round trip to correctly flush the TLB.
*/
set_bit(DRM_SCHED_FENCE_DONT_PIPELINE, &f->flags);
swap(*fence, f);
}
dma_fence_put(f); return 0;
}
/** * amdgpu_vm_sdma_copy_ptes - copy the PTEs from mapping * * @p: see amdgpu_vm_update_params definition * @bo: PD/PT to update * @pe: addr of the page entry * @count: number of page entries to copy * * Traces the parameters and calls the DMA function to copy the PTEs.
*/ staticvoid amdgpu_vm_sdma_copy_ptes(struct amdgpu_vm_update_params *p, struct amdgpu_bo *bo, uint64_t pe, unsigned count)
{ struct amdgpu_ib *ib = p->job->ibs;
uint64_t src = ib->gpu_addr;
src += p->num_dw_left * 4;
pe += amdgpu_bo_gpu_offset_no_check(bo);
trace_amdgpu_vm_copy_ptes(pe, src, count, p->immediate);
/** * amdgpu_vm_sdma_set_ptes - helper to call the right asic function * * @p: see amdgpu_vm_update_params definition * @bo: PD/PT to update * @pe: byte offset of the PDE/PTE, relative to start of PDB/PTB * @addr: dst addr to write into pe * @count: number of page entries to update * @incr: increase next addr by incr bytes * @flags: hw access flags * * Traces the parameters and calls the right asic functions * to setup the page table using the DMA.
*/ staticvoid amdgpu_vm_sdma_set_ptes(struct amdgpu_vm_update_params *p, struct amdgpu_bo *bo, uint64_t pe,
uint64_t addr, unsigned count,
uint32_t incr, uint64_t flags)
{ struct amdgpu_ib *ib = p->job->ibs;
/** * amdgpu_vm_sdma_update - execute VM update * * @p: see amdgpu_vm_update_params definition * @vmbo: PD/PT to update * @pe: byte offset of the PDE/PTE, relative to start of PDB/PTB * @addr: dst addr to write into pe * @count: number of page entries to update * @incr: increase next addr by incr bytes * @flags: hw access flags * * Reserve space in the IB, setup mapping buffer on demand and write commands to * the IB.
*/ staticint amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p, struct amdgpu_bo_vm *vmbo, uint64_t pe,
uint64_t addr, unsigned count, uint32_t incr,
uint64_t flags)
{ struct amdgpu_bo *bo = &vmbo->bo; struct dma_resv_iter cursor; unsignedint i, ndw, nptes; struct dma_fence *fence;
uint64_t *pte; int r;
/* Wait for PD/PT moves to be completed */
dma_resv_iter_begin(&cursor, bo->tbo.base.resv, DMA_RESV_USAGE_KERNEL);
dma_resv_for_each_fence_unlocked(&cursor, fence) {
dma_fence_get(fence);
r = drm_sched_job_add_dependency(&p->job->base, fence); if (r) {
dma_fence_put(fence);
dma_resv_iter_end(&cursor); return r;
}
}
dma_resv_iter_end(&cursor);
do {
ndw = p->num_dw_left;
ndw -= p->job->ibs->length_dw;
if (ndw < 32) {
r = amdgpu_vm_sdma_commit(p, NULL); if (r) return r;
r = amdgpu_vm_sdma_alloc_job(p, count); if (r) return r;
}
if (!p->pages_addr) { /* set page commands needed */
amdgpu_vm_sdma_set_ptes(p, bo, pe, addr, count,
incr, flags); return 0;
}
/* Put the PTEs at the end of the IB. */
p->num_dw_left -= nptes * 2;
pte = (uint64_t *)&(p->job->ibs->ptr[p->num_dw_left]); for (i = 0; i < nptes; ++i, addr += incr) {
pte[i] = amdgpu_vm_map_gart(p->pages_addr, addr);
pte[i] |= flags;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.