dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Chris Wilson <chris@chris-wilson.co.uk>
To: dri-devel@lists.freedesktop.org
Cc: Zach Reizner <zachr@google.com>
Subject: [PATCH v3] drm/vgem: Enable dmabuf interface for export
Date: Mon, 20 Jun 2016 21:06:59 +0100	[thread overview]
Message-ID: <1466453219-6665-1-git-send-email-chris@chris-wilson.co.uk> (raw)
In-Reply-To: <1466317129-11615-1-git-send-email-chris@chris-wilson.co.uk>

Enable the standard GEM dma-buf interface provided by the DRM core, but
only for exporting the VGEM object. This allows passing around the VGEM
objects created from the dumb interface and using them as sources
elsewhere. Creating a VGEM object for a foriegn handle is not supported.

v2: With additional completeness.
v3: Need to clear the CPU cache upon exporting the dma-addresses.

Testcase: igt/vgem_basic/dmabuf-*
Testcase: igt/prime_vgem
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sean Paul <seanpaul@chromium.org>
Cc: Zach Reizner <zachr@google.com>
---
 drivers/gpu/drm/vgem/vgem_drv.c | 112 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 111 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index e1a697d0662f..db48e837992d 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -193,14 +193,124 @@ static const struct file_operations vgem_driver_fops = {
 	.release	= drm_release,
 };
 
+static void __put_pages(struct page **pages, long n_pages)
+{
+	while (n_pages--)
+		put_page(pages[n_pages]);
+	drm_free_large(pages);
+}
+
+static int vgem_prime_pin(struct drm_gem_object *obj)
+{
+	long n_pages = obj->size >> PAGE_SHIFT;
+	struct page **pages;
+
+	/* Flush the object from the CPU cache so that importers
+	 * can rely on coherent indirect access via access the
+	 * exported dma-address.
+	 */
+	pages = drm_gem_get_pages(obj);
+	if (IS_ERR(pages))
+		return PTR_ERR(pages);
+
+	drm_clflush_pages(pages, n_pages);
+	__put_pages(pages, n_pages);
+
+	return 0;
+}
+
+static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+	long n_pages = obj->size >> PAGE_SHIFT;
+	struct sg_table *st;
+	struct page **pages;
+	int ret;
+
+	st = kmalloc(sizeof(struct sg_table), GFP_KERNEL);
+	if (st == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	pages = drm_gem_get_pages(obj);
+	if (IS_ERR(pages)) {
+		ret = PTR_ERR(pages);
+		goto err;
+	}
+
+	ret = sg_alloc_table_from_pages(st, pages, n_pages,
+					0, obj->size, GFP_KERNEL);
+	__put_pages(pages, n_pages);
+	if (ret)
+		goto err;
+
+	return st;
+
+err:
+	kfree(st);
+	return ERR_PTR(ret);
+}
+
+static void *vgem_prime_vmap(struct drm_gem_object *obj)
+{
+	long n_pages = obj->size >> PAGE_SHIFT;
+	struct page **pages;
+	void *addr;
+
+	pages = drm_gem_get_pages(obj);
+	if (IS_ERR(pages))
+		return NULL;
+
+	addr = vmap(pages, n_pages, 0, pgprot_writecombine(PAGE_KERNEL_IO));
+	__put_pages(pages, n_pages);
+
+	return addr;
+}
+
+static void vgem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+	vunmap(vaddr);
+}
+
+static int vgem_prime_mmap(struct drm_gem_object *obj,
+			   struct vm_area_struct *vma)
+{
+	int ret;
+
+	if (obj->size < vma->vm_end - vma->vm_start)
+		return -EINVAL;
+
+	if (!obj->filp)
+		return -ENODEV;
+
+	ret = obj->filp->f_op->mmap(obj->filp, vma);
+	if (ret)
+		return ret;
+
+	fput(vma->vm_file);
+	vma->vm_file = get_file(obj->filp);
+	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP;
+	vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+
+	return 0;
+}
+
 static struct drm_driver vgem_driver = {
-	.driver_features		= DRIVER_GEM,
+	.driver_features		= DRIVER_GEM | DRIVER_PRIME,
 	.gem_free_object_unlocked	= vgem_gem_free_object,
 	.gem_vm_ops			= &vgem_gem_vm_ops,
 	.ioctls				= vgem_ioctls,
 	.fops				= &vgem_driver_fops,
+
 	.dumb_create			= vgem_gem_dumb_create,
 	.dumb_map_offset		= vgem_gem_dumb_map,
+
+	.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+	.gem_prime_pin = vgem_prime_pin,
+	.gem_prime_export = drm_gem_prime_export,
+	.gem_prime_get_sg_table = vgem_prime_get_sg_table,
+	.gem_prime_vmap = vgem_prime_vmap,
+	.gem_prime_vunmap = vgem_prime_vunmap,
+	.gem_prime_mmap = vgem_prime_mmap,
+
 	.name	= DRIVER_NAME,
 	.desc	= DRIVER_DESC,
 	.date	= DRIVER_DATE,
-- 
2.8.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2016-06-20 20:07 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-18 15:20 [PATCH 1/3] drm: Wait on the reservation object when sync'ing dmabufs Chris Wilson
2016-06-18 15:20 ` [PATCH 2/3] drm/vgem: Fix mmaping Chris Wilson
2016-06-21 21:04   ` Chris Wilson
2016-06-18 15:20 ` [PATCH 3/3] drm/vgem: Enable dmabuf interface for export Chris Wilson
2016-06-19  6:18   ` [PATCH v2] " Chris Wilson
2016-06-20 20:04     ` [PATCH v3 1/3] dmabuf Chris Wilson
2016-06-20 20:04       ` [PATCH v3 2/3] drm: Prevent NULL deref in drm_name_info() Chris Wilson
2016-06-20 20:04       ` [PATCH v3 3/3] meh Chris Wilson
2016-06-20 20:06       ` [PATCH v3 1/3] dmabuf Chris Wilson
2016-06-20 20:06     ` Chris Wilson [this message]
2016-06-27 17:57       ` [PATCH v3] drm/vgem: Enable dmabuf interface for export Zach Reizner
2016-06-18 22:37 ` [PATCH 1/3] drm: Wait on the reservation object when sync'ing dmabufs Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1466453219-6665-1-git-send-email-chris@chris-wilson.co.uk \
    --to=chris@chris-wilson.co.uk \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=zachr@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).