From patchwork Thu Apr 6 23:18:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laura Abbott X-Patchwork-Id: 9668551 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9B9A660364 for ; Thu, 6 Apr 2017 23:18:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B9003285DE for ; Thu, 6 Apr 2017 23:18:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id AE072285E9; Thu, 6 Apr 2017 23:18:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.7 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_SPAM autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4863C285DE for ; Thu, 6 Apr 2017 23:18:44 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EBF276E1E1; Thu, 6 Apr 2017 23:18:42 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pg0-f43.google.com (mail-pg0-f43.google.com [74.125.83.43]) by gabe.freedesktop.org (Postfix) with ESMTPS id 326C56E1E9 for ; Thu, 6 Apr 2017 23:18:41 +0000 (UTC) Received: by mail-pg0-f43.google.com with SMTP id x125so48835809pgb.0 for ; Thu, 06 Apr 2017 16:18:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=vWDxUGedQiX9wIFFRwEI/ZGnvAGSoJ5f3WUCK3Db1a0=; b=tj2SYGuZX8FF0+o1pW4P68iUNjP1/mRKIqV07MYY/7um/wSxViRy976/x5KrqHHRyO yxqy8z36BdQ8T8v/aP2hK40wLyfSSoFchcObFDEeqZ03919HMeQy+nFRatdHJDqSrdwH wkeAtbdyiIcSqyJR4h1OlBxOjrZODSup03XHJKuOU0VQIuOXVGQ0as3UIBsfGpTw6wNe IWEYMaWkYtwyf93SloJTogJ6yh9+OSYQ5Hf5Ol5l7IVmqMGFr9HzvFwZ7uZjJIuYA07p 9LzHuIKqFnp+a/bo+62YjWUT7uA2pXK+S0HeGTpam8zy8gwCCHRpTpopYBMNKHGDwnHC j7DA== X-Gm-Message-State: AFeK/H1UKG4Bh0ODM1yF997Id4raNSYeGOroixh82Q9PpFoowaQo1DRQgHsX/GDvJXkPbOxL X-Received: by 10.99.126.80 with SMTP id o16mr37563099pgn.1.1491520720718; Thu, 06 Apr 2017 16:18:40 -0700 (PDT) Received: from labbott-redhat-machine.hsd1.wa.comcast.net ([2601:602:9802:a8dc::159c]) by smtp.gmail.com with ESMTPSA id p68sm5599691pga.6.2017.04.06.16.18.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 06 Apr 2017 16:18:39 -0700 (PDT) From: Laura Abbott To: Daniel Vetter , Chris Wilson , Sean Paul Subject: [RFC PATCH 2/2] drm/vgem: Enable dmabuf import interfaces Date: Thu, 6 Apr 2017 16:18:33 -0700 Message-Id: <1491520713-14277-3-git-send-email-labbott@redhat.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1491520713-14277-1-git-send-email-labbott@redhat.com> References: <1491520713-14277-1-git-send-email-labbott@redhat.com> Cc: linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Enable the GEM dma-buf import interfaces in addition to the export interfaces. This lets vgem be used as a test source for other allocators (e.g. Ion). Signed-off-by: Laura Abbott --- drivers/gpu/drm/vgem/vgem_drv.c | 135 ++++++++++++++++++++++++++++++++-------- drivers/gpu/drm/vgem/vgem_drv.h | 3 + 2 files changed, 111 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index b94feef..abc72e1 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -34,6 +34,9 @@ #include #include #include + +#include + #include "vgem_drv.h" #define DRIVER_NAME "vgem" @@ -42,40 +45,67 @@ #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 +#define VGEM_BO_IMPORT BIT(0) + +void vgem_gem_put_pages(struct drm_vgem_gem_object *obj) +{ + drm_gem_put_pages(&obj->base, obj->pages, false, false); + obj->pages = NULL; +} + static void vgem_gem_free_object(struct drm_gem_object *obj) { struct drm_vgem_gem_object *vgem_obj = to_vgem_bo(obj); + if (vgem_obj->pages) { + if (vgem_obj->flags & VGEM_BO_IMPORT) + drm_free_large(vgem_obj->pages); + else + vgem_gem_put_pages(vgem_obj); + } + + if (obj->import_attach) + drm_prime_gem_destroy(obj, vgem_obj->table); + drm_gem_object_release(obj); kfree(vgem_obj); } +int vgem_gem_get_pages(struct drm_vgem_gem_object *obj) +{ + struct page **pages; + + if (obj->pages) + return 0; + + pages = drm_gem_get_pages(&obj->base); + if (IS_ERR(pages)) { + return PTR_ERR(pages); + } + + obj->pages = pages; + + return 0; +} + static int vgem_gem_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; struct drm_vgem_gem_object *obj = vma->vm_private_data; /* We don't use vmf->pgoff since that has the fake offset */ unsigned long vaddr = vmf->address; - struct page *page; + loff_t num_pages; + pgoff_t page_offset; + page_offset = (vaddr - vma->vm_start) >> PAGE_SHIFT; - page = shmem_read_mapping_page(file_inode(obj->base.filp)->i_mapping, - (vaddr - vma->vm_start) >> PAGE_SHIFT); - if (!IS_ERR(page)) { - vmf->page = page; - return 0; - } else switch (PTR_ERR(page)) { - case -ENOSPC: - case -ENOMEM: - return VM_FAULT_OOM; - case -EBUSY: - return VM_FAULT_RETRY; - case -EFAULT: - case -EINVAL: - return VM_FAULT_SIGBUS; - default: - WARN_ON_ONCE(PTR_ERR(page)); - return VM_FAULT_SIGBUS; - } + num_pages = DIV_ROUND_UP(obj->base.size, PAGE_SIZE); + + if (page_offset > num_pages) + return VM_FAULT_SIGBUS; + + get_page(obj->pages[page_offset]); + vmf->page = obj->pages[page_offset]; + return 0; } static const struct vm_operations_struct vgem_gem_vm_ops = { @@ -112,7 +142,30 @@ static void vgem_preclose(struct drm_device *dev, struct drm_file *file) kfree(vfile); } -/* ioctls */ +static struct drm_vgem_gem_object *__vgem_gem_create(struct drm_device *dev, + unsigned long size) +{ + struct drm_vgem_gem_object *obj; + int ret; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) + return ERR_PTR(-ENOMEM); + + ret = drm_gem_object_init(dev, &obj->base, roundup(size, PAGE_SIZE)); + if (ret) { + kfree(obj); + return ERR_PTR(ret); + } + + return obj; +} + +static void __vgem_gem_destroy(struct drm_vgem_gem_object *obj) +{ + drm_gem_object_release(&obj->base); + kfree(obj); +} static struct drm_gem_object *vgem_gem_create(struct drm_device *dev, struct drm_file *file, @@ -122,24 +175,25 @@ static struct drm_gem_object *vgem_gem_create(struct drm_device *dev, struct drm_vgem_gem_object *obj; int ret; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); - if (!obj) - return ERR_PTR(-ENOMEM); + obj = __vgem_gem_create(dev, size); + if (IS_ERR(obj)) + return ERR_CAST(obj); - ret = drm_gem_object_init(dev, &obj->base, roundup(size, PAGE_SIZE)); + ret = vgem_gem_get_pages(obj); if (ret) goto err_free; ret = drm_gem_handle_create(file, &obj->base, handle); drm_gem_object_unreference_unlocked(&obj->base); if (ret) - goto err; + goto err_pages; return &obj->base; +err_pages: + vgem_gem_put_pages(obj); err_free: - kfree(obj); -err: + __vgem_gem_destroy(obj); return ERR_PTR(ret); } @@ -256,6 +310,30 @@ static struct sg_table *vgem_prime_get_sg_table(struct drm_gem_object *obj) return st; } +static struct drm_gem_object *vgem_prime_import_sg_table(struct drm_device *dev, + struct dma_buf_attachment *attach, struct sg_table *sg) +{ + struct drm_vgem_gem_object *obj; + int npages; + + obj = __vgem_gem_create(dev, attach->dmabuf->size); + if (IS_ERR(obj)) + return ERR_CAST(obj); + + npages = PAGE_ALIGN(attach->dmabuf->size) / PAGE_SIZE; + + obj->table = sg; + obj->pages = drm_malloc_ab(npages, sizeof(struct page *)); + obj->flags = VGEM_BO_IMPORT; + if (!obj->pages) { + __vgem_gem_destroy(obj); + return ERR_PTR(-ENOMEM); + } + drm_prime_sg_to_page_addr_arrays(obj->table, obj->pages, NULL, + npages); + return &obj->base; +} + static void *vgem_prime_vmap(struct drm_gem_object *obj) { long n_pages = obj->size >> PAGE_SHIFT; @@ -314,8 +392,11 @@ static struct drm_driver vgem_driver = { .dumb_map_offset = vgem_gem_dumb_map, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_pin = vgem_prime_pin, + .gem_prime_import = drm_gem_prime_import, .gem_prime_export = drm_gem_prime_export, + .gem_prime_import_sg_table = vgem_prime_import_sg_table, .gem_prime_get_sg_table = vgem_prime_get_sg_table, .gem_prime_vmap = vgem_prime_vmap, .gem_prime_vunmap = vgem_prime_vunmap, diff --git a/drivers/gpu/drm/vgem/vgem_drv.h b/drivers/gpu/drm/vgem/vgem_drv.h index cb59c7a..f5dd076 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.h +++ b/drivers/gpu/drm/vgem/vgem_drv.h @@ -43,6 +43,9 @@ struct vgem_file { #define to_vgem_bo(x) container_of(x, struct drm_vgem_gem_object, base) struct drm_vgem_gem_object { struct drm_gem_object base; + struct page **pages; + struct sg_table *table; + unsigned long flags; }; int vgem_fence_open(struct vgem_file *file);