drm/amdgpu: add a VM mapping replace operation v2
Add a new operation to replace mappings in a VM with a new one. v2: Fix Jerry's comment, separate out clear operation. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
dc54d3d174
commit
80f95c579d
@ -544,7 +544,8 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev,
|
||||
if (r)
|
||||
goto error;
|
||||
|
||||
if (operation == AMDGPU_VA_OP_MAP)
|
||||
if (operation == AMDGPU_VA_OP_MAP ||
|
||||
operation == AMDGPU_VA_OP_REPLACE)
|
||||
r = amdgpu_vm_bo_update(adev, bo_va, false);
|
||||
|
||||
error:
|
||||
@ -595,6 +596,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
||||
case AMDGPU_VA_OP_MAP:
|
||||
case AMDGPU_VA_OP_UNMAP:
|
||||
case AMDGPU_VA_OP_CLEAR:
|
||||
case AMDGPU_VA_OP_REPLACE:
|
||||
break;
|
||||
default:
|
||||
dev_err(&dev->pdev->dev, "unsupported operation %d\n",
|
||||
@ -656,6 +658,17 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
|
||||
args->va_address,
|
||||
args->map_size);
|
||||
break;
|
||||
case AMDGPU_VA_OP_REPLACE:
|
||||
r = amdgpu_vm_alloc_pts(adev, bo_va->vm, args->va_address,
|
||||
args->map_size);
|
||||
if (r)
|
||||
goto error_backoff;
|
||||
|
||||
va_flags = amdgpu_vm_get_pte_flags(adev, args->flags);
|
||||
r = amdgpu_vm_bo_replace_map(adev, bo_va, args->va_address,
|
||||
args->offset_in_bo, args->map_size,
|
||||
va_flags);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1560,6 +1560,70 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_bo_replace_map - map bo inside a vm, replacing existing mappings
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @bo_va: bo_va to store the address
|
||||
* @saddr: where to map the BO
|
||||
* @offset: requested offset in the BO
|
||||
* @flags: attributes of pages (read/write/valid/etc.)
|
||||
*
|
||||
* Add a mapping of the BO at the specefied addr into the VM. Replace existing
|
||||
* mappings as we do so.
|
||||
* Returns 0 for success, error for failure.
|
||||
*
|
||||
* Object has to be reserved and unreserved outside!
|
||||
*/
|
||||
int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo_va *bo_va,
|
||||
uint64_t saddr, uint64_t offset,
|
||||
uint64_t size, uint64_t flags)
|
||||
{
|
||||
struct amdgpu_bo_va_mapping *mapping;
|
||||
struct amdgpu_vm *vm = bo_va->vm;
|
||||
uint64_t eaddr;
|
||||
int r;
|
||||
|
||||
/* validate the parameters */
|
||||
if (saddr & AMDGPU_GPU_PAGE_MASK || offset & AMDGPU_GPU_PAGE_MASK ||
|
||||
size == 0 || size & AMDGPU_GPU_PAGE_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
/* make sure object fit at this offset */
|
||||
eaddr = saddr + size - 1;
|
||||
if (saddr >= eaddr ||
|
||||
(bo_va->bo && offset + size > amdgpu_bo_size(bo_va->bo)))
|
||||
return -EINVAL;
|
||||
|
||||
/* Allocate all the needed memory */
|
||||
mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
|
||||
if (!mapping)
|
||||
return -ENOMEM;
|
||||
|
||||
r = amdgpu_vm_bo_clear_mappings(adev, bo_va->vm, saddr, size);
|
||||
if (r) {
|
||||
kfree(mapping);
|
||||
return r;
|
||||
}
|
||||
|
||||
saddr /= AMDGPU_GPU_PAGE_SIZE;
|
||||
eaddr /= AMDGPU_GPU_PAGE_SIZE;
|
||||
|
||||
mapping->it.start = saddr;
|
||||
mapping->it.last = eaddr;
|
||||
mapping->offset = offset;
|
||||
mapping->flags = flags;
|
||||
|
||||
list_add(&mapping->list, &bo_va->invalids);
|
||||
interval_tree_insert(&mapping->it, &vm->va);
|
||||
|
||||
if (flags & AMDGPU_PTE_PRT)
|
||||
amdgpu_vm_prt_get(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_vm_bo_unmap - remove bo mapping from vm
|
||||
*
|
||||
|
@ -207,6 +207,10 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo_va *bo_va,
|
||||
uint64_t addr, uint64_t offset,
|
||||
uint64_t size, uint64_t flags);
|
||||
int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo_va *bo_va,
|
||||
uint64_t addr, uint64_t offset,
|
||||
uint64_t size, uint64_t flags);
|
||||
int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
|
||||
struct amdgpu_bo_va *bo_va,
|
||||
uint64_t addr);
|
||||
|
@ -351,6 +351,7 @@ struct drm_amdgpu_gem_op {
|
||||
#define AMDGPU_VA_OP_MAP 1
|
||||
#define AMDGPU_VA_OP_UNMAP 2
|
||||
#define AMDGPU_VA_OP_CLEAR 3
|
||||
#define AMDGPU_VA_OP_REPLACE 4
|
||||
|
||||
/* Delay the page table update till the next CS */
|
||||
#define AMDGPU_VM_DELAY_UPDATE (1 << 0)
|
||||
|
Loading…
Reference in New Issue
Block a user