drm/amdgpu: add shadow bo support V2

shadow bo is the shadow of a bo, which is always in GTT,
which can be used to backup the original bo.
V2:
reference shadow parent, shadow bo will be freed by who allocted him.

Signed-off-by: Chunming Zhou <David1.Zhou@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Chunming Zhou 2016-07-26 14:13:21 +08:00 committed by Alex Deucher
parent f4a7f127d9
commit e7893c4bd3
3 changed files with 48 additions and 3 deletions

View File

@ -505,6 +505,7 @@ struct amdgpu_bo {
struct amdgpu_device *adev; struct amdgpu_device *adev;
struct drm_gem_object gem_base; struct drm_gem_object gem_base;
struct amdgpu_bo *parent; struct amdgpu_bo *parent;
struct amdgpu_bo *shadow;
struct ttm_bo_kmap_obj dma_buf_vmap; struct ttm_bo_kmap_obj dma_buf_vmap;
struct amdgpu_mn *mn; struct amdgpu_mn *mn;

View File

@ -380,6 +380,37 @@ fail_free:
return r; return r;
} }
static int amdgpu_bo_create_shadow(struct amdgpu_device *adev,
unsigned long size, int byte_align,
struct amdgpu_bo *bo)
{
struct ttm_placement placement = {0};
struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1];
int r;
if (bo->shadow)
return 0;
bo->flags |= AMDGPU_GEM_CREATE_SHADOW;
memset(&placements, 0,
(AMDGPU_GEM_DOMAIN_MAX + 1) * sizeof(struct ttm_place));
amdgpu_ttm_placement_init(adev, &placement,
placements, AMDGPU_GEM_DOMAIN_GTT,
AMDGPU_GEM_CREATE_CPU_GTT_USWC);
r = amdgpu_bo_create_restricted(adev, size, byte_align, true,
AMDGPU_GEM_DOMAIN_GTT,
AMDGPU_GEM_CREATE_CPU_GTT_USWC,
NULL, &placement,
bo->tbo.resv,
&bo->shadow);
if (!r)
bo->shadow->parent = amdgpu_bo_ref(bo);
return r;
}
int amdgpu_bo_create(struct amdgpu_device *adev, int amdgpu_bo_create(struct amdgpu_device *adev,
unsigned long size, int byte_align, unsigned long size, int byte_align,
bool kernel, u32 domain, u64 flags, bool kernel, u32 domain, u64 flags,
@ -389,6 +420,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
{ {
struct ttm_placement placement = {0}; struct ttm_placement placement = {0};
struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1]; struct ttm_place placements[AMDGPU_GEM_DOMAIN_MAX + 1];
int r;
memset(&placements, 0, memset(&placements, 0,
(AMDGPU_GEM_DOMAIN_MAX + 1) * sizeof(struct ttm_place)); (AMDGPU_GEM_DOMAIN_MAX + 1) * sizeof(struct ttm_place));
@ -396,9 +428,19 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
amdgpu_ttm_placement_init(adev, &placement, amdgpu_ttm_placement_init(adev, &placement,
placements, domain, flags); placements, domain, flags);
return amdgpu_bo_create_restricted(adev, size, byte_align, kernel, r = amdgpu_bo_create_restricted(adev, size, byte_align, kernel,
domain, flags, sg, &placement, domain, flags, sg, &placement,
resv, bo_ptr); resv, bo_ptr);
if (r)
return r;
if (flags & AMDGPU_GEM_CREATE_SHADOW) {
r = amdgpu_bo_create_shadow(adev, size, byte_align, (*bo_ptr));
if (r)
amdgpu_bo_unref(bo_ptr);
}
return r;
} }
int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr) int amdgpu_bo_kmap(struct amdgpu_bo *bo, void **ptr)

View File

@ -79,6 +79,8 @@ extern "C" {
#define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2) #define AMDGPU_GEM_CREATE_CPU_GTT_USWC (1 << 2)
/* Flag that the memory should be in VRAM and cleared */ /* Flag that the memory should be in VRAM and cleared */
#define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3) #define AMDGPU_GEM_CREATE_VRAM_CLEARED (1 << 3)
/* Flag that create shadow bo(GTT) while allocating vram bo */
#define AMDGPU_GEM_CREATE_SHADOW (1 << 4)
struct drm_amdgpu_gem_create_in { struct drm_amdgpu_gem_create_in {
/** the requested memory size */ /** the requested memory size */