[PATCH 2/2] drm/amdgpu: add gart recovery by gtt list
Christian König
deathsimple at vodafone.de
Tue Aug 30 09:05:40 UTC 2016
Am 30.08.2016 um 10:54 schrieb Chunming Zhou:
> Change-Id: I8daf687d43b51d69f9be36cae8b265deb88e5754
> Signed-off-by: Chunming Zhou <David1.Zhou at amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu.h | 15 +++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 3 +++
> drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 20 ++++++++++++++++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 14 +-------------
> 4 files changed, 39 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> index 18bbfea..6ee9987 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
> @@ -607,6 +607,20 @@ struct amdgpu_gart {
> const struct amdgpu_gart_funcs *gart_funcs;
> };
>
> +struct amdgpu_ttm_tt {
> + struct ttm_dma_tt ttm;
> + struct amdgpu_device *adev;
> + u64 offset;
> + uint32_t pte_flags;
> + uint64_t userptr;
> + struct mm_struct *usermm;
> + uint32_t userflags;
> + spinlock_t guptasklock;
> + struct list_head guptasks;
> + atomic_t mmu_invalidations;
> + struct list_head list;
> +};
> +
> int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev);
> void amdgpu_gart_table_ram_free(struct amdgpu_device *adev);
> int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev);
> @@ -620,6 +634,7 @@ void amdgpu_gart_unbind(struct amdgpu_device *adev, unsigned offset,
> int amdgpu_gart_bind(struct amdgpu_device *adev, unsigned offset,
> int pages, struct page **pagelist,
> dma_addr_t *dma_addr, uint32_t flags);
> +int amdgpu_gart_recovery(struct amdgpu_device *adev);
>
> /*
> * GPU MC structures, functions & helpers
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 6cd485a..0e475ed 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -2247,6 +2247,9 @@ retry:
> struct fence *fence = NULL, *next = NULL;
>
> DRM_INFO("recover vram bo from shadow\n");
> + r = amdgpu_gart_recovery(adev);
> + if (r)
> + DRM_ERROR("gart recovery failed!!!\n");
> mutex_lock(&adev->shadow_list_lock);
> list_for_each_entry_safe(bo, tmp, &adev->shadow_list, shadow_list) {
> amdgpu_recover_vram_from_shadow(adev, ring, bo, &next);
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> index 921bce2..02695a6 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c
> @@ -302,6 +302,26 @@ int amdgpu_gart_bind(struct amdgpu_device *adev, unsigned offset,
> return 0;
> }
>
> +int amdgpu_gart_recovery(struct amdgpu_device *adev)
> +{
> + struct amdgpu_ttm_tt *gtt, *tmp;
> + int r;
> +
> + mutex_lock(&adev->gtt_list_lock);
> + list_for_each_entry_safe(gtt, tmp, &adev->gtt_list, list) {
> + r = amdgpu_gart_bind(adev, gtt->offset, gtt->ttm.ttm.num_pages,
> + gtt->ttm.ttm.pages, gtt->ttm.dma_address,
> + gtt->pte_flags);
> + if (r) {
> + mutex_unlock(&adev->gtt_list_lock);
> + DRM_ERROR("failed to bind %lu pages at 0x%08X\n",
> + gtt->ttm.ttm.num_pages, (unsigned)gtt->offset);
> + return r;
> + }
> + }
> + mutex_unlock(&adev->gtt_list_lock);
> + return 0;
> +}
This function would better be in amdgpu_ttm.c, cause it uses the TTM
handling internal structures for the recovery.
Call it something like amdgpu_ttm_recover_gart(), this way you also
don't need to move the structure.
> /**
> * amdgpu_gart_init - init the driver info for managing the gart
> *
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index efeb9a5..431fe62 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -511,19 +511,6 @@ struct amdgpu_ttm_gup_task_list {
> struct task_struct *task;
> };
>
> -struct amdgpu_ttm_tt {
> - struct ttm_dma_tt ttm;
> - struct amdgpu_device *adev;
> - u64 offset;
> - uint64_t userptr;
> - struct mm_struct *usermm;
> - uint32_t userflags;
> - spinlock_t guptasklock;
> - struct list_head guptasks;
> - atomic_t mmu_invalidations;
> - struct list_head list;
> -};
> -
> int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
> {
> struct amdgpu_ttm_tt *gtt = (void *)ttm;
> @@ -668,6 +655,7 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
> ttm->num_pages, (unsigned)gtt->offset);
> return r;
> }
> + gtt->pte_flags = flags;
No need to save the flags here. When the BO is bound we know that it's
mem type is TTM_PL_TT.
Just use a fixed ttm_mem_reg in the backup function with the mem_type
set accordingly.
Regards,
Christian.
> mutex_lock(>t->adev->gtt_list_lock);
> list_add_tail(>t->list, >t->adev->gtt_list);
> mutex_unlock(>t->adev->gtt_list_lock);
More information about the amd-gfx
mailing list