Skip to content

Commit a68c7ea

Browse files
arunpravin24ChristianKoenigAMD
authored andcommitted
drm/amdgpu: Enable clear page functionality
Add clear page support in vram memory region. v1(Christian): - Dont handle clear page as TTM flag since when moving the BO back in from GTT again we don't need that. - Make a specialized version of amdgpu_fill_buffer() which only clears the VRAM areas which are not already cleared - Drop the TTM_PL_FLAG_WIPE_ON_RELEASE check in amdgpu_object.c v2: - Modify the function name amdgpu_ttm_* (Alex) - Drop the delayed parameter (Christian) - handle amdgpu_res_cleared(&cursor) just above the size calculation (Christian) - Use AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE for clearing the buffers in the free path to properly wait for fences etc.. (Christian) v3(Christian): - Remove buffer clear code in VRAM manager instead change the AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE handling to set the DRM_BUDDY_CLEARED flag. - Remove ! from amdgpu_res_cleared(&cursor) check. v4(Christian): - vres flag setting move to vram manager file - use dma_fence_get_stub in amdgpu_ttm_clear_buffer function - make fence a mandatory parameter and drop the if and the get/put dance Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com> Suggested-by: Christian König <christian.koenig@amd.com> Acked-by: Felix Kuehling <felix.kuehling@amd.com> Link: https://patchwork.freedesktop.org/patch/msgid/20240419063538.11957-2-Arunpravin.PaneerSelvam@amd.com Signed-off-by: Christian König <christian.koenig@amd.com>
1 parent 9695092 commit a68c7ea

6 files changed

Lines changed: 116 additions & 9 deletions

File tree

drivers/gpu/drm/amd/amdgpu/amdgpu_object.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "amdgpu.h"
4040
#include "amdgpu_trace.h"
4141
#include "amdgpu_amdkfd.h"
42+
#include "amdgpu_vram_mgr.h"
4243

4344
/**
4445
* DOC: amdgpu_object
@@ -601,8 +602,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
601602
if (!amdgpu_bo_support_uswc(bo->flags))
602603
bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
603604

604-
if (adev->ras_enabled)
605-
bo->flags |= AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE;
605+
bo->flags |= AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE;
606606

607607
bo->tbo.bdev = &adev->mman.bdev;
608608
if (bp->domain & (AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA |
@@ -634,7 +634,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
634634
bo->tbo.resource->mem_type == TTM_PL_VRAM) {
635635
struct dma_fence *fence;
636636

637-
r = amdgpu_fill_buffer(bo, 0, bo->tbo.base.resv, &fence, true);
637+
r = amdgpu_ttm_clear_buffer(bo, bo->tbo.base.resv, &fence);
638638
if (unlikely(r))
639639
goto fail_unreserve;
640640

@@ -1365,8 +1365,9 @@ void amdgpu_bo_release_notify(struct ttm_buffer_object *bo)
13651365
if (WARN_ON_ONCE(!dma_resv_trylock(bo->base.resv)))
13661366
return;
13671367

1368-
r = amdgpu_fill_buffer(abo, AMDGPU_POISON, bo->base.resv, &fence, true);
1368+
r = amdgpu_fill_buffer(abo, 0, bo->base.resv, &fence, true);
13691369
if (!WARN_ON(r)) {
1370+
amdgpu_vram_mgr_set_cleared(bo->resource);
13701371
amdgpu_bo_fence(abo, fence, false);
13711372
dma_fence_put(fence);
13721373
}

drivers/gpu/drm/amd/amdgpu/amdgpu_res_cursor.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,29 @@ static inline void amdgpu_res_next(struct amdgpu_res_cursor *cur, uint64_t size)
164164
}
165165
}
166166

167+
/**
168+
* amdgpu_res_cleared - check if blocks are cleared
169+
*
170+
* @cur: the cursor to extract the block
171+
*
172+
* Check if the @cur block is cleared
173+
*/
174+
static inline bool amdgpu_res_cleared(struct amdgpu_res_cursor *cur)
175+
{
176+
struct drm_buddy_block *block;
177+
178+
switch (cur->mem_type) {
179+
case TTM_PL_VRAM:
180+
block = cur->node;
181+
182+
if (!amdgpu_vram_mgr_is_cleared(block))
183+
return false;
184+
break;
185+
default:
186+
return false;
187+
}
188+
189+
return true;
190+
}
191+
167192
#endif

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,11 +378,12 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
378378
(abo->flags & AMDGPU_GEM_CREATE_VRAM_WIPE_ON_RELEASE)) {
379379
struct dma_fence *wipe_fence = NULL;
380380

381-
r = amdgpu_fill_buffer(abo, AMDGPU_POISON, NULL, &wipe_fence,
382-
false);
381+
r = amdgpu_fill_buffer(abo, 0, NULL, &wipe_fence,
382+
false);
383383
if (r) {
384384
goto error;
385385
} else if (wipe_fence) {
386+
amdgpu_vram_mgr_set_cleared(bo->resource);
386387
dma_fence_put(fence);
387388
fence = wipe_fence;
388389
}
@@ -2215,6 +2216,71 @@ static int amdgpu_ttm_fill_mem(struct amdgpu_ring *ring, uint32_t src_data,
22152216
return 0;
22162217
}
22172218

2219+
/**
2220+
* amdgpu_ttm_clear_buffer - clear memory buffers
2221+
* @bo: amdgpu buffer object
2222+
* @resv: reservation object
2223+
* @fence: dma_fence associated with the operation
2224+
*
2225+
* Clear the memory buffer resource.
2226+
*
2227+
* Returns:
2228+
* 0 for success or a negative error code on failure.
2229+
*/
2230+
int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
2231+
struct dma_resv *resv,
2232+
struct dma_fence **fence)
2233+
{
2234+
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
2235+
struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
2236+
struct amdgpu_res_cursor cursor;
2237+
u64 addr;
2238+
int r;
2239+
2240+
if (!adev->mman.buffer_funcs_enabled)
2241+
return -EINVAL;
2242+
2243+
if (!fence)
2244+
return -EINVAL;
2245+
2246+
*fence = dma_fence_get_stub();
2247+
2248+
amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);
2249+
2250+
mutex_lock(&adev->mman.gtt_window_lock);
2251+
while (cursor.remaining) {
2252+
struct dma_fence *next = NULL;
2253+
u64 size;
2254+
2255+
if (amdgpu_res_cleared(&cursor)) {
2256+
amdgpu_res_next(&cursor, cursor.size);
2257+
continue;
2258+
}
2259+
2260+
/* Never clear more than 256MiB at once to avoid timeouts */
2261+
size = min(cursor.size, 256ULL << 20);
2262+
2263+
r = amdgpu_ttm_map_buffer(&bo->tbo, bo->tbo.resource, &cursor,
2264+
1, ring, false, &size, &addr);
2265+
if (r)
2266+
goto err;
2267+
2268+
r = amdgpu_ttm_fill_mem(ring, 0, addr, size, resv,
2269+
&next, true, true);
2270+
if (r)
2271+
goto err;
2272+
2273+
dma_fence_put(*fence);
2274+
*fence = next;
2275+
2276+
amdgpu_res_next(&cursor, size);
2277+
}
2278+
err:
2279+
mutex_unlock(&adev->mman.gtt_window_lock);
2280+
2281+
return r;
2282+
}
2283+
22182284
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
22192285
uint32_t src_data,
22202286
struct dma_resv *resv,

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@
3838
#define AMDGPU_GTT_MAX_TRANSFER_SIZE 512
3939
#define AMDGPU_GTT_NUM_TRANSFER_WINDOWS 2
4040

