mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 10:50:16 +01:00
v3dv: don't leak BOs from CLs when using BRANCH
Keep the list of BOs referenced in the CL and free all of them when the CL is destroyed. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
parent
e7232252b7
commit
27d360c702
4 changed files with 48 additions and 50 deletions
|
|
@ -60,6 +60,7 @@ v3dv_bo_alloc(struct v3dv_device *device, uint32_t size, const char *name)
|
|||
bo->map = NULL;
|
||||
bo->map_size = 0;
|
||||
bo->name = name;
|
||||
list_inithead(&bo->list_link);
|
||||
|
||||
return bo;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
struct v3dv_device;
|
||||
|
||||
struct v3dv_bo {
|
||||
struct list_head list_link;
|
||||
|
||||
uint32_t handle;
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ v3dv_cl_init(struct v3dv_job *job, struct v3dv_cl *cl)
|
|||
cl->bo = NULL;
|
||||
cl->size = 0;
|
||||
cl->job = job;
|
||||
list_inithead(&cl->bo_list);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -52,15 +53,52 @@ v3dv_cl_reset(struct v3dv_cl *cl)
|
|||
void
|
||||
v3dv_cl_destroy(struct v3dv_cl *cl)
|
||||
{
|
||||
if (cl->bo) {
|
||||
list_for_each_entry_safe(struct v3dv_bo, bo, &cl->bo_list, list_link) {
|
||||
assert(cl->job);
|
||||
v3dv_bo_free(cl->job->device, cl->bo);
|
||||
list_del(&bo->list_link);
|
||||
v3dv_bo_free(cl->job->device, bo);
|
||||
}
|
||||
|
||||
/* Leave the CL in a reset state to catch use after destroy instances */
|
||||
v3dv_cl_init(NULL, cl);
|
||||
}
|
||||
|
||||
static bool
|
||||
cl_alloc_bo(struct v3dv_cl *cl, uint32_t space, bool use_branch)
|
||||
{
|
||||
struct v3dv_bo *bo = v3dv_bo_alloc(cl->job->device, space, "CL");
|
||||
if (!bo) {
|
||||
fprintf(stderr, "failed to allocate memory for command list\n");
|
||||
v3dv_flag_oom(NULL, cl->job);
|
||||
return false;
|
||||
}
|
||||
|
||||
list_addtail(&bo->list_link, &cl->bo_list);
|
||||
|
||||
bool ok = v3dv_bo_map(cl->job->device, bo, bo->size);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "failed to map command list buffer\n");
|
||||
v3dv_flag_oom(NULL, cl->job);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Chain to the new BO from the old one if requested */
|
||||
if (use_branch && cl->bo) {
|
||||
cl_emit(cl, BRANCH, branch) {
|
||||
branch.address = v3dv_cl_address(bo, 0);
|
||||
}
|
||||
}
|
||||
|
||||
v3dv_job_add_bo(cl->job, bo);
|
||||
|
||||
cl->bo = bo;
|
||||
cl->base = cl->bo->map;
|
||||
cl->size = cl->bo->size;
|
||||
cl->next = cl->base;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
v3dv_cl_ensure_space(struct v3dv_cl *cl, uint32_t space, uint32_t alignment)
|
||||
{
|
||||
|
|
@ -71,27 +109,7 @@ v3dv_cl_ensure_space(struct v3dv_cl *cl, uint32_t space, uint32_t alignment)
|
|||
return offset;
|
||||
}
|
||||
|
||||
struct v3dv_bo *bo = v3dv_bo_alloc(cl->job->device, space, "CL");
|
||||
if (!bo) {
|
||||
fprintf(stderr, "failed to allocate memory for command list\n");
|
||||
v3dv_flag_oom(NULL, cl->job);
|
||||
return 0;
|
||||
}
|
||||
|
||||
v3dv_job_add_bo(cl->job, bo);
|
||||
|
||||
bool ok = v3dv_bo_map(cl->job->device, bo, bo->size);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "failed to map command list buffer\n");
|
||||
v3dv_flag_oom(NULL, cl->job);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cl->bo = bo;
|
||||
cl->base = cl->bo->map;
|
||||
cl->size = cl->bo->size;
|
||||
cl->next = cl->base;
|
||||
|
||||
cl_alloc_bo(cl, space, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -101,31 +119,5 @@ v3dv_cl_ensure_space_with_branch(struct v3dv_cl *cl, uint32_t space)
|
|||
if (v3dv_cl_offset(cl) + space + cl_packet_length(BRANCH) <= cl->size)
|
||||
return;
|
||||
|
||||
struct v3dv_bo *bo = v3dv_bo_alloc(cl->job->device, space, "CL");
|
||||
if (!bo) {
|
||||
fprintf(stderr, "failed to allocate memory for command list\n");
|
||||
v3dv_flag_oom(NULL, cl->job);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Chain to the new BO from the old one if needed */
|
||||
if (cl->bo) {
|
||||
cl_emit(cl, BRANCH, branch) {
|
||||
branch.address = v3dv_cl_address(bo, 0);
|
||||
}
|
||||
}
|
||||
|
||||
v3dv_job_add_bo(cl->job, bo);
|
||||
|
||||
bool ok = v3dv_bo_map(cl->job->device, bo, bo->size);
|
||||
if (!ok) {
|
||||
fprintf(stderr, "failed to map command list buffer\n");
|
||||
v3dv_flag_oom(NULL, cl->job);
|
||||
return;
|
||||
}
|
||||
|
||||
cl->bo = bo;
|
||||
cl->base = cl->bo->map;
|
||||
cl->size = cl->bo->size;
|
||||
cl->next = cl->base;
|
||||
cl_alloc_bo(cl, space, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include "broadcom/cle/v3d_packet_helpers.h"
|
||||
|
||||
#include "list.h"
|
||||
|
||||
struct v3dv_bo;
|
||||
struct v3dv_job;
|
||||
struct v3dv_cl;
|
||||
|
|
@ -50,6 +52,7 @@ struct v3dv_cl {
|
|||
struct v3dv_cl_out *next;
|
||||
struct v3dv_bo *bo;
|
||||
uint32_t size;
|
||||
struct list_head bo_list;
|
||||
};
|
||||
|
||||
static inline struct v3dv_cl_reloc
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue