freedreno/drm: Rework bo creation path

Decoupling handle and fd_bo creation simplifies things for "normal" drm
drivers, avoiding duplication for the create vs import paths.  But this
is awkward for the virtio backend when wants to do multiple things in
the same guest<->host round trip.

So instead, split the paths in the interface backend and move the code
sharing for the two different paths into the msm backend itself.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14900>
This commit is contained in:
Rob Clark 2022-02-03 16:00:09 -08:00 committed by Marge Bot
parent 9ea36968d3
commit 598405c91f
5 changed files with 52 additions and 20 deletions

View file

@ -57,6 +57,21 @@ lookup_bo(struct hash_table *tbl, uint32_t key)
return bo;
}
static void
bo_init_common(struct fd_bo *bo, struct fd_device *dev)
{
/* Backend should have initialized these: */
assert(bo->size);
assert(bo->handle);
bo->dev = dev;
bo->iova = bo->funcs->iova(bo);
bo->reloc_flags = FD_RELOC_FLAGS_INIT;
p_atomic_set(&bo->refcnt, 1);
list_inithead(&bo->list);
}
/* allocate a new buffer object, call w/ table_lock held */
static struct fd_bo *
bo_from_handle(struct fd_device *dev, uint32_t size, uint32_t handle)
@ -73,16 +88,12 @@ bo_from_handle(struct fd_device *dev, uint32_t size, uint32_t handle)
drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
return NULL;
}
bo->dev = dev;
bo->size = size;
bo->handle = handle;
bo->iova = bo->funcs->iova(bo);
bo->reloc_flags = FD_RELOC_FLAGS_INIT;
p_atomic_set(&bo->refcnt, 1);
list_inithead(&bo->list);
bo_init_common(bo, dev);
/* add ourself into the handle table: */
_mesa_hash_table_insert(dev->handle_table, &bo->handle, bo);
return bo;
}
@ -91,8 +102,6 @@ bo_new(struct fd_device *dev, uint32_t size, uint32_t flags,
struct fd_bo_cache *cache)
{
struct fd_bo *bo = NULL;
uint32_t handle;
int ret;
/* demote cached-coherent to WC if not supported: */
if ((flags & FD_BO_CACHED_COHERENT) && !dev->has_cached_coherent)
@ -102,12 +111,15 @@ bo_new(struct fd_device *dev, uint32_t size, uint32_t flags,
if (bo)
return bo;
ret = dev->funcs->bo_new_handle(dev, size, flags, &handle);
if (ret)
bo = dev->funcs->bo_new(dev, size, flags);
if (!bo)
return NULL;
bo_init_common(bo, dev);
simple_mtx_lock(&table_lock);
bo = bo_from_handle(dev, size, handle);
/* add ourself into the handle table: */
_mesa_hash_table_insert(dev->handle_table, &bo->handle, bo);
simple_mtx_unlock(&table_lock);
bo->alloc_flags = flags;

View file

@ -89,10 +89,16 @@ grow(void **ptr, uint16_t nr, uint16_t *max, uint16_t sz)
struct fd_device_funcs {
int (*bo_new_handle)(struct fd_device *dev, uint32_t size, uint32_t flags,
uint32_t *handle);
/* Create a new buffer object:
*/
struct fd_bo *(*bo_new)(struct fd_device *dev, uint32_t size, uint32_t flags);
/* Create a new buffer object from existing handle (ie. dma-buf or
* flink import):
*/
struct fd_bo *(*bo_from_handle)(struct fd_device *dev, uint32_t size,
uint32_t handle);
struct fd_pipe *(*pipe_new)(struct fd_device *dev, enum fd_pipe_id id,
unsigned prio);
void (*destroy)(struct fd_device *dev);

View file

@ -164,9 +164,8 @@ static const struct fd_bo_funcs funcs = {
};
/* allocate a buffer handle: */
int
msm_bo_new_handle(struct fd_device *dev, uint32_t size, uint32_t flags,
uint32_t *handle)
static int
new_handle(struct fd_device *dev, uint32_t size, uint32_t flags, uint32_t *handle)
{
struct drm_msm_gem_new req = {
.size = size,
@ -195,6 +194,20 @@ msm_bo_new_handle(struct fd_device *dev, uint32_t size, uint32_t flags,
/* allocate a new buffer object */
struct fd_bo *
msm_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags)
{
uint32_t handle;
int ret;
ret = new_handle(dev, size, flags, &handle);
if (ret)
return NULL;
return msm_bo_from_handle(dev, size, handle);
}
/* allocate a new buffer object from existing handle (import) */
struct fd_bo *
msm_bo_from_handle(struct fd_device *dev, uint32_t size, uint32_t handle)
{
struct msm_bo *msm_bo;
@ -205,6 +218,8 @@ msm_bo_from_handle(struct fd_device *dev, uint32_t size, uint32_t handle)
return NULL;
bo = &msm_bo->base;
bo->size = size;
bo->handle = handle;
bo->funcs = &funcs;
return bo;

View file

@ -41,7 +41,7 @@ msm_device_destroy(struct fd_device *dev)
}
static const struct fd_device_funcs funcs = {
.bo_new_handle = msm_bo_new_handle,
.bo_new = msm_bo_new,
.bo_from_handle = msm_bo_from_handle,
.pipe_new = msm_pipe_new,
.destroy = msm_device_destroy,

View file

@ -96,8 +96,7 @@ struct msm_bo {
};
FD_DEFINE_CAST(fd_bo, msm_bo);
int msm_bo_new_handle(struct fd_device *dev, uint32_t size, uint32_t flags,
uint32_t *handle);
struct fd_bo *msm_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags);
struct fd_bo *msm_bo_from_handle(struct fd_device *dev, uint32_t size,
uint32_t handle);