41-
#define AMDGPU_POISON 0xd0bed0be
42-
4341
extern const struct attribute_group amdgpu_vram_mgr_attr_group;
4442
extern const struct attribute_group amdgpu_gtt_mgr_attr_group;
4543

@@ -155,6 +153,9 @@ int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
155153
uint64_t size, bool tmz,
156154
struct dma_resv *resv,
157155
struct dma_fence **f);
156+
int amdgpu_ttm_clear_buffer(struct amdgpu_bo *bo,
157+
struct dma_resv *resv,
158+
struct dma_fence **fence);
158159
int amdgpu_fill_buffer(struct amdgpu_bo *bo,
159160
uint32_t src_data,
160161
struct dma_resv *resv,

drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
450450
{
451451
struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
452452
struct amdgpu_device *adev = to_amdgpu_device(mgr);
453+
struct amdgpu_bo *bo = ttm_to_amdgpu_bo(tbo);
453454
u64 vis_usage = 0, max_bytes, min_block_size;
454455
struct amdgpu_vram_mgr_resource *vres;
455456
u64 size, remaining_size, lpfn, fpfn;
@@ -501,6 +502,9 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
501502
if (place->flags & TTM_PL_FLAG_CONTIGUOUS)
502503
vres->flags |= DRM_BUDDY_CONTIGUOUS_ALLOCATION;
503504

505+
if (bo->flags & AMDGPU_GEM_CREATE_VRAM_CLEARED)
506+
vres->flags |= DRM_BUDDY_CLEAR_ALLOCATION;
507+
504508
if (fpfn || lpfn != mgr->mm.size)
505509
/* Allocate blocks in desired range */
506510
vres->flags |= DRM_BUDDY_RANGE_ALLOCATION;
@@ -604,7 +608,7 @@ static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man,
604608

605609
amdgpu_vram_mgr_do_reserve(man);
606610

607-
drm_buddy_free_list(mm, &vres->blocks, 0);
611+
drm_buddy_free_list(mm, &vres->blocks, vres->flags);
608612
mutex_unlock(&mgr->lock);
609613

610614
atomic64_sub(vis_usage, &mgr->vis_usage);

drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,20 @@ static inline u64 amdgpu_vram_mgr_block_size(struct drm_buddy_block *block)
5353
return (u64)PAGE_SIZE << drm_buddy_block_order(block);
5454
}
5555

56+
static inline bool amdgpu_vram_mgr_is_cleared(struct drm_buddy_block *block)
57+
{
58+
return drm_buddy_block_is_clear(block);
59+
}
60+
5661
static inline struct amdgpu_vram_mgr_resource *
5762
to_amdgpu_vram_mgr_resource(struct ttm_resource *res)
5863
{
5964
return container_of(res, struct amdgpu_vram_mgr_resource, base);
6065
}
6166

67+
static inline void amdgpu_vram_mgr_set_cleared(struct ttm_resource *res)
68+
{
69+
to_amdgpu_vram_mgr_resource(res)->flags |= DRM_BUDDY_CLEARED;
70+
}
71+
6272
#endif

0 commit comments

Comments
 (0)