Am 05.08.2016 um 11:40 schrieb Michel Dänzer: > From: Michel Dänzer <michel.daenzer at amd.com> > > Fixes hangs under memory pressure, e.g. running the piglit test > tex3d-maxsize concurrently with other tests. > > Fixes: 17d33bc9d6ef ("drm/ttm: drop waiting for idle in ttm_bo_evict.") > Signed-off-by: Michel Dänzer <michel.daenzer at amd.com> Ah, yes of course. Good catch, patch is Reviewed-by: Christian König <christian.koenig at amd.com>. Regards, Christian. > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 4 ++-- > drivers/gpu/drm/nouveau/nouveau_bo.c | 4 ++-- > drivers/gpu/drm/radeon/radeon_ttm.c | 4 ++-- > drivers/gpu/drm/ttm/ttm_bo.c | 3 ++- > drivers/gpu/drm/ttm/ttm_bo_util.c | 10 +++++++++- > include/drm/ttm/ttm_bo_driver.h | 3 ++- > 6 files changed, 19 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > index b7742e6..9b61c8b 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > @@ -335,7 +335,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, > if (unlikely(r)) { > goto out_cleanup; > } > - r = ttm_bo_move_ttm(bo, true, no_wait_gpu, new_mem); > + r = ttm_bo_move_ttm(bo, true, interruptible, no_wait_gpu, new_mem); > out_cleanup: > ttm_bo_mem_put(bo, &tmp_mem); > return r; > @@ -368,7 +368,7 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, > if (unlikely(r)) { > return r; > } > - r = ttm_bo_move_ttm(bo, true, no_wait_gpu, &tmp_mem); > + r = ttm_bo_move_ttm(bo, true, interruptible, no_wait_gpu, &tmp_mem); > if (unlikely(r)) { > goto out_cleanup; > } > diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c > index 528bdef..6190035 100644 > --- a/drivers/gpu/drm/nouveau/nouveau_bo.c > +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c > @@ -1151,7 +1151,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, > if (ret) > goto out; > > - ret = ttm_bo_move_ttm(bo, true, no_wait_gpu, new_mem); > + ret = ttm_bo_move_ttm(bo, true, intr, no_wait_gpu, new_mem); > out: > ttm_bo_mem_put(bo, &tmp_mem); > return ret; > @@ -1179,7 +1179,7 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, > if (ret) > return ret; > > - ret = ttm_bo_move_ttm(bo, true, no_wait_gpu, &tmp_mem); > + ret = ttm_bo_move_ttm(bo, true, intr, no_wait_gpu, &tmp_mem); > if (ret) > goto out; > > diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c > index 1cb7266..557ef0c 100644 > --- a/drivers/gpu/drm/radeon/radeon_ttm.c > +++ b/drivers/gpu/drm/radeon/radeon_ttm.c > @@ -346,7 +346,7 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, > if (unlikely(r)) { > goto out_cleanup; > } > - r = ttm_bo_move_ttm(bo, true, no_wait_gpu, new_mem); > + r = ttm_bo_move_ttm(bo, true, interruptible, no_wait_gpu, new_mem); > out_cleanup: > ttm_bo_mem_put(bo, &tmp_mem); > return r; > @@ -379,7 +379,7 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo, > if (unlikely(r)) { > return r; > } > - r = ttm_bo_move_ttm(bo, true, no_wait_gpu, &tmp_mem); > + r = ttm_bo_move_ttm(bo, true, interruptible, no_wait_gpu, &tmp_mem); > if (unlikely(r)) { > goto out_cleanup; > } > diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c > index 3452748..f078038 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo.c > +++ b/drivers/gpu/drm/ttm/ttm_bo.c > @@ -355,7 +355,8 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, > > if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) && > !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) > - ret = ttm_bo_move_ttm(bo, evict, no_wait_gpu, mem); > + ret = ttm_bo_move_ttm(bo, evict, interruptible, no_wait_gpu, > + mem); > else if (bdev->driver->move) > ret = bdev->driver->move(bo, evict, interruptible, > no_wait_gpu, mem); > diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c > index 2df602a..f157a9e 100644 > --- a/drivers/gpu/drm/ttm/ttm_bo_util.c > +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c > @@ -45,7 +45,7 @@ void ttm_bo_free_old_node(struct ttm_buffer_object *bo) > } > > int ttm_bo_move_ttm(struct ttm_buffer_object *bo, > - bool evict, > + bool evict, bool interruptible, > bool no_wait_gpu, struct ttm_mem_reg *new_mem) > { > struct ttm_tt *ttm = bo->ttm; > @@ -53,6 +53,14 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo, > int ret; > > if (old_mem->mem_type != TTM_PL_SYSTEM) { > + ret = ttm_bo_wait(bo, interruptible, no_wait_gpu); > + > + if (unlikely(ret != 0)) { > + if (ret != -ERESTARTSYS) > + pr_err("Failed to expire sync object before unbinding TTM\n"); > + return ret; > + } > + > ttm_tt_unbind(ttm); > ttm_bo_free_old_node(bo); > ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM, > diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h > index 4348d6d..99c6d01 100644 > --- a/include/drm/ttm/ttm_bo_driver.h > +++ b/include/drm/ttm/ttm_bo_driver.h > @@ -962,6 +962,7 @@ void ttm_mem_io_free(struct ttm_bo_device *bdev, > * > * @bo: A pointer to a struct ttm_buffer_object. > * @evict: 1: This is an eviction. Don't try to pipeline. > + * @interruptible: Sleep interruptible if waiting. > * @no_wait_gpu: Return immediately if the GPU is busy. > * @new_mem: struct ttm_mem_reg indicating where to move. > * > @@ -976,7 +977,7 @@ void ttm_mem_io_free(struct ttm_bo_device *bdev, > */ > > extern int ttm_bo_move_ttm(struct ttm_buffer_object *bo, > - bool evict, bool no_wait_gpu, > + bool evict, bool interruptible, bool no_wait_gpu, > struct ttm_mem_reg *new_mem); > > /**