diff options
author | Philip Yang <Philip.Yang@amd.com> | 2022-04-27 18:50:49 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2022-04-28 17:49:04 -0400 |
commit | 3da2c38231a4c62dafdbd762a199cfacaccd0533 (patch) | |
tree | 2c88432664a23171dcc1afd6d9773c70533cd176 /drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |
parent | 86e18ac3aee9d0a3deadb6dc0a8685621805ceed (diff) | |
download | linux-3da2c38231a4c62dafdbd762a199cfacaccd0533.tar.bz2 |
drm/amdgpu: Free user pages if amdgpu_cs_parser_bos failed
Otherwise userspace resubmit the BOs again will trigger kernel WARNING
and fail the command submission.
Signed-off-by: Philip Yang <Philip.Yang@amd.com>
Tested-by: Robert Święcki <robert@swiecki.net>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 12bad207bb0f..67bd506fa141 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -550,7 +550,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, if (r) { kvfree(e->user_pages); e->user_pages = NULL; - return r; + goto out_free_user_pages; } for (i = 0; i < bo->tbo.ttm->num_pages; i++) { @@ -567,7 +567,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, if (unlikely(r != 0)) { if (r != -ERESTARTSYS) DRM_ERROR("ttm_eu_reserve_buffers failed.\n"); - goto out; + goto out_free_user_pages; } amdgpu_bo_list_for_each_entry(e, p->bo_list) { @@ -649,7 +649,19 @@ error_validate: } ttm_eu_backoff_reservation(&p->ticket, &p->validated); } -out: + +out_free_user_pages: + if (r) { + amdgpu_bo_list_for_each_userptr_entry(e, p->bo_list) { + struct amdgpu_bo *bo = ttm_to_amdgpu_bo(e->tv.bo); + + if (!e->user_pages) + continue; + amdgpu_ttm_tt_get_user_pages_done(bo->tbo.ttm); + kvfree(e->user_pages); + e->user_pages = NULL; + } + } return r; } |