[PATCH] drm/ttm: Use RCU for ttm_mem_type_manager.move fence
Christian König
christian.koenig at amd.com
Mon Aug 29 17:09:07 UTC 2016
Am 29.08.2016 um 18:57 schrieb Chris Wilson:
> The ttm_mem_type_manager.move tracks the fence for the last migration on
> the memory manager. Currently it is accessed under its own spinlock to
> ensure that the fence doesn't disappear from underneath it. We can
> translate the reader to acquire a reference to the fence using
> fence_get_rcu_safe() which ensures that the fence cannot be reallocated
> as the reference is acquired.
>
> Suggested-by: Christian König <christian.koenig at amd.com>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Christian König <christian.koenig at amd.com>
Reviewed-by: Christian König <christian.koenig at amd.com>.
> ---
> drivers/gpu/drm/ttm/ttm_bo.c | 24 ++++++++++++++++--------
> drivers/gpu/drm/ttm/ttm_bo_util.c | 12 ++++++++----
> include/drm/ttm/ttm_bo_driver.h | 2 +-
> 3 files changed, 25 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index 42c074a9c955..422d9b39d8ae 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -797,9 +797,9 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo,
> struct fence *fence;
> int ret;
>
> - spin_lock(&man->move_lock);
> - fence = fence_get(man->move);
> - spin_unlock(&man->move_lock);
> + rcu_read_lock();
> + fence = fence_get_rcu_safe(&man->move);
> + rcu_read_unlock();
>
> if (fence) {
> reservation_object_add_shared_fence(bo->resv, fence);
> @@ -1310,9 +1310,9 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
> }
> spin_unlock(&glob->lru_lock);
>
> - spin_lock(&man->move_lock);
> - fence = fence_get(man->move);
> - spin_unlock(&man->move_lock);
> + rcu_read_lock();
> + fence = fence_get_rcu_safe(&man->move);
> + rcu_read_unlock();
>
> if (fence) {
> ret = fence_wait(fence, false);
> @@ -1332,6 +1332,7 @@ static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
> int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
> {
> struct ttm_mem_type_manager *man;
> + struct fence *last_move;
> int ret = -EINVAL;
>
> if (mem_type >= TTM_NUM_MEM_TYPES) {
> @@ -1345,7 +1346,14 @@ int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
> mem_type);
> return ret;
> }
> - fence_put(man->move);
> +
> + /* The locking here is overkill; but harmless and documentary */
> + spin_lock(&man->move_lock);
> + last_move = rcu_dereference_protected(man->move,
> + spin_is_locked(&man->move_lock));
> + rcu_assign_pointer(man->move, NULL);
> + spin_unlock(&man->move_lock);
> + fence_put(last_move);
>
> man->use_type = false;
> man->has_type = false;
> @@ -1410,7 +1418,7 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
> man->size = p_size;
>
> INIT_LIST_HEAD(&man->lru);
> - man->move = NULL;
> + RCU_INIT_POINTER(man->move, NULL);
>
> return 0;
> }
> diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
> index f157a9efd220..cd675d503ee4 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo_util.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
> @@ -755,6 +755,7 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo,
> ttm_bo_unref(&ghost_obj);
>
> } else if (from->flags & TTM_MEMTYPE_FLAG_FIXED) {
> + struct fence *last_move;
>
> /**
> * BO doesn't have a TTM we need to bind/unbind. Just remember
> @@ -762,11 +763,14 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo,
> */
>
> spin_lock(&from->move_lock);
> - if (!from->move || fence_is_later(fence, from->move)) {
> - fence_put(from->move);
> - from->move = fence_get(fence);
> - }
> + last_move = rcu_dereference_protected(from->move,
> + spin_is_locked(&from->move_lock));
> + if (!last_move || fence_is_later(fence, last_move))
> + rcu_assign_pointer(from->move, fence_get(fence));
> + else
> + last_move = NULL;
> spin_unlock(&from->move_lock);
> + fence_put(last_move);
>
> ttm_bo_free_old_node(bo);
>
> diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h
> index 99c6d01d24f2..508d2f428d25 100644
> --- a/include/drm/ttm/ttm_bo_driver.h
> +++ b/include/drm/ttm/ttm_bo_driver.h
> @@ -305,7 +305,7 @@ struct ttm_mem_type_manager {
> /*
> * Protected by @move_lock.
> */
> - struct fence *move;
> + struct fence __rcu *move;
> };
>
> /**
More information about the dri-devel
mailing list