Skip to content

Commit 4a696a2

Browse files
vivekkreddydigetx
authored andcommitted
drm/virtio: Add prepare and cleanup routines for imported dmabuf obj
When an imported dmabuf obj is used as part of an atomic commit, we need to pin it as part of prepare and unpin it during cleanup of the associated FB, to make sure that it does not move until the commit is completed (and also while it is being used on the Host). Cc: Gerd Hoffmann <[email protected]> Cc: Dmitry Osipenko <[email protected]> Cc: Rob Clark <[email protected]> Cc: Gurchetan Singh <[email protected]> Cc: Chia-I Wu <[email protected]> Signed-off-by: Vivek Kasireddy <[email protected]> Tested-by: Dmitry Osipenko <[email protected]> Reviewed-by: Dmitry Osipenko <[email protected]> Signed-off-by: Dmitry Osipenko <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent ca77f27 commit 4a696a2

File tree

1 file changed

+64
-1
lines changed

1 file changed

+64
-1
lines changed

drivers/gpu/drm/virtio/virtgpu_plane.c

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <drm/drm_damage_helper.h>
2828
#include <drm/drm_fourcc.h>
2929
#include <drm/drm_gem_atomic_helper.h>
30+
#include <linux/virtio_dma_buf.h>
3031

3132
#include "virtgpu_drv.h"
3233

@@ -259,6 +260,44 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
259260
rect.y2 - rect.y1);
260261
}
261262

263+
static int virtio_gpu_prepare_imported_obj(struct drm_plane *plane,
264+
struct drm_plane_state *new_state,
265+
struct drm_gem_object *obj)
266+
{
267+
struct virtio_gpu_device *vgdev = plane->dev->dev_private;
268+
struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
269+
struct dma_buf_attachment *attach = obj->import_attach;
270+
struct dma_resv *resv = attach->dmabuf->resv;
271+
struct virtio_gpu_mem_entry *ents = NULL;
272+
unsigned int nents;
273+
int ret;
274+
275+
dma_resv_lock(resv, NULL);
276+
277+
ret = dma_buf_pin(attach);
278+
if (ret) {
279+
dma_resv_unlock(resv);
280+
return ret;
281+
}
282+
283+
if (!bo->sgt) {
284+
ret = virtgpu_dma_buf_import_sgt(&ents, &nents,
285+
bo, attach);
286+
if (ret)
287+
goto err;
288+
289+
virtio_gpu_object_attach(vgdev, bo, ents, nents);
290+
}
291+
292+
dma_resv_unlock(resv);
293+
return 0;
294+
295+
err:
296+
dma_buf_unpin(attach);
297+
dma_resv_unlock(resv);
298+
return ret;
299+
}
300+
262301
static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
263302
struct drm_plane_state *new_state)
264303
{
@@ -267,6 +306,8 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
267306
struct virtio_gpu_framebuffer *vgfb;
268307
struct virtio_gpu_plane_state *vgplane_st;
269308
struct virtio_gpu_object *bo;
309+
struct drm_gem_object *obj;
310+
int ret;
270311

271312
if (!new_state->fb)
272313
return 0;
@@ -280,7 +321,14 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
280321
if (!bo || (plane->type == DRM_PLANE_TYPE_PRIMARY && !bo->guest_blob))
281322
return 0;
282323

283-
if (bo->dumb) {
324+
obj = new_state->fb->obj[0];
325+
if (obj->import_attach) {
326+
ret = virtio_gpu_prepare_imported_obj(plane, new_state, obj);
327+
if (ret)
328+
return ret;
329+
}
330+
331+
if (bo->dumb || obj->import_attach) {
284332
vgplane_st->fence = virtio_gpu_fence_alloc(vgdev,
285333
vgdev->fence_drv.context,
286334
0);
@@ -291,10 +339,21 @@ static int virtio_gpu_plane_prepare_fb(struct drm_plane *plane,
291339
return 0;
292340
}
293341

342+
static void virtio_gpu_cleanup_imported_obj(struct drm_gem_object *obj)
343+
{
344+
struct dma_buf_attachment *attach = obj->import_attach;
345+
struct dma_resv *resv = attach->dmabuf->resv;
346+
347+
dma_resv_lock(resv, NULL);
348+
dma_buf_unpin(attach);
349+
dma_resv_unlock(resv);
350+
}
351+
294352
static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane,
295353
struct drm_plane_state *state)
296354
{
297355
struct virtio_gpu_plane_state *vgplane_st;
356+
struct drm_gem_object *obj;
298357

299358
if (!state->fb)
300359
return;
@@ -304,6 +363,10 @@ static void virtio_gpu_plane_cleanup_fb(struct drm_plane *plane,
304363
dma_fence_put(&vgplane_st->fence->f);
305364
vgplane_st->fence = NULL;
306365
}
366+
367+
obj = state->fb->obj[0];
368+
if (obj->import_attach)
369+
virtio_gpu_cleanup_imported_obj(obj);
307370
}
308371

309372
static void virtio_gpu_cursor_plane_update(struct drm_plane *plane,

0 commit comments

Comments
 (0)