On 16.12.2016 03:49, zhoucm1 wrote: > On 2016å¹´12æ??16æ?¥ 01:10, Nicolai Hähnle wrote: >> From: Nicolai Hähnle <nicolai.haehnle at amd.com> >> >> Ensure that the driver can listen to evictions even when they don't >> take the >> path through ttm_bo_driver::move. >> >> This is crucial for amdgpu, which relies on an eviction counter to skip >> re-binding page tables when possible. >> >> Signed-off-by: Nicolai Hähnle <nicolai.haehnle at amd.com> > Acked-by: Chunming Zhou <david1.zhou at amd.com> Thanks. Ping for feedback from non-AMD people? Nicolai >> --- >> drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 1 + >> drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 3 ++- >> drivers/gpu/drm/nouveau/nouveau_bo.c | 3 ++- >> drivers/gpu/drm/qxl/qxl_ttm.c | 1 + >> drivers/gpu/drm/radeon/radeon_object.c | 1 + >> drivers/gpu/drm/radeon/radeon_object.h | 1 + >> drivers/gpu/drm/ttm/ttm_bo.c | 8 ++++---- >> drivers/gpu/drm/virtio/virtgpu_ttm.c | 1 + >> drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c | 1 + >> include/drm/ttm/ttm_bo_driver.h | 10 ++++++++-- >> 10 files changed, 22 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c >> index bf79b73..c29db99 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c >> @@ -842,20 +842,21 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, >> void *buffer, >> if (metadata_size) >> *metadata_size = bo->metadata_size; >> if (flags) >> *flags = bo->metadata_flags; >> return 0; >> } >> void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, >> + bool evict, >> struct ttm_mem_reg *new_mem) >> { >> struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); >> struct amdgpu_bo *abo; >> struct ttm_mem_reg *old_mem = &bo->mem; >> if (!amdgpu_ttm_bo_is_amdgpu_bo(bo)) >> return; >> abo = container_of(bo, struct amdgpu_bo, tbo); >> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h >> b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h >> index 5cbf59e..4306b2f 100644 >> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h >> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h >> @@ -148,21 +148,22 @@ void amdgpu_bo_fini(struct amdgpu_device *adev); >> int amdgpu_bo_fbdev_mmap(struct amdgpu_bo *bo, >> struct vm_area_struct *vma); >> int amdgpu_bo_set_tiling_flags(struct amdgpu_bo *bo, u64 tiling_flags); >> void amdgpu_bo_get_tiling_flags(struct amdgpu_bo *bo, u64 >> *tiling_flags); >> int amdgpu_bo_set_metadata (struct amdgpu_bo *bo, void *metadata, >> uint32_t metadata_size, uint64_t flags); >> int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, >> size_t buffer_size, uint32_t *metadata_size, >> uint64_t *flags); >> void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, >> - struct ttm_mem_reg *new_mem); >> + bool evict, >> + struct ttm_mem_reg *new_mem); >> int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); >> void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, >> bool shared); >> u64 amdgpu_bo_gpu_offset(struct amdgpu_bo *bo); >> int amdgpu_bo_backup_to_shadow(struct amdgpu_device *adev, >> struct amdgpu_ring *ring, >> struct amdgpu_bo *bo, >> struct reservation_object *resv, >> struct dma_fence **fence, bool direct); >> int amdgpu_bo_restore_from_shadow(struct amdgpu_device *adev, >> diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c >> b/drivers/gpu/drm/nouveau/nouveau_bo.c >> index e0c0007..6fa1521 100644 >> --- a/drivers/gpu/drm/nouveau/nouveau_bo.c >> +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c >> @@ -1187,21 +1187,22 @@ nouveau_bo_move_flips(struct ttm_buffer_object >> *bo, bool evict, bool intr, >> ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_gpu, new_mem); >> if (ret) >> goto out; >> out: >> ttm_bo_mem_put(bo, &tmp_mem); >> return ret; >> } >> static void >> -nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg >> *new_mem) >> +nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, >> + struct ttm_mem_reg *new_mem) >> { >> struct nouveau_bo *nvbo = nouveau_bo(bo); >> struct nvkm_vma *vma; >> /* ttm can now (stupidly) pass the driver bos it didn't >> create... */ >> if (bo->destroy != nouveau_bo_del_ttm) >> return; >> list_for_each_entry(vma, &nvbo->vma_list, head) { >> if (new_mem && new_mem->mem_type != TTM_PL_SYSTEM && >> diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c >> b/drivers/gpu/drm/qxl/qxl_ttm.c >> index 1176133..f3939a9 100644 >> --- a/drivers/gpu/drm/qxl/qxl_ttm.c >> +++ b/drivers/gpu/drm/qxl/qxl_ttm.c >> @@ -360,20 +360,21 @@ static int qxl_bo_move(struct ttm_buffer_object >> *bo, >> if (old_mem->mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) { >> qxl_move_null(bo, new_mem); >> return 0; >> } >> return ttm_bo_move_memcpy(bo, interruptible, no_wait_gpu, >> new_mem); >> } >> static void qxl_bo_move_notify(struct ttm_buffer_object *bo, >> + bool evict, >> struct ttm_mem_reg *new_mem) >> { >> struct qxl_bo *qbo; >> struct qxl_device *qdev; >> if (!qxl_ttm_bo_is_qxl_bo(bo)) >> return; >> qbo = to_qxl_bo(bo); >> qdev = qbo->gem_base.dev->dev_private; >> diff --git a/drivers/gpu/drm/radeon/radeon_object.c >> b/drivers/gpu/drm/radeon/radeon_object.c >> index 41b72ce..74b2760 100644 >> --- a/drivers/gpu/drm/radeon/radeon_object.c >> +++ b/drivers/gpu/drm/radeon/radeon_object.c >> @@ -758,20 +758,21 @@ int radeon_bo_check_tiling(struct radeon_bo *bo, >> bool has_moved, >> return 0; >> } >> if ((bo->surface_reg >= 0) && !has_moved) >> return 0; >> return radeon_bo_get_surface_reg(bo); >> } >> void radeon_bo_move_notify(struct ttm_buffer_object *bo, >> + bool evict, >> struct ttm_mem_reg *new_mem) >> { >> struct radeon_bo *rbo; >> if (!radeon_ttm_bo_is_radeon_bo(bo)) >> return; >> rbo = container_of(bo, struct radeon_bo, tbo); >> radeon_bo_check_tiling(rbo, 0, 1); >> radeon_vm_bo_invalidate(rbo->rdev, rbo); >> diff --git a/drivers/gpu/drm/radeon/radeon_object.h >> b/drivers/gpu/drm/radeon/radeon_object.h >> index a10bb3d..9ffd821 100644 >> --- a/drivers/gpu/drm/radeon/radeon_object.h >> +++ b/drivers/gpu/drm/radeon/radeon_object.h >> @@ -143,20 +143,21 @@ extern void radeon_bo_fini(struct radeon_device >> *rdev); >> extern int radeon_bo_list_validate(struct radeon_device *rdev, >> struct ww_acquire_ctx *ticket, >> struct list_head *head, int ring); >> extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, >> u32 tiling_flags, u32 pitch); >> extern void radeon_bo_get_tiling_flags(struct radeon_bo *bo, >> u32 *tiling_flags, u32 *pitch); >> extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, >> bool force_drop); >> extern void radeon_bo_move_notify(struct ttm_buffer_object *bo, >> + bool evict, >> struct ttm_mem_reg *new_mem); >> extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object >> *bo); >> extern int radeon_bo_get_surface_reg(struct radeon_bo *bo); >> extern void radeon_bo_fence(struct radeon_bo *bo, struct >> radeon_fence *fence, >> bool shared); >> /* >> * sub allocation >> */ >> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c >> b/drivers/gpu/drm/ttm/ttm_bo.c >> index d506361..d4973e9c 100644 >> --- a/drivers/gpu/drm/ttm/ttm_bo.c >> +++ b/drivers/gpu/drm/ttm/ttm_bo.c >> @@ -335,45 +335,45 @@ 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); >> if (ret) >> goto out_err; >> } >> if (bo->mem.mem_type == TTM_PL_SYSTEM) { >> if (bdev->driver->move_notify) >> - bdev->driver->move_notify(bo, mem); >> + bdev->driver->move_notify(bo, evict, mem); >> bo->mem = *mem; >> mem->mm_node = NULL; >> goto moved; >> } >> } >> if (bdev->driver->move_notify) >> - bdev->driver->move_notify(bo, mem); >> + bdev->driver->move_notify(bo, evict, mem); >> if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && >> !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) >> ret = ttm_bo_move_ttm(bo, interruptible, no_wait_gpu, mem); >> else if (bdev->driver->move) >> ret = bdev->driver->move(bo, evict, interruptible, >> no_wait_gpu, mem); >> else >> ret = ttm_bo_move_memcpy(bo, interruptible, no_wait_gpu, mem); >> if (ret) { >> if (bdev->driver->move_notify) { >> struct ttm_mem_reg tmp_mem = *mem; >> *mem = bo->mem; >> bo->mem = tmp_mem; >> - bdev->driver->move_notify(bo, mem); >> + bdev->driver->move_notify(bo, false, mem); >> bo->mem = *mem; >> *mem = tmp_mem; >> } >> goto out_err; >> } >> moved: >> if (bo->evicted) { >> if (bdev->driver->invalidate_caches) { >> @@ -407,21 +407,21 @@ static int ttm_bo_handle_move_mem(struct >> ttm_buffer_object *bo, >> * Call bo::reserved. >> * Will release GPU memory type usage on destruction. >> * This is the place to put in driver specific hooks to release >> * driver private resources. >> * Will release the bo::reserved lock. >> */ >> static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) >> { >> if (bo->bdev->driver->move_notify) >> - bo->bdev->driver->move_notify(bo, NULL); >> + bo->bdev->driver->move_notify(bo, false, NULL); >> ttm_tt_destroy(bo->ttm); >> bo->ttm = NULL; >> ttm_bo_mem_put(bo, &bo->mem); >> ww_mutex_unlock (&bo->resv->lock); >> } >> static void ttm_bo_flush_all_fences(struct ttm_buffer_object *bo) >> { >> diff --git a/drivers/gpu/drm/virtio/virtgpu_ttm.c >> b/drivers/gpu/drm/virtio/virtgpu_ttm.c >> index 4a1de9f..10387d7 100644 >> --- a/drivers/gpu/drm/virtio/virtgpu_ttm.c >> +++ b/drivers/gpu/drm/virtio/virtgpu_ttm.c >> @@ -379,20 +379,21 @@ static int virtio_gpu_bo_move(struct >> ttm_buffer_object *bo, >> ret = ttm_bo_wait(bo, interruptible, no_wait_gpu); >> if (ret) >> return ret; >> virtio_gpu_move_null(bo, new_mem); >> return 0; >> } >> static void virtio_gpu_bo_move_notify(struct ttm_buffer_object *tbo, >> + bool evict, >> struct ttm_mem_reg *new_mem) >> { >> struct virtio_gpu_object *bo; >> struct virtio_gpu_device *vgdev; >> bo = container_of(tbo, struct virtio_gpu_object, tbo); >> vgdev = (struct virtio_gpu_device *)bo->gem_base.dev->dev_private; >> if (!new_mem || (new_mem->placement & TTM_PL_FLAG_SYSTEM)) { >> if (bo->hw_res_handle) >> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c >> b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c >> index c894a48..caa279b 100644 >> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c >> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c >> @@ -818,20 +818,21 @@ static int vmw_ttm_fault_reserve_notify(struct >> ttm_buffer_object *bo) >> * vmw_move_notify - TTM move_notify_callback >> * >> * @bo: The TTM buffer object about to move. >> * @mem: The struct ttm_mem_reg indicating to what memory >> * region the move is taking place. >> * >> * Calls move_notify for all subsystems needing it. >> * (currently only resources). >> */ >> static void vmw_move_notify(struct ttm_buffer_object *bo, >> + bool evict, >> struct ttm_mem_reg *mem) >> { >> vmw_resource_move_notify(bo, mem); >> vmw_query_move_notify(bo, mem); >> } >> /** >> * vmw_swap_notify - TTM move_notify_callback >> * >> diff --git a/include/drm/ttm/ttm_bo_driver.h >> b/include/drm/ttm/ttm_bo_driver.h >> index cdbdb40..8b4bec7 100644 >> --- a/include/drm/ttm/ttm_bo_driver.h >> +++ b/include/drm/ttm/ttm_bo_driver.h >> @@ -424,23 +424,29 @@ struct ttm_bo_driver { >> * >> * Called from the map / write / read methods to verify that the >> * caller is permitted to access the buffer object. >> * This member may be set to NULL, which will refuse this kind of >> * access for all buffer objects. >> * This function should return 0 if access is granted, -EPERM >> otherwise. >> */ >> int (*verify_access)(struct ttm_buffer_object *bo, >> struct file *filp); >> - /* hook to notify driver about a driver move so it >> - * can do tiling things */ >> + /** >> + * Hook to notify driver about a driver move so it >> + * can do tiling things and book-keeping. >> + * >> + * @evict: whether this move is evicting the buffer from the >> graphics >> + * address space >> + */ >> void (*move_notify)(struct ttm_buffer_object *bo, >> + bool evict, >> struct ttm_mem_reg *new_mem); >> /* notify the driver we are taking a fault on this BO >> * and have reserved it */ >> int (*fault_reserve_notify)(struct ttm_buffer_object *bo); >> /** >> * notify the driver that we're about to swap out this bo >> */ >> void (*swap_notify)(struct ttm_buffer_object *bo); >> >