freedreno/drm: Add optimized path for freeing many BOs

Submits tend to hold references to a lot of BOs, which get unref'd when
the submit is destroyed/retired.  For now, all this does is reduce lock
aquire/release, but the next commit will build on it.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19832>
This commit is contained in:
Rob Clark 2022-11-17 13:53:07 -08:00 committed by Marge Bot
parent d7511ad784
commit e5a60e1df2
3 changed files with 13 additions and 6 deletions

View file

@ -301,6 +301,15 @@ fd_bo_del(struct fd_bo *bo)
simple_mtx_unlock(&table_lock);
}
void
fd_bo_del_array(struct fd_bo **bos, unsigned count)
{
simple_mtx_lock(&table_lock);
for (unsigned i = 0; i < count; i++)
fd_bo_del_locked(bos[i]);
simple_mtx_unlock(&table_lock);
}
/**
* Cleanup fences, dropping pipe references. If 'expired' is true, only
* cleanup expired fences.

View file

@ -281,6 +281,7 @@ fd_bo_get_iova(struct fd_bo *bo)
struct fd_bo *fd_bo_ref(struct fd_bo *bo);
void fd_bo_del(struct fd_bo *bo);
void fd_bo_del_array(struct fd_bo **bos, unsigned count);
int fd_bo_get_name(struct fd_bo *bo, uint32_t *name);
uint32_t fd_bo_handle(struct fd_bo *bo);
int fd_bo_dmabuf(struct fd_bo *bo);

View file

@ -392,8 +392,7 @@ fd_submit_sp_destroy(struct fd_submit *submit)
// an indication that we are leaking bo's
slab_destroy_child(&fd_submit->ring_pool);
for (unsigned i = 0; i < fd_submit->nr_bos; i++)
fd_bo_del(fd_submit->bos[i]);
fd_bo_del_array(fd_submit->bos, fd_submit->nr_bos);
free(fd_submit->bos);
free(fd_submit);
@ -548,15 +547,13 @@ fd_ringbuffer_sp_destroy(struct fd_ringbuffer *ring)
fd_bo_del(fd_ring->ring_bo);
if (ring->flags & _FD_RINGBUFFER_OBJECT) {
for (unsigned i = 0; i < fd_ring->u.nr_reloc_bos; i++) {
fd_bo_del(fd_ring->u.reloc_bos[i]);
}
fd_bo_del_array(fd_ring->u.reloc_bos, fd_ring->u.nr_reloc_bos);
free(fd_ring->u.reloc_bos);
free(fd_ring);
} else {
struct fd_submit *submit = fd_ring->u.submit;
// TODO re-arrange the data structures so we can use fd_bo_del_array()
for (unsigned i = 0; i < fd_ring->u.nr_cmds; i++) {
fd_bo_del(fd_ring->u.cmds[i].ring_bo);
}