};
struct radeon_fence {
- struct fence base;
+ struct fence base;
- struct radeon_device *rdev;
- uint64_t seq;
+ struct radeon_device *rdev;
+ uint64_t seq;
/* RB, DMA, etc. */
- unsigned ring;
+ unsigned ring;
+ bool is_vm_update;
- wait_queue_t fence_wake;
+ wait_queue_t fence_wake;
};
int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
struct radeon_sync {
struct radeon_semaphore *semaphores[RADEON_NUM_SYNCS];
struct radeon_fence *sync_to[RADEON_NUM_RINGS];
+ struct radeon_fence *last_vm_update;
};
void radeon_sync_create(struct radeon_sync *sync);
struct mutex mutex;
/* last fence for cs using this vm */
struct radeon_fence *fence;
- /* last flush or NULL if we still need to flush */
- struct radeon_fence *last_flush;
+ /* last flushed PD/PT update */
+ struct radeon_fence *flushed_updates;
/* last use of vmid */
struct radeon_fence *last_id_use;
};
struct radeon_vm *vm, int ring);
void radeon_vm_flush(struct radeon_device *rdev,
struct radeon_vm *vm,
- int ring);
+ int ring, struct radeon_fence *fence);
void radeon_vm_fence(struct radeon_device *rdev,
struct radeon_vm *vm,
struct radeon_fence *fence);
return NULL;
/* we definately need to flush */
- radeon_fence_unref(&vm->last_flush);
+ vm->pd_gpu_addr = ~0ll;
/* skip over VMID 0, since it is the system VM */
for (i = 1; i < rdev->vm_manager.nvm; ++i) {
* @rdev: radeon_device pointer
* @vm: vm we want to flush
* @ring: ring to use for flush
+ * @updates: last vm update that is waited for
*
* Flush the vm (cayman+).
*
*/
void radeon_vm_flush(struct radeon_device *rdev,
struct radeon_vm *vm,
- int ring)
+ int ring, struct radeon_fence *updates)
{
uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory);
- /* if we can't remember our last VM flush then flush now! */
- if (!vm->last_flush || pd_addr != vm->pd_gpu_addr) {
+ if (pd_addr != vm->pd_gpu_addr || !vm->flushed_updates ||
+ radeon_fence_is_earlier(vm->flushed_updates, updates)) {
+
trace_radeon_vm_flush(pd_addr, ring, vm->id);
+ radeon_fence_unref(&vm->flushed_updates);
+ vm->flushed_updates = radeon_fence_ref(updates);
vm->pd_gpu_addr = pd_addr;
radeon_ring_vm_flush(rdev, &rdev->ring[ring],
vm->id, vm->pd_gpu_addr);
radeon_fence_unref(&vm->last_id_use);
vm->last_id_use = radeon_fence_ref(fence);
-
- /* we just flushed the VM, remember that */
- if (!vm->last_flush)
- vm->last_flush = radeon_fence_ref(fence);
}
/**
if (r)
goto error_free;
+ ib.fence->is_vm_update = true;
radeon_bo_fence(bo, ib.fence, false);
error_free:
radeon_ib_free(rdev, &ib);
return r;
}
+ ib.fence->is_vm_update = true;
radeon_bo_fence(pd, ib.fence, false);
radeon_fence_unref(&vm->fence);
vm->fence = radeon_fence_ref(ib.fence);
- radeon_fence_unref(&vm->last_flush);
}
radeon_ib_free(rdev, &ib);
radeon_ib_free(rdev, &ib);
return r;
}
+ ib.fence->is_vm_update = true;
radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence);
radeon_fence_unref(&vm->fence);
vm->fence = radeon_fence_ref(ib.fence);
radeon_ib_free(rdev, &ib);
- radeon_fence_unref(&vm->last_flush);
return 0;
}
vm->id = 0;
vm->ib_bo_va = NULL;
vm->fence = NULL;
- vm->last_flush = NULL;
+ vm->flushed_updates = NULL;
vm->last_id_use = NULL;
mutex_init(&vm->mutex);
vm->va = RB_ROOT;
radeon_bo_unref(&vm->page_directory);
radeon_fence_unref(&vm->fence);
- radeon_fence_unref(&vm->last_flush);
+ radeon_fence_unref(&vm->flushed_updates);
radeon_fence_unref(&vm->last_id_use);
mutex_destroy(&vm->mutex);