mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
drm/ttm: fix bulk move handling v2
The resource must be on the LRU before ttm_lru_bulk_move_add() is called
and we need to check if the BO is pinned or not before adding it.
Additional to that we missed taking the LRU spinlock in ttm_bo_unpin().
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Acked-by: Luben Tuikov <luben.tuikov@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220613080816.4965-1-christian.koenig@amd.com
Fixes: fee2ede155
("drm/ttm: rework bulk move handling v5")
This commit is contained in:
parent
81b0d0e4f8
commit
0f9cd1ea10
@ -109,11 +109,11 @@ void ttm_bo_set_bulk_move(struct ttm_buffer_object *bo,
|
||||
return;
|
||||
|
||||
spin_lock(&bo->bdev->lru_lock);
|
||||
if (bo->bulk_move && bo->resource)
|
||||
ttm_lru_bulk_move_del(bo->bulk_move, bo->resource);
|
||||
if (bo->resource)
|
||||
ttm_resource_del_bulk_move(bo->resource, bo);
|
||||
bo->bulk_move = bulk;
|
||||
if (bo->bulk_move && bo->resource)
|
||||
ttm_lru_bulk_move_add(bo->bulk_move, bo->resource);
|
||||
if (bo->resource)
|
||||
ttm_resource_add_bulk_move(bo->resource, bo);
|
||||
spin_unlock(&bo->bdev->lru_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_bo_set_bulk_move);
|
||||
@ -689,8 +689,11 @@ void ttm_bo_pin(struct ttm_buffer_object *bo)
|
||||
{
|
||||
dma_resv_assert_held(bo->base.resv);
|
||||
WARN_ON_ONCE(!kref_read(&bo->kref));
|
||||
if (!(bo->pin_count++) && bo->bulk_move && bo->resource)
|
||||
ttm_lru_bulk_move_del(bo->bulk_move, bo->resource);
|
||||
spin_lock(&bo->bdev->lru_lock);
|
||||
if (bo->resource)
|
||||
ttm_resource_del_bulk_move(bo->resource, bo);
|
||||
++bo->pin_count;
|
||||
spin_unlock(&bo->bdev->lru_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_bo_pin);
|
||||
|
||||
@ -707,8 +710,11 @@ void ttm_bo_unpin(struct ttm_buffer_object *bo)
|
||||
if (WARN_ON_ONCE(!bo->pin_count))
|
||||
return;
|
||||
|
||||
if (!(--bo->pin_count) && bo->bulk_move && bo->resource)
|
||||
ttm_lru_bulk_move_add(bo->bulk_move, bo->resource);
|
||||
spin_lock(&bo->bdev->lru_lock);
|
||||
--bo->pin_count;
|
||||
if (bo->resource)
|
||||
ttm_resource_add_bulk_move(bo->resource, bo);
|
||||
spin_unlock(&bo->bdev->lru_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_bo_unpin);
|
||||
|
||||
|
@ -91,7 +91,7 @@ static void ttm_lru_bulk_move_pos_tail(struct ttm_lru_bulk_move_pos *pos,
|
||||
}
|
||||
|
||||
/* Add the resource to a bulk_move cursor */
|
||||
void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
|
||||
static void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
|
||||
struct ttm_resource *res)
|
||||
{
|
||||
struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res);
|
||||
@ -105,7 +105,7 @@ void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
|
||||
}
|
||||
|
||||
/* Remove the resource from a bulk_move range */
|
||||
void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
|
||||
static void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
|
||||
struct ttm_resource *res)
|
||||
{
|
||||
struct ttm_lru_bulk_move_pos *pos = ttm_lru_bulk_move_pos(bulk, res);
|
||||
@ -122,6 +122,22 @@ void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the resource to a bulk move if the BO is configured for it */
|
||||
void ttm_resource_add_bulk_move(struct ttm_resource *res,
|
||||
struct ttm_buffer_object *bo)
|
||||
{
|
||||
if (bo->bulk_move && !bo->pin_count)
|
||||
ttm_lru_bulk_move_add(bo->bulk_move, res);
|
||||
}
|
||||
|
||||
/* Remove the resource from a bulk move if the BO is configured for it */
|
||||
void ttm_resource_del_bulk_move(struct ttm_resource *res,
|
||||
struct ttm_buffer_object *bo)
|
||||
{
|
||||
if (bo->bulk_move && !bo->pin_count)
|
||||
ttm_lru_bulk_move_del(bo->bulk_move, res);
|
||||
}
|
||||
|
||||
/* Move a resource to the LRU or bulk tail */
|
||||
void ttm_resource_move_to_lru_tail(struct ttm_resource *res)
|
||||
{
|
||||
@ -169,15 +185,14 @@ void ttm_resource_init(struct ttm_buffer_object *bo,
|
||||
res->bus.is_iomem = false;
|
||||
res->bus.caching = ttm_cached;
|
||||
res->bo = bo;
|
||||
INIT_LIST_HEAD(&res->lru);
|
||||
|
||||
man = ttm_manager_type(bo->bdev, place->mem_type);
|
||||
spin_lock(&bo->bdev->lru_lock);
|
||||
man->usage += res->num_pages << PAGE_SHIFT;
|
||||
if (bo->bulk_move)
|
||||
ttm_lru_bulk_move_add(bo->bulk_move, res);
|
||||
if (bo->pin_count)
|
||||
list_add_tail(&res->lru, &bo->bdev->pinned);
|
||||
else
|
||||
ttm_resource_move_to_lru_tail(res);
|
||||
list_add_tail(&res->lru, &man->lru[bo->priority]);
|
||||
man->usage += res->num_pages << PAGE_SHIFT;
|
||||
spin_unlock(&bo->bdev->lru_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(ttm_resource_init);
|
||||
@ -210,8 +225,16 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo,
|
||||
{
|
||||
struct ttm_resource_manager *man =
|
||||
ttm_manager_type(bo->bdev, place->mem_type);
|
||||
int ret;
|
||||
|
||||
return man->func->alloc(man, bo, place, res_ptr);
|
||||
ret = man->func->alloc(man, bo, place, res_ptr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
spin_lock(&bo->bdev->lru_lock);
|
||||
ttm_resource_add_bulk_move(*res_ptr, bo);
|
||||
spin_unlock(&bo->bdev->lru_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
|
||||
@ -221,12 +244,9 @@ void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res)
|
||||
if (!*res)
|
||||
return;
|
||||
|
||||
if (bo->bulk_move) {
|
||||
spin_lock(&bo->bdev->lru_lock);
|
||||
ttm_lru_bulk_move_del(bo->bulk_move, *res);
|
||||
ttm_resource_del_bulk_move(*res, bo);
|
||||
spin_unlock(&bo->bdev->lru_lock);
|
||||
}
|
||||
|
||||
man = ttm_manager_type(bo->bdev, (*res)->mem_type);
|
||||
man->func->free(man, *res);
|
||||
*res = NULL;
|
||||
|
@ -311,12 +311,12 @@ ttm_resource_manager_cleanup(struct ttm_resource_manager *man)
|
||||
}
|
||||
|
||||
void ttm_lru_bulk_move_init(struct ttm_lru_bulk_move *bulk);
|
||||
void ttm_lru_bulk_move_add(struct ttm_lru_bulk_move *bulk,
|
||||
struct ttm_resource *res);
|
||||
void ttm_lru_bulk_move_del(struct ttm_lru_bulk_move *bulk,
|
||||
struct ttm_resource *res);
|
||||
void ttm_lru_bulk_move_tail(struct ttm_lru_bulk_move *bulk);
|
||||
|
||||
void ttm_resource_add_bulk_move(struct ttm_resource *res,
|
||||
struct ttm_buffer_object *bo);
|
||||
void ttm_resource_del_bulk_move(struct ttm_resource *res,
|
||||
struct ttm_buffer_object *bo);
|
||||
void ttm_resource_move_to_lru_tail(struct ttm_resource *res);
|
||||
|
||||
void ttm_resource_init(struct ttm_buffer_object *bo,
|
||||
|
Loading…
Reference in New Issue
Block a user