freedreno/drm: Split out bo->finalize()

The complexity around batching up handle closing is simply to allow the
virtgpu to back up ccmd's to the host (because virtio/virtgpu is pretty
inefficient when it comes to lots of small msgs to the host, and it is
common that when we are deleting BOs, we delete a lot of them at the
same time.  But that will make the locking fix in the next commit
impossible (without nested locks).  So let's flip this around and do the
step that virtgpu wants to batch up first, before we get into closing
GEM handles, etc.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20918>
This commit is contained in:
Rob Clark
2023-01-26 13:57:13 -08:00
committed by Marge Bot
parent 5a46e884ea
commit 444db624df
4 changed files with 49 additions and 18 deletions

View File

@@ -298,6 +298,20 @@ fd_bo_ref(struct fd_bo *bo)
static uint32_t bo_del(struct fd_bo *bo);
static void close_handles(struct fd_device *dev, uint32_t *handles, unsigned cnt);
static void
bo_finalize(struct fd_bo *bo)
{
if (bo->funcs->finalize)
bo->funcs->finalize(bo);
}
static void
dev_flush(struct fd_device *dev)
{
if (dev->funcs->flush)
dev->funcs->flush(dev);
}
static bool
try_recycle(struct fd_bo *bo)
{
@@ -327,6 +341,9 @@ fd_bo_del(struct fd_bo *bo)
struct fd_device *dev = bo->dev;
bo_finalize(bo);
dev_flush(dev);
uint32_t handle = bo_del(bo);
if (handle)
close_handles(dev, &handle, 1);
@@ -349,9 +366,14 @@ fd_bo_del_array(struct fd_bo **bos, int count)
for (int i = 0; i < count; i++) {
if (!unref(&bos[i]->refcnt) || try_recycle(bos[i])) {
bos[i--] = bos[--count];
} else {
/* We are going to delete this one, so finalize it first: */
bo_finalize(bos[i]);
}
}
dev_flush(dev);
/*
* Second pass, delete all of the objects remaining after first pass.
*/
@@ -387,6 +409,12 @@ fd_bo_del_list_nocache(struct list_head *list)
uint32_t handles[64];
unsigned cnt = 0;
foreach_bo (bo, list) {
bo_finalize(bo);
}
dev_flush(dev);
foreach_bo_safe (bo, list) {
assert(bo->refcnt == 0);
if (cnt == ARRAY_SIZE(handles)) {
@@ -439,6 +467,8 @@ fd_bo_fini_common(struct fd_bo *bo)
_mesa_hash_table_remove_key(dev->name_table, &bo->name);
simple_mtx_unlock(&table_lock);
}
free(bo);
}
/**

View File

@@ -411,6 +411,19 @@ struct fd_bo_funcs {
int (*madvise)(struct fd_bo *bo, int willneed);
uint64_t (*iova)(struct fd_bo *bo);
void (*set_name)(struct fd_bo *bo, const char *fmt, va_list ap);
/**
* Optional hook that is called before ->destroy(). In the case of
* batch deletes (such as BO cache cleanup or cleaning up a submit)
* the ->finalize() hook will be called for all of the BOs being
* destroyed followed by dev->flush() and then bo->destroy(). This
* allows the backend to batch up processing. (Ie. this is for
* virtio backend to batch ccmds to the host)
*
* In all cases, dev->flush() will happen after bo->finalize() and
* bo->destroy().
*/
void (*finalize)(struct fd_bo *bo);
void (*destroy)(struct fd_bo *bo);
/**

View File

@@ -136,21 +136,13 @@ msm_bo_set_name(struct fd_bo *bo, const char *fmt, va_list ap)
drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_INFO, &req, sizeof(req));
}
static void
msm_bo_destroy(struct fd_bo *bo)
{
struct msm_bo *msm_bo = to_msm_bo(bo);
fd_bo_fini_common(bo);
free(msm_bo);
}
static const struct fd_bo_funcs funcs = {
.offset = msm_bo_offset,
.cpu_prep = msm_bo_cpu_prep,
.madvise = msm_bo_madvise,
.iova = msm_bo_iova,
.set_name = msm_bo_set_name,
.destroy = msm_bo_destroy,
.destroy = fd_bo_fini_common,
};
/* allocate a buffer handle: */

View File

@@ -267,20 +267,14 @@ set_iova(struct fd_bo *bo, uint64_t iova)
}
static void
virtio_bo_destroy(struct fd_bo *bo)
virtio_bo_finalize(struct fd_bo *bo)
{
struct virtio_bo *virtio_bo = to_virtio_bo(bo);
/* Release iova by setting to zero: */
if (bo->iova) {
set_iova(bo, 0);
virtio_dev_free_iova(bo->dev, bo->iova, bo->size);
}
fd_bo_fini_common(bo);
free(virtio_bo);
}
static const struct fd_bo_funcs funcs = {
@@ -291,7 +285,8 @@ static const struct fd_bo_funcs funcs = {
.set_name = virtio_bo_set_name,
.upload = virtio_bo_upload,
.prefer_upload = virtio_bo_prefer_upload,
.destroy = virtio_bo_destroy,
.finalize = virtio_bo_finalize,
.destroy = fd_bo_fini_common,
};
static struct fd_bo *
@@ -358,7 +353,8 @@ virtio_bo_from_handle(struct fd_device *dev, uint32_t size, uint32_t handle)
return bo;
fail:
virtio_bo_destroy(bo);
virtio_bo_finalize(bo);
fd_bo_fini_common(bo);
return NULL;
}