[PATCH v2 2/4] drm/ttm: Clear all DMA mappings on demand
Christian König
ckoenig.leichtzumerken at gmail.com
Fri Aug 27 06:23:29 UTC 2021
Am 26.08.21 um 19:27 schrieb Andrey Grodzovsky:
> Used by drivers supporting hot unplug to handle all
> DMA IOMMU group related dependencies before the group
> is removed during device removal and we try to access
> it after free when last device pointer from user space
> is dropped.
>
> Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky at amd.com>
> ---
> drivers/gpu/drm/ttm/ttm_device.c | 45 ++++++++++++++++++++++++++++++++
> include/drm/ttm/ttm_device.h | 1 +
> 2 files changed, 46 insertions(+)
>
> diff --git a/drivers/gpu/drm/ttm/ttm_device.c b/drivers/gpu/drm/ttm/ttm_device.c
> index 5f31acec3ad7..ea50aba13743 100644
> --- a/drivers/gpu/drm/ttm/ttm_device.c
> +++ b/drivers/gpu/drm/ttm/ttm_device.c
> @@ -245,3 +245,48 @@ void ttm_device_fini(struct ttm_device *bdev)
> ttm_global_release();
> }
> EXPORT_SYMBOL(ttm_device_fini);
> +
> +void ttm_device_clear_dma_mappings(struct ttm_device *bdev)
> +{
> + struct ttm_resource_manager *man;
> + struct ttm_buffer_object *bo;
> + unsigned int i, j;
> +
> + spin_lock(&bdev->lru_lock);
> + for (i = TTM_PL_SYSTEM; i < TTM_NUM_MEM_TYPES; ++i) {
> + man = ttm_manager_type(bdev, i);
> + if (!man || !man->use_tt)
> + continue;
> +
> + while (!list_empty(&man->pinned)) {
> + bo = list_first_entry(&man->pinned, struct ttm_buffer_object, lru);
> + /* Take ref against racing releases once lru_lock is unlocked */
> + ttm_bo_get(bo);
This should probably use ttm_bo_get_unless_zero() since it is possible
that the BO is already cleaning up in another thread.
> + list_del_init(&bo->lru);
> + spin_unlock(&bdev->lru_lock);
> +
> + if (bo->ttm)
> + ttm_tt_destroy_common(bo->bdev, bo->ttm);
That needs to be ttm_tt_unpopulate() or otherwise we will mess up the
statistics.
> +
> + ttm_bo_put(bo);
> + spin_lock(&bdev->lru_lock);
> + }
> +
> + for (j = 0; j < TTM_MAX_BO_PRIORITY; ++j) {
> + while (!list_empty(&man->lru[j])) {
> + bo = list_first_entry(&man->lru[j], struct ttm_buffer_object, lru);
> + ttm_bo_get(bo);
Same here of course.
> + list_del_init(&bo->lru);
> + spin_unlock(&bdev->lru_lock);
> +
> + if (bo->ttm)
> + ttm_tt_destroy_common(bo->bdev, bo->ttm);.
Same here.
Christian.
> +
> + ttm_bo_put(bo);
> + spin_lock(&bdev->lru_lock);
> + }
> + }
> + }
> + spin_unlock(&bdev->lru_lock);
> +}
> +EXPORT_SYMBOL(ttm_device_clear_dma_mappings);
> diff --git a/include/drm/ttm/ttm_device.h b/include/drm/ttm/ttm_device.h
> index cd592f8e941b..d2837decb49a 100644
> --- a/include/drm/ttm/ttm_device.h
> +++ b/include/drm/ttm/ttm_device.h
> @@ -298,5 +298,6 @@ int ttm_device_init(struct ttm_device *bdev, struct ttm_device_funcs *funcs,
> struct drm_vma_offset_manager *vma_manager,
> bool use_dma_alloc, bool use_dma32);
> void ttm_device_fini(struct ttm_device *bdev);
> +void ttm_device_clear_dma_mappings(struct ttm_device *bdev);
>
> #endif
More information about the dri-devel
mailing list