From patchwork Tue Mar 5 20:54:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 10840113 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2F4C514DE for ; Tue, 5 Mar 2019 20:54:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1A2E02AA6B for ; Tue, 5 Mar 2019 20:54:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0E0112CE19; Tue, 5 Mar 2019 20:54:50 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 37E662AA6B for ; Tue, 5 Mar 2019 20:54:49 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 66A5189BF1; Tue, 5 Mar 2019 20:54:45 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by gabe.freedesktop.org (Postfix) with ESMTPS id A8F5989C16 for ; Tue, 5 Mar 2019 20:54:43 +0000 (UTC) Received: by mail-pg1-x544.google.com with SMTP id h11so6477199pgl.0 for ; Tue, 05 Mar 2019 12:54:43 -0800 (PST) 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=BG94J8n4JZbnxfrekiwpt69zPxSc7JCbOZr/oAI9WHA=; b=jOU0BSKyQD48bqVo+AR+bT+LxXDeTMYofHWAOxGDQ0WPevem8Ny3E7Wl6Q1K7bQAjA DJEHlLigQcw+Tr/SPm92+tMZjAb+HeHDw0QEVUHd+YmCSe4NMjixJ0RE0rIr38XYQ4fF aVALm/nTKD/ofgrzYdFsMN6kgRfxFKSUgbB0GXlEf9wy+iZVgyNdzBlnB69UH8weMaoD z93XULVf9GUDdDNqvYCmTo1oW4xBkveAAFxnc6/cQzAQbUxuGmP6Y8mIe6Ubmc9ncPad FPPqd+Kcx50/HKiJjv0XdyJ0LpJ3jQ3FfUl/JLxVpFyXDAyKYkigoXnOIjnmAp242Qwx iXXw== X-Gm-Message-State: APjAAAWZqIXIZc/5HdW5hg0H+/3k17hIMWhfBW/rY2Ylsjwj1BeoHaHo HwvffE4u2Uw/ZPNR2vlgWzl9Eg== X-Google-Smtp-Source: APXvYqwhBQzKMB98Agxzd4hdnG+gvvWsB/MpP1KzDsieRzFUOBTztn3nv3OM7smscsoV9DNO6/GoYg== X-Received: by 2002:a17:902:380c:: with SMTP id l12mr3150482plc.326.1551819283088; Tue, 05 Mar 2019 12:54:43 -0800 (PST) Received: from localhost.localdomain ([2601:1c2:680:1319:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id i4sm13411788pfo.158.2019.03.05.12.54.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Mar 2019 12:54:41 -0800 (PST) From: John Stultz To: lkml Subject: [RFC][PATCH 1/5 v2] dma-buf: Add dma-buf heaps framework Date: Tue, 5 Mar 2019 12:54:29 -0800 Message-Id: <1551819273-640-2-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1551819273-640-1-git-send-email-john.stultz@linaro.org> References: <1551819273-640-1-git-send-email-john.stultz@linaro.org> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BG94J8n4JZbnxfrekiwpt69zPxSc7JCbOZr/oAI9WHA=; b=DvBnCV+VDj6+dTQ3JqYAVu46uY16fx5QHPkEp0TQbCH9iJDLmAAAmUPVlNyfhOA3Ot jRcM94UeZmqSG17v3aKd4pggxnbM38DAL8k6azBaWy756ZTGdlovhWnCPUW6iNVvf4rC 1I4YhSK3IvAsVj2RktHrg/beONtZf1eRla9GTJwRPog+8SCK7nzk/Mb7PatfthTChnjC OM7U3DUq45P2tw19RCx8QcjRrtKjF019N5ySCUmbZUqJw8WvyXb18eoHbw5XabTbtbmL dvv8RYA2TgjjXwf9K45/B39jMIavUe9Hq7eyEEPgwa++YdiRLLmVr+ptEx0i4MaQ3Ye0 x68Q== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg KH , Chenbo Feng , Alistair Strachan , Liam Mark , "Andrew F. Davis" , dri-devel@lists.freedesktop.org MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: "Andrew F. Davis" This framework allows a unified userspace interface for dma-buf exporters, allowing userland to allocate specific types of memory for use in dma-buf sharing. Each heap is given its own device node, which a user can allocate a dma-buf fd from using the DMA_HEAP_IOC_ALLOC. This code is an evoluiton of the Android ION implementation, and a big thanks is due to its authors/maintainers over time for their effort: Rebecca Schultz Zavin, Colin Cross, Benjamin Gaignard, Laura Abbott, and many other contributors! Cc: Laura Abbott Cc: Benjamin Gaignard Cc: Greg KH Cc: Sumit Semwal Cc: Liam Mark Cc: Brian Starkey Cc: Andrew F. Davis Cc: Chenbo Feng Cc: Alistair Strachan Cc: dri-devel@lists.freedesktop.org Signed-off-by: Andrew F. Davis [jstultz: reworded commit message, and lots of cleanups] Signed-off-by: John Stultz --- v2: * Folded down fixes I had previously shared in implementing heaps * Make flags a u64 (Suggested by Laura) * Add PAGE_ALIGN() fix to the core alloc funciton * IOCTL fixups suggested by Brian * Added fixes suggested by Benjamin * Removed core stats mgmt, as that should be implemented by per-heap code * Changed alloc to return a dma-buf fd, rather then a buffer (as it simplifies error handling) --- MAINTAINERS | 16 ++++ drivers/dma-buf/Kconfig | 8 ++ drivers/dma-buf/Makefile | 1 + drivers/dma-buf/dma-heap.c | 191 ++++++++++++++++++++++++++++++++++++++++++ include/linux/dma-heap.h | 65 ++++++++++++++ include/uapi/linux/dma-heap.h | 52 ++++++++++++ 6 files changed, 333 insertions(+) create mode 100644 drivers/dma-buf/dma-heap.c create mode 100644 include/linux/dma-heap.h create mode 100644 include/uapi/linux/dma-heap.h diff --git a/MAINTAINERS b/MAINTAINERS index ac2e518..a661e19 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4621,6 +4621,22 @@ F: include/linux/*fence.h F: Documentation/driver-api/dma-buf.rst T: git git://anongit.freedesktop.org/drm/drm-misc +DMA-BUF HEAPS FRAMEWORK +M: Laura Abbott +R: Liam Mark +R: Brian Starkey +R: "Andrew F. Davis" +R: John Stultz +S: Maintained +L: linux-media@vger.kernel.org +L: dri-devel@lists.freedesktop.org +L: linaro-mm-sig@lists.linaro.org (moderated for non-subscribers) +F: include/uapi/linux/dma-heap.h +F: include/linux/dma-heap.h +F: drivers/dma-buf/dma-heap.c +F: drivers/dma-buf/heaps/* +T: git git://anongit.freedesktop.org/drm/drm-misc + DMA GENERIC OFFLOAD ENGINE SUBSYSTEM M: Vinod Koul L: dmaengine@vger.kernel.org diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig index 2e5a0fa..09c61db 100644 --- a/drivers/dma-buf/Kconfig +++ b/drivers/dma-buf/Kconfig @@ -39,4 +39,12 @@ config UDMABUF A driver to let userspace turn memfd regions into dma-bufs. Qemu can use this to create host dmabufs for guest framebuffers. +menuconfig DMABUF_HEAPS + bool "DMA-BUF Userland Memory Heaps" + select DMA_SHARED_BUFFER + help + Choose this option to enable the DMA-BUF userland memory heaps, + this allows userspace to allocate dma-bufs that can be shared between + drivers. + endmenu diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index 0913a6c..b0332f1 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -1,4 +1,5 @@ obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o +obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o obj-$(CONFIG_SYNC_FILE) += sync_file.o obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o obj-$(CONFIG_UDMABUF) += udmabuf.o diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c new file mode 100644 index 0000000..14b3975 --- /dev/null +++ b/drivers/dma-buf/dma-heap.c @@ -0,0 +1,191 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Framework for userspace DMA-BUF allocations + * + * Copyright (C) 2011 Google, Inc. + * Copyright (C) 2019 Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define DEVNAME "dma_heap" + +#define NUM_HEAP_MINORS 128 +static DEFINE_IDR(dma_heap_idr); +static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */ + +dev_t dma_heap_devt; +struct class *dma_heap_class; +struct list_head dma_heap_list; +struct dentry *dma_heap_debug_root; + +static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, + unsigned int flags) +{ + len = PAGE_ALIGN(len); + if (!len) + return -EINVAL; + + return heap->ops->allocate(heap, len, flags); +} + +static int dma_heap_open(struct inode *inode, struct file *filp) +{ + struct dma_heap *heap; + + mutex_lock(&minor_lock); + heap = idr_find(&dma_heap_idr, iminor(inode)); + mutex_unlock(&minor_lock); + if (!heap) { + pr_err("dma_heap: minor %d unknown.\n", iminor(inode)); + return -ENODEV; + } + + /* instance data as context */ + filp->private_data = heap; + nonseekable_open(inode, filp); + + return 0; +} + +static int dma_heap_release(struct inode *inode, struct file *filp) +{ + filp->private_data = NULL; + + return 0; +} + +static long dma_heap_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + switch (cmd) { + case DMA_HEAP_IOC_ALLOC: + { + struct dma_heap_allocation_data heap_allocation; + struct dma_heap *heap = filp->private_data; + int fd; + + if (copy_from_user(&heap_allocation, (void __user *)arg, + sizeof(heap_allocation))) + return -EFAULT; + + if (heap_allocation.fd || + heap_allocation.reserved0 || + heap_allocation.reserved1 || + heap_allocation.reserved2) { + pr_warn_once("dma_heap: ioctl data not valid\n"); + return -EINVAL; + } + if (heap_allocation.flags & ~DMA_HEAP_VALID_FLAGS) { + pr_warn_once("dma_heap: flags has invalid or unsupported flags set\n"); + return -EINVAL; + } + + fd = dma_heap_buffer_alloc(heap, heap_allocation.len, + heap_allocation.flags); + if (fd < 0) + return fd; + + heap_allocation.fd = fd; + + if (copy_to_user((void __user *)arg, &heap_allocation, + sizeof(heap_allocation))) + return -EFAULT; + + break; + } + default: + return -ENOTTY; + } + + return 0; +} + +static const struct file_operations dma_heap_fops = { + .owner = THIS_MODULE, + .open = dma_heap_open, + .release = dma_heap_release, + .unlocked_ioctl = dma_heap_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = dma_heap_ioctl, +#endif +}; + +int dma_heap_add(struct dma_heap *heap) +{ + struct device *dev_ret; + int ret; + + if (!heap->name || !strcmp(heap->name, "")) { + pr_err("dma_heap: Cannot add heap without a name\n"); + return -EINVAL; + } + + if (!heap->ops || !heap->ops->allocate) { + pr_err("dma_heap: Cannot add heap with invalid ops struct\n"); + return -EINVAL; + } + + /* Find unused minor number */ + mutex_lock(&minor_lock); + ret = idr_alloc(&dma_heap_idr, heap, 0, NUM_HEAP_MINORS, GFP_KERNEL); + mutex_unlock(&minor_lock); + if (ret < 0) { + pr_err("dma_heap: Unable to get minor number for heap\n"); + return ret; + } + heap->minor = ret; + + /* Create device */ + heap->heap_devt = MKDEV(MAJOR(dma_heap_devt), heap->minor); + dev_ret = device_create(dma_heap_class, + NULL, + heap->heap_devt, + NULL, + heap->name); + if (IS_ERR(dev_ret)) { + pr_err("dma_heap: Unable to create char device\n"); + return PTR_ERR(dev_ret); + } + + /* Add device */ + cdev_init(&heap->heap_cdev, &dma_heap_fops); + ret = cdev_add(&heap->heap_cdev, dma_heap_devt, NUM_HEAP_MINORS); + if (ret < 0) { + device_destroy(dma_heap_class, heap->heap_devt); + pr_err("dma_heap: Unable to add char device\n"); + return ret; + } + + return 0; +} +EXPORT_SYMBOL(dma_heap_add); + +static int dma_heap_init(void) +{ + int ret; + + ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME); + if (ret) + return ret; + + dma_heap_class = class_create(THIS_MODULE, DEVNAME); + if (IS_ERR(dma_heap_class)) { + unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS); + return PTR_ERR(dma_heap_class); + } + + return 0; +} +subsys_initcall(dma_heap_init); diff --git a/include/linux/dma-heap.h b/include/linux/dma-heap.h new file mode 100644 index 0000000..ed86a8e --- /dev/null +++ b/include/linux/dma-heap.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * DMABUF Heaps Allocation Infrastructure + * + * Copyright (C) 2011 Google, Inc. + * Copyright (C) 2019 Linaro Ltd. + */ + +#ifndef _DMA_HEAPS_H +#define _DMA_HEAPS_H + +#include +#include + +/** + * struct dma_heap_buffer - metadata for a particular buffer + * @heap: back pointer to the heap the buffer came from + * @dmabuf: backing dma-buf for this buffer + * @size: size of the buffer + * @flags: buffer specific flags + */ +struct dma_heap_buffer { + struct dma_heap *heap; + struct dma_buf *dmabuf; + size_t size; + unsigned long flags; +}; + +/** + * struct dma_heap - represents a dmabuf heap in the system + * @name: used for debugging/device-node name + * @ops: ops struct for this heap + * @minor minor number of this heap device + * @heap_devt heap device node + * @heap_cdev heap char device + * + * Represents a heap of memory from which buffers can be made. + */ +struct dma_heap { + const char *name; + struct dma_heap_ops *ops; + unsigned int minor; + dev_t heap_devt; + struct cdev heap_cdev; +}; + +/** + * struct dma_heap_ops - ops to operate on a given heap + * @allocate: allocate dmabuf and return fd + * + * allocate returns dmabuf fd on success, -errno on error. + */ +struct dma_heap_ops { + int (*allocate)(struct dma_heap *heap, + unsigned long len, + unsigned long flags); +}; + +/** + * dma_heap_add - adds a heap to dmabuf heaps + * @heap: the heap to add + */ +int dma_heap_add(struct dma_heap *heap); + +#endif /* _DMA_HEAPS_H */ diff --git a/include/uapi/linux/dma-heap.h b/include/uapi/linux/dma-heap.h new file mode 100644 index 0000000..75c5d3f --- /dev/null +++ b/include/uapi/linux/dma-heap.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * DMABUF Heaps Userspace API + * + * Copyright (C) 2011 Google, Inc. + * Copyright (C) 2019 Linaro Ltd. + */ +#ifndef _UAPI_LINUX_DMABUF_POOL_H +#define _UAPI_LINUX_DMABUF_POOL_H + +#include +#include + +/** + * DOC: DMABUF Heaps Userspace API + * + */ + +/* Currently no flags */ +#define DMA_HEAP_VALID_FLAGS (0) + +/** + * struct dma_heap_allocation_data - metadata passed from userspace for + * allocations + * @len: size of the allocation + * @flags: flags passed to pool + * @fd: will be populated with a fd which provdes the + * handle to the allocated dma-buf + * + * Provided by userspace as an argument to the ioctl + */ +struct dma_heap_allocation_data { + __u64 len; + __u64 flags; + __u32 fd; + __u32 reserved0; + __u32 reserved1; + __u32 reserved2; +}; + +#define DMA_HEAP_IOC_MAGIC 'H' + +/** + * DOC: DMA_HEAP_IOC_ALLOC - allocate memory from pool + * + * Takes an dma_heap_allocation_data struct and returns it with the fd field + * populated with the dmabuf handle of the allocation. + */ +#define DMA_HEAP_IOC_ALLOC _IOWR(DMA_HEAP_IOC_MAGIC, 0, \ + struct dma_heap_allocation_data) + +#endif /* _UAPI_LINUX_DMABUF_POOL_H */ From patchwork Tue Mar 5 20:54:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 10840115 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A506114DE for ; Tue, 5 Mar 2019 20:54:52 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 923D02AA6B for ; Tue, 5 Mar 2019 20:54:52 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8632D2CE19; Tue, 5 Mar 2019 20:54:52 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 B92F82AA6B for ; Tue, 5 Mar 2019 20:54:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F2CCF89C60; Tue, 5 Mar 2019 20:54:46 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) by gabe.freedesktop.org (Postfix) with ESMTPS id 702F889C16 for ; Tue, 5 Mar 2019 20:54:45 +0000 (UTC) Received: by mail-pf1-x443.google.com with SMTP id u9so6618964pfn.1 for ; Tue, 05 Mar 2019 12:54:45 -0800 (PST) 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=V4gbFKLyjI3IwmyANMx9RTxgAjbN5gJRajPVnQsoKow=; b=uEGDdNKhaz5APqvX9WSIFaBNfhhqkarYIrSURKeaBGQd6mPmQJep7568whfo8LKikX +cWZsTSmwzlYV1NAWB7/qzIeNSKf8zEsMwHnLykHHBAYZAiWrMkMs4ObMvZC/0Dh38Ck OXhqsfTamJU88Ttx5UYq6kKeI6UdSqHU26eV6lDozpaYH9+r3w16rl8vKvT7Nadj1S0x CUyf+HxDkYFfk0Iw0gY1vqCMeK8Fe8XOvTc1SqinrezzgTWSkFL2GTMDxZxF1pxpIknc Am3sIMs9uubQPVRLSI9mEiozwnfsVI5YcYfJ+paixvh6e/+QYN+r8TfEa8AxGt5BXg8/ ibxA== X-Gm-Message-State: APjAAAVs5bDl/8igejU7zFXALIyucexX0+HfkA2stDsRsZ5EL5BPaz4r 7fMJWfCHo+9bCA77dg8We2O3AA== X-Google-Smtp-Source: APXvYqwjoDN0TV9qV8dX52oCEtTS7B1X2+9fRWiLb/GYUrddBubzSbk3CGQdr1xikKUKpm7vwp+aIg== X-Received: by 2002:a65:6241:: with SMTP id q1mr3146039pgv.340.1551819284810; Tue, 05 Mar 2019 12:54:44 -0800 (PST) Received: from localhost.localdomain ([2601:1c2:680:1319:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id i4sm13411788pfo.158.2019.03.05.12.54.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Mar 2019 12:54:43 -0800 (PST) From: John Stultz To: lkml Subject: [RFC][PATCH 2/5 v2] dma-buf: heaps: Add heap helpers Date: Tue, 5 Mar 2019 12:54:30 -0800 Message-Id: <1551819273-640-3-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1551819273-640-1-git-send-email-john.stultz@linaro.org> References: <1551819273-640-1-git-send-email-john.stultz@linaro.org> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=V4gbFKLyjI3IwmyANMx9RTxgAjbN5gJRajPVnQsoKow=; b=tQ3o7bDEfeFHNNx9lxcsffx/ug2FlH6XBA80njihZ82Qubnsm9gFWpTOt3ssLsgmke NVoHUmU82mFiPJkh9x+SrBQOwCRNNdbmJ5F47VB2OKwuWtoFa8Z1ykd9aryppldlnhcV RTgJS41k57yo0St04Wff+xyrcDmVD8sLa10X1fxerw9NcgfUjOdne2Q4kiztqENL80wW dRxtZtc2vxLK2D7ym5tjbbkF//mBdrWXByMIz8bu1oLhUsNKfh0z1aAhpABTE0cAu3Tw EpIgqIT5HXIqN35clE+c4O4XmtdPoqy3sVU5WWVZVdFeEiBueZbmohXH82F9LEMt/c9x e1Rg== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg KH , Chenbo Feng , Alistair Strachan , Liam Mark , dri-devel@lists.freedesktop.org, "Andrew F . Davis" MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add generic helper dmabuf ops for dma heaps, so we can reduce the amount of duplicative code for the exported dmabufs. This code is an evolution of the Android ION implementation, so thanks to its original authors and maintainters: Rebecca Schultz Zavin, Colin Cross, Laura Abbott, and others! Cc: Laura Abbott Cc: Benjamin Gaignard Cc: Greg KH Cc: Sumit Semwal Cc: Liam Mark Cc: Brian Starkey Cc: Andrew F. Davis Cc: Chenbo Feng Cc: Alistair Strachan Cc: dri-devel@lists.freedesktop.org Signed-off-by: John Stultz --- v2: * Removed cache management performance hack that I had accidentally folded in. * Removed stats code that was in helpers * Lots of checkpatch cleanups --- drivers/dma-buf/Makefile | 1 + drivers/dma-buf/heaps/Makefile | 2 + drivers/dma-buf/heaps/heap-helpers.c | 335 +++++++++++++++++++++++++++++++++++ drivers/dma-buf/heaps/heap-helpers.h | 48 +++++ 4 files changed, 386 insertions(+) create mode 100644 drivers/dma-buf/heaps/Makefile create mode 100644 drivers/dma-buf/heaps/heap-helpers.c create mode 100644 drivers/dma-buf/heaps/heap-helpers.h diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile index b0332f1..09c2f2d 100644 --- a/drivers/dma-buf/Makefile +++ b/drivers/dma-buf/Makefile @@ -1,4 +1,5 @@ obj-y := dma-buf.o dma-fence.o dma-fence-array.o reservation.o seqno-fence.o +obj-$(CONFIG_DMABUF_HEAPS) += heaps/ obj-$(CONFIG_DMABUF_HEAPS) += dma-heap.o obj-$(CONFIG_SYNC_FILE) += sync_file.o obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile new file mode 100644 index 0000000..de49898 --- /dev/null +++ b/drivers/dma-buf/heaps/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-y += heap-helpers.o diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c new file mode 100644 index 0000000..ae5e9d0 --- /dev/null +++ b/drivers/dma-buf/heaps/heap-helpers.c @@ -0,0 +1,335 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "heap-helpers.h" + + +static void *dma_heap_map_kernel(struct heap_helper_buffer *buffer) +{ + struct scatterlist *sg; + int i, j; + void *vaddr; + pgprot_t pgprot; + struct sg_table *table = buffer->sg_table; + int npages = PAGE_ALIGN(buffer->heap_buffer.size) / PAGE_SIZE; + struct page **pages = vmalloc(array_size(npages, + sizeof(struct page *))); + struct page **tmp = pages; + + if (!pages) + return ERR_PTR(-ENOMEM); + + pgprot = PAGE_KERNEL; + + for_each_sg(table->sgl, sg, table->nents, i) { + int npages_this_entry = PAGE_ALIGN(sg->length) / PAGE_SIZE; + struct page *page = sg_page(sg); + + WARN_ON(i >= npages); + for (j = 0; j < npages_this_entry; j++) + *(tmp++) = page++; + } + vaddr = vmap(pages, npages, VM_MAP, pgprot); + vfree(pages); + + if (!vaddr) + return ERR_PTR(-ENOMEM); + + return vaddr; +} + +static int dma_heap_map_user(struct heap_helper_buffer *buffer, + struct vm_area_struct *vma) +{ + struct sg_table *table = buffer->sg_table; + unsigned long addr = vma->vm_start; + unsigned long offset = vma->vm_pgoff * PAGE_SIZE; + struct scatterlist *sg; + int i; + int ret; + + for_each_sg(table->sgl, sg, table->nents, i) { + struct page *page = sg_page(sg); + unsigned long remainder = vma->vm_end - addr; + unsigned long len = sg->length; + + if (offset >= sg->length) { + offset -= sg->length; + continue; + } else if (offset) { + page += offset / PAGE_SIZE; + len = sg->length - offset; + offset = 0; + } + len = min(len, remainder); + ret = remap_pfn_range(vma, addr, page_to_pfn(page), len, + vma->vm_page_prot); + if (ret) + return ret; + addr += len; + if (addr >= vma->vm_end) + return 0; + } + + return 0; +} + + +void dma_heap_buffer_destroy(struct dma_heap_buffer *heap_buffer) +{ + struct heap_helper_buffer *buffer = to_helper_buffer(heap_buffer); + + if (buffer->kmap_cnt > 0) { + pr_warn_once("%s: buffer still mapped in the kernel\n", + __func__); + vunmap(buffer->vaddr); + } + + buffer->free(buffer); +} + +static void *dma_heap_buffer_kmap_get(struct dma_heap_buffer *heap_buffer) +{ + struct heap_helper_buffer *buffer = to_helper_buffer(heap_buffer); + void *vaddr; + + if (buffer->kmap_cnt) { + buffer->kmap_cnt++; + return buffer->vaddr; + } + vaddr = dma_heap_map_kernel(buffer); + if (WARN_ONCE(!vaddr, + "heap->ops->map_kernel should return ERR_PTR on error")) + return ERR_PTR(-EINVAL); + if (IS_ERR(vaddr)) + return vaddr; + buffer->vaddr = vaddr; + buffer->kmap_cnt++; + return vaddr; +} + +static void dma_heap_buffer_kmap_put(struct dma_heap_buffer *heap_buffer) +{ + struct heap_helper_buffer *buffer = to_helper_buffer(heap_buffer); + + buffer->kmap_cnt--; + if (!buffer->kmap_cnt) { + vunmap(buffer->vaddr); + buffer->vaddr = NULL; + } +} + +static struct sg_table *dup_sg_table(struct sg_table *table) +{ + struct sg_table *new_table; + int ret, i; + struct scatterlist *sg, *new_sg; + + new_table = kzalloc(sizeof(*new_table), GFP_KERNEL); + if (!new_table) + return ERR_PTR(-ENOMEM); + + ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL); + if (ret) { + kfree(new_table); + return ERR_PTR(-ENOMEM); + } + + new_sg = new_table->sgl; + for_each_sg(table->sgl, sg, table->nents, i) { + memcpy(new_sg, sg, sizeof(*sg)); + new_sg->dma_address = 0; + new_sg = sg_next(new_sg); + } + + return new_table; +} + +static void free_duped_table(struct sg_table *table) +{ + sg_free_table(table); + kfree(table); +} + +struct dma_heaps_attachment { + struct device *dev; + struct sg_table *table; + struct list_head list; +}; + +static int dma_heap_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct dma_heaps_attachment *a; + struct sg_table *table; + struct dma_heap_buffer *heap_buffer = dmabuf->priv; + struct heap_helper_buffer *buffer = to_helper_buffer(heap_buffer); + + a = kzalloc(sizeof(*a), GFP_KERNEL); + if (!a) + return -ENOMEM; + + table = dup_sg_table(buffer->sg_table); + if (IS_ERR(table)) { + kfree(a); + return -ENOMEM; + } + + a->table = table; + a->dev = attachment->dev; + INIT_LIST_HEAD(&a->list); + + attachment->priv = a; + + mutex_lock(&buffer->lock); + list_add(&a->list, &buffer->attachments); + mutex_unlock(&buffer->lock); + + return 0; +} + +static void dma_heap_detatch(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct dma_heaps_attachment *a = attachment->priv; + struct dma_heap_buffer *heap_buffer = dmabuf->priv; + struct heap_helper_buffer *buffer = to_helper_buffer(heap_buffer); + + mutex_lock(&buffer->lock); + list_del(&a->list); + mutex_unlock(&buffer->lock); + free_duped_table(a->table); + + kfree(a); +} + +static struct sg_table *dma_heap_map_dma_buf( + struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + struct dma_heaps_attachment *a = attachment->priv; + struct sg_table *table; + + table = a->table; + + if (!dma_map_sg(attachment->dev, table->sgl, table->nents, + direction)) + table = ERR_PTR(-ENOMEM); + return table; +} + +static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *table, + enum dma_data_direction direction) +{ + dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction); +} + +static int dma_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + struct dma_heap_buffer *heap_buffer = dmabuf->priv; + struct heap_helper_buffer *buffer = to_helper_buffer(heap_buffer); + int ret = 0; + + mutex_lock(&buffer->lock); + /* now map it to userspace */ + ret = dma_heap_map_user(buffer, vma); + mutex_unlock(&buffer->lock); + + if (ret) + pr_err("%s: failure mapping buffer to userspace\n", + __func__); + + return ret; +} + +static void dma_heap_dma_buf_release(struct dma_buf *dmabuf) +{ + struct dma_heap_buffer *buffer = dmabuf->priv; + + dma_heap_buffer_destroy(buffer); +} + +static void *dma_heap_dma_buf_kmap(struct dma_buf *dmabuf, + unsigned long offset) +{ + struct dma_heap_buffer *heap_buffer = dmabuf->priv; + struct heap_helper_buffer *buffer = to_helper_buffer(heap_buffer); + + return buffer->vaddr + offset * PAGE_SIZE; +} + +static void dma_heap_dma_buf_kunmap(struct dma_buf *dmabuf, + unsigned long offset, + void *ptr) +{ +} + +static int dma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction direction) +{ + struct dma_heap_buffer *heap_buffer = dmabuf->priv; + struct heap_helper_buffer *buffer = to_helper_buffer(heap_buffer); + void *vaddr; + struct dma_heaps_attachment *a; + int ret = 0; + + mutex_lock(&buffer->lock); + vaddr = dma_heap_buffer_kmap_get(heap_buffer); + if (IS_ERR(vaddr)) { + ret = PTR_ERR(vaddr); + goto unlock; + } + mutex_unlock(&buffer->lock); + + mutex_lock(&buffer->lock); + list_for_each_entry(a, &buffer->attachments, list) { + dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents, + direction); + } + +unlock: + mutex_unlock(&buffer->lock); + return ret; +} + +static int dma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, + enum dma_data_direction direction) +{ + struct dma_heap_buffer *heap_buffer = dmabuf->priv; + struct heap_helper_buffer *buffer = to_helper_buffer(heap_buffer); + struct dma_heaps_attachment *a; + + mutex_lock(&buffer->lock); + dma_heap_buffer_kmap_put(heap_buffer); + mutex_unlock(&buffer->lock); + + mutex_lock(&buffer->lock); + list_for_each_entry(a, &buffer->attachments, list) { + dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents, + direction); + } + mutex_unlock(&buffer->lock); + + return 0; +} + +const struct dma_buf_ops heap_helper_ops = { + .map_dma_buf = dma_heap_map_dma_buf, + .unmap_dma_buf = dma_heap_unmap_dma_buf, + .mmap = dma_heap_mmap, + .release = dma_heap_dma_buf_release, + .attach = dma_heap_attach, + .detach = dma_heap_detatch, + .begin_cpu_access = dma_heap_dma_buf_begin_cpu_access, + .end_cpu_access = dma_heap_dma_buf_end_cpu_access, + .map = dma_heap_dma_buf_kmap, + .unmap = dma_heap_dma_buf_kunmap, +}; diff --git a/drivers/dma-buf/heaps/heap-helpers.h b/drivers/dma-buf/heaps/heap-helpers.h new file mode 100644 index 0000000..0bd8643 --- /dev/null +++ b/drivers/dma-buf/heaps/heap-helpers.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * DMABUF Heaps helper code + * + * Copyright (C) 2011 Google, Inc. + * Copyright (C) 2019 Linaro Ltd. + */ + +#ifndef _HEAP_HELPERS_H +#define _HEAP_HELPERS_H + +#include +#include + +struct heap_helper_buffer { + struct dma_heap_buffer heap_buffer; + + unsigned long private_flags; + void *priv_virt; + struct mutex lock; + int kmap_cnt; + void *vaddr; + struct sg_table *sg_table; + struct list_head attachments; + + void (*free)(struct heap_helper_buffer *buffer); + +}; + +#define to_helper_buffer(x) \ + container_of(x, struct heap_helper_buffer, heap_buffer) + +static inline void INIT_HEAP_HELPER_BUFFER(struct heap_helper_buffer *buffer, + void (*free)(struct heap_helper_buffer *)) +{ + buffer->private_flags = 0; + buffer->priv_virt = NULL; + mutex_init(&buffer->lock); + buffer->kmap_cnt = 0; + buffer->vaddr = NULL; + buffer->sg_table = NULL; + INIT_LIST_HEAD(&buffer->attachments); + buffer->free = free; +} + +extern const struct dma_buf_ops heap_helper_ops; + +#endif /* _HEAP_HELPERS_H */ From patchwork Tue Mar 5 20:54:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 10840117 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DB61D1575 for ; Tue, 5 Mar 2019 20:54:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C9EE52AA6B for ; Tue, 5 Mar 2019 20:54:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BDBF12CE19; Tue, 5 Mar 2019 20:54:54 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 3DB6C2AA6B for ; Tue, 5 Mar 2019 20:54:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3FEA089C16; Tue, 5 Mar 2019 20:54:49 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pf1-x441.google.com (mail-pf1-x441.google.com [IPv6:2607:f8b0:4864:20::441]) by gabe.freedesktop.org (Postfix) with ESMTPS id E301989C16 for ; Tue, 5 Mar 2019 20:54:46 +0000 (UTC) Received: by mail-pf1-x441.google.com with SMTP id n125so6614455pfn.5 for ; Tue, 05 Mar 2019 12:54:46 -0800 (PST) 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=10sN7326k7j9LMSRAvavufAoxXSQ/sxj9rGttiEYBLI=; b=eh8EUpe4Am8LvaKLDVlJNYDdjuQlrT+iIgEJNLaXZ9lW5ZhFVirXwW3iWF28H8fZIn lFLnzP65WX0Mdb5c1gXJsrzfau57MSCGydEbB2E9XbWzGyCtgzJw1fkMFilT6403JdzB 2f4RZrwO0y5scOHdGwoyZlS+9MugZxvTikop2la7eoVPvOOYM7tYVjYDtsYhBQC55PiR HILeuGvtRkQ1WRZnsKaEmX7bcGSynTgYTS646Wnrw5aqVNyeFLh2Bmm4ufLfvRUxmYKk 9GJxEKOEGc0kWsfhh28A9KnnvEbQ53JO9O6Q+Q/IvXb23xDl02ervPsFFqcHWjYLsG+n 2ZtA== X-Gm-Message-State: APjAAAU82jew1v1xwCWrXZXCmaHc1zjVOklC5deUi25iwXhvRi8lY/VD 8S29qUrm/WcdXQsvNJEhz2Mc+A== X-Google-Smtp-Source: APXvYqyw6P1dcy/08qrowb3Lcm2ulZcEET3axbofUHPNEjyyJTCXZqG8t1VPyxs28WwSFfLYwYRtGw== X-Received: by 2002:a17:902:b093:: with SMTP id p19mr3194304plr.139.1551819286365; Tue, 05 Mar 2019 12:54:46 -0800 (PST) Received: from localhost.localdomain ([2601:1c2:680:1319:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id i4sm13411788pfo.158.2019.03.05.12.54.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Mar 2019 12:54:45 -0800 (PST) From: John Stultz To: lkml Subject: [RFC][PATCH 3/5 v2] dma-buf: heaps: Add system heap to dmabuf heaps Date: Tue, 5 Mar 2019 12:54:31 -0800 Message-Id: <1551819273-640-4-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1551819273-640-1-git-send-email-john.stultz@linaro.org> References: <1551819273-640-1-git-send-email-john.stultz@linaro.org> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=10sN7326k7j9LMSRAvavufAoxXSQ/sxj9rGttiEYBLI=; b=y9lnW8Kmg4irPZPNx525O45cijd7sNdoQiLbkI6aBgRQH4pY3hwkFcZpSHZpvky9FZ wpSE5CC9PnR8pSMtn0ZsW1xOz92fTrNyLGW2r7ABwUQmx3L2VMncHcp5P3veEfzU6L4+ q2380Qw4gqYxrEPwi4arsJBcSu0eyBPNppR4/XvZxWsXchOWW4w8+QagHCsbsll+/3wx sp2F2H9XMwiCaWco6ECKJLGvu1nVENUrD52ScmkmD7PLxFiW4HRE8F73dtwP6om+pRd+ 0rtk3moDnsiXq1f9dQsdo7nXNnzESau052vS2EGHRWvdKP1Km7azf1V1S5TQulCcFwCs 6f6Q== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg KH , Chenbo Feng , Alistair Strachan , Liam Mark , dri-devel@lists.freedesktop.org, "Andrew F . Davis" MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch adds system heap to the dma-buf heaps framework. This allows applications to get a page-allocator backed dma-buf for non-contiguous memory. This code is an evolution of the Android ION implementation, so thanks to its original authors and maintainters: Rebecca Schultz Zavin, Colin Cross, Laura Abbott, and others! Cc: Laura Abbott Cc: Benjamin Gaignard Cc: Greg KH Cc: Sumit Semwal Cc: Liam Mark Cc: Brian Starkey Cc: Andrew F. Davis Cc: Chenbo Feng Cc: Alistair Strachan Cc: dri-devel@lists.freedesktop.org Signed-off-by: John Stultz --- v2: * Switch allocate to return dmabuf fd * Simplify init code * Checkpatch fixups * Droped dead system-contig code --- drivers/dma-buf/Kconfig | 2 + drivers/dma-buf/heaps/Kconfig | 6 ++ drivers/dma-buf/heaps/Makefile | 1 + drivers/dma-buf/heaps/system_heap.c | 132 ++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 drivers/dma-buf/heaps/Kconfig create mode 100644 drivers/dma-buf/heaps/system_heap.c diff --git a/drivers/dma-buf/Kconfig b/drivers/dma-buf/Kconfig index 09c61db..63c139d 100644 --- a/drivers/dma-buf/Kconfig +++ b/drivers/dma-buf/Kconfig @@ -47,4 +47,6 @@ menuconfig DMABUF_HEAPS this allows userspace to allocate dma-bufs that can be shared between drivers. +source "drivers/dma-buf/heaps/Kconfig" + endmenu diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig new file mode 100644 index 0000000..2050527 --- /dev/null +++ b/drivers/dma-buf/heaps/Kconfig @@ -0,0 +1,6 @@ +config DMABUF_HEAPS_SYSTEM + bool "DMA-BUF System Heap" + depends on DMABUF_HEAPS + help + Choose this option to enable the system dmabuf heap. The system heap + is backed by pages from the buddy allocator. If in doubt, say Y. diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile index de49898..d1808ec 100644 --- a/drivers/dma-buf/heaps/Makefile +++ b/drivers/dma-buf/heaps/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 obj-y += heap-helpers.o +obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c new file mode 100644 index 0000000..e001661 --- /dev/null +++ b/drivers/dma-buf/heaps/system_heap.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DMABUF System heap exporter + * + * Copyright (C) 2011 Google, Inc. + * Copyright (C) 2019 Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "heap-helpers.h" + + +struct system_heap { + struct dma_heap heap; +}; + + +static void system_heap_free(struct heap_helper_buffer *buffer) +{ + int i; + struct scatterlist *sg; + struct sg_table *table = buffer->sg_table; + + for_each_sg(table->sgl, sg, table->nents, i) + __free_page(sg_page(sg)); + + sg_free_table(table); + kfree(table); + kfree(buffer); +} + +static int system_heap_allocate(struct dma_heap *heap, + unsigned long len, + unsigned long flags) +{ + struct heap_helper_buffer *helper_buffer; + struct sg_table *table; + struct scatterlist *sg; + int i, j; + int npages = PAGE_ALIGN(len) / PAGE_SIZE; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct dma_buf *dmabuf; + int ret = -ENOMEM; + + helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL); + if (!helper_buffer) + return -ENOMEM; + + INIT_HEAP_HELPER_BUFFER(helper_buffer, system_heap_free); + helper_buffer->heap_buffer.flags = flags; + helper_buffer->heap_buffer.heap = heap; + helper_buffer->heap_buffer.size = len; + + table = kmalloc(sizeof(struct sg_table), GFP_KERNEL); + if (!table) + goto err0; + + i = sg_alloc_table(table, npages, GFP_KERNEL); + if (i) + goto err1; + for_each_sg(table->sgl, sg, table->nents, i) { + struct page *page; + + page = alloc_page(GFP_KERNEL); + if (!page) + goto err2; + sg_set_page(sg, page, PAGE_SIZE, 0); + } + + /* create the dmabuf */ + exp_info.ops = &heap_helper_ops; + exp_info.size = len; + exp_info.flags = O_RDWR; + exp_info.priv = &helper_buffer->heap_buffer; + dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(dmabuf)) { + ret = PTR_ERR(dmabuf); + goto err2; + } + + helper_buffer->heap_buffer.dmabuf = dmabuf; + helper_buffer->sg_table = table; + + ret = dma_buf_fd(dmabuf, O_CLOEXEC); + if (ret < 0) { + dma_buf_put(dmabuf); + /* just return, as put will call release and that will free */ + return ret; + } + + return ret; + +err2: + for_each_sg(table->sgl, sg, i, j) + __free_page(sg_page(sg)); + sg_free_table(table); +err1: + kfree(table); +err0: + kfree(helper_buffer); + return -ENOMEM; +} + + +static struct dma_heap_ops system_heap_ops = { + .allocate = system_heap_allocate, +}; + +static int system_heap_create(void) +{ + struct system_heap *sys_heap; + + sys_heap = kzalloc(sizeof(*sys_heap), GFP_KERNEL); + if (!sys_heap) + return -ENOMEM; + sys_heap->heap.name = "system_heap"; + sys_heap->heap.ops = &system_heap_ops; + + dma_heap_add(&sys_heap->heap); + + return 0; +} +device_initcall(system_heap_create); From patchwork Tue Mar 5 20:54:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 10840121 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6730214DE for ; Tue, 5 Mar 2019 20:54:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5534C2CDE6 for ; Tue, 5 Mar 2019 20:54:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 48DFC2CECD; Tue, 5 Mar 2019 20:54:59 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 E17432CDE6 for ; Tue, 5 Mar 2019 20:54:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 3BA256E013; Tue, 5 Mar 2019 20:54:52 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pf1-x441.google.com (mail-pf1-x441.google.com [IPv6:2607:f8b0:4864:20::441]) by gabe.freedesktop.org (Postfix) with ESMTPS id AB9BA6E013 for ; Tue, 5 Mar 2019 20:54:48 +0000 (UTC) Received: by mail-pf1-x441.google.com with SMTP id n22so6621198pfa.3 for ; Tue, 05 Mar 2019 12:54:48 -0800 (PST) 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=zjNdJq9UTy396FItVuuFMC2moUGC3uBW2PZHwqhq9dk=; b=VRnzlQR8cnQdYYp70t69KuWrO4wZbs/FkHSCLGeA/Yy3pgYWfH61YKbh0tCgJoGMBD JJBmhYCTByG5muTTNKKEgrBLIu57/ukRN33vviJ9d/v1CDKm9MOxJMhjFOFfkJNnc619 2L2+oQtf306YWjUMG4PbQiuAd/3M8CBY4r0Rc6Ic52yfvgHgeNp//uNyeB0Lvn/UXvPt NfxkTTOK3RnpaI0aC+CWRn8+7rl9Q/kndf+pTwrsnwyJsyQJ6FytXFWf8KFLeS2cIjwE 8zS1/ozMfUfyp/gwVSVUeS8iH6feOBTA0FNX1uvAgGh4U3tb+w/Jer2F7iUFqptw1QIr RD/Q== X-Gm-Message-State: APjAAAXc9rezCm0K8XuU9EjXznbL+HaY8reN4edp5eOTLiDE1cLxXXjQ 1zdJxjFGGApodXpXeAsSZDIF1A== X-Google-Smtp-Source: APXvYqyCoIwrVw6dklhSs10riFYQ7lAejNtK1w2JcI8ZHD/fdINxXX4t16AcR3LX1QOc3azbJVEYYQ== X-Received: by 2002:a17:902:7613:: with SMTP id k19mr3118077pll.207.1551819288135; Tue, 05 Mar 2019 12:54:48 -0800 (PST) Received: from localhost.localdomain ([2601:1c2:680:1319:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id i4sm13411788pfo.158.2019.03.05.12.54.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Mar 2019 12:54:46 -0800 (PST) From: John Stultz To: lkml Subject: [RFC][PATCH 4/5 v2] dma-buf: heaps: Add CMA heap to dmabuf heapss Date: Tue, 5 Mar 2019 12:54:32 -0800 Message-Id: <1551819273-640-5-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1551819273-640-1-git-send-email-john.stultz@linaro.org> References: <1551819273-640-1-git-send-email-john.stultz@linaro.org> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=zjNdJq9UTy396FItVuuFMC2moUGC3uBW2PZHwqhq9dk=; b=JGXEitfWTC2Fx8f/vKAaxDImoKOjNAKc/WUp8LWBS8yzzGJu6Hvqz1ohHTFYRbieZ4 m68weAQQgYdRN2VJoAVodZOyQ5W1bcx6E4gncHyE7EtAcTHSFcDNeP2TxXWxGJZNC/ZH s36M3ziKhwOLNaNCW4TShZcu3qAs48TnDwwHwwAleoNlBnf5rzLayRZjf+oQ/IpuTMrL R0o8zQbdqfUPrZoZ+y1JdeO9oh754Zp3ozNzlhFhjZf8hRb+K6wT7ySImkuG6cdVybf9 wvTBnyAqTwihnTN+4qu0rV7YolTCP/cnBUXDWpjcLX37Vvfb0dDrzLN1L3QN2/+KJgCX alJg== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg KH , Chenbo Feng , Alistair Strachan , Liam Mark , dri-devel@lists.freedesktop.org, "Andrew F . Davis" MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This adds a CMA heap, which allows userspace to allocate a dma-buf of contiguous memory out of a CMA region. This code is an evolution of the Android ION implementation, so thanks to its original author and maintainters: Benjamin Gaignard, Laura Abbott, and others! Cc: Laura Abbott Cc: Benjamin Gaignard Cc: Greg KH Cc: Sumit Semwal Cc: Liam Mark Cc: Brian Starkey Cc: Andrew F. Davis Cc: Chenbo Feng Cc: Alistair Strachan Cc: dri-devel@lists.freedesktop.org Signed-off-by: John Stultz Reviewed-by: Benjamin Gaignard --- v2: * Switch allocate to return dmabuf fd * Simplify init code * Checkpatch fixups --- drivers/dma-buf/heaps/Kconfig | 8 ++ drivers/dma-buf/heaps/Makefile | 1 + drivers/dma-buf/heaps/cma_heap.c | 164 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 drivers/dma-buf/heaps/cma_heap.c diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig index 2050527..a5eef06 100644 --- a/drivers/dma-buf/heaps/Kconfig +++ b/drivers/dma-buf/heaps/Kconfig @@ -4,3 +4,11 @@ config DMABUF_HEAPS_SYSTEM help Choose this option to enable the system dmabuf heap. The system heap is backed by pages from the buddy allocator. If in doubt, say Y. + +config DMABUF_HEAPS_CMA + bool "DMA-BUF CMA Heap" + depends on DMABUF_HEAPS && DMA_CMA + help + Choose this option to enable dma-buf CMA heap. This heap is backed + by the Contiguous Memory Allocator (CMA). If your system has these + regions, you should say Y here. diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile index d1808ec..6e54cde 100644 --- a/drivers/dma-buf/heaps/Makefile +++ b/drivers/dma-buf/heaps/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 obj-y += heap-helpers.o obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o +obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c new file mode 100644 index 0000000..33c18ec --- /dev/null +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DMABUF CMA heap exporter + * + * Copyright (C) 2012, 2019 Linaro Ltd. + * Author: for ST-Ericsson. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "heap-helpers.h" + +struct cma_heap { + struct dma_heap heap; + struct cma *cma; +}; + + +#define to_cma_heap(x) container_of(x, struct cma_heap, heap) + + +static void cma_heap_free(struct heap_helper_buffer *buffer) +{ + struct cma_heap *cma_heap = to_cma_heap(buffer->heap_buffer.heap); + struct page *pages = buffer->priv_virt; + unsigned long nr_pages; + + nr_pages = PAGE_ALIGN(buffer->heap_buffer.size) >> PAGE_SHIFT; + + /* release memory */ + cma_release(cma_heap->cma, pages, nr_pages); + /* release sg table */ + sg_free_table(buffer->sg_table); + kfree(buffer->sg_table); + kfree(buffer); +} + +/* dmabuf heap CMA operations functions */ +static int cma_heap_allocate(struct dma_heap *heap, + unsigned long len, + unsigned long flags) +{ + struct cma_heap *cma_heap = to_cma_heap(heap); + struct heap_helper_buffer *helper_buffer; + struct sg_table *table; + struct page *pages; + size_t size = PAGE_ALIGN(len); + unsigned long nr_pages = size >> PAGE_SHIFT; + unsigned long align = get_order(size); + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct dma_buf *dmabuf; + int ret = -ENOMEM; + + if (align > CONFIG_CMA_ALIGNMENT) + align = CONFIG_CMA_ALIGNMENT; + + helper_buffer = kzalloc(sizeof(*helper_buffer), GFP_KERNEL); + if (!helper_buffer) + return -ENOMEM; + + INIT_HEAP_HELPER_BUFFER(helper_buffer, cma_heap_free); + helper_buffer->heap_buffer.flags = flags; + helper_buffer->heap_buffer.heap = heap; + helper_buffer->heap_buffer.size = len; + + + pages = cma_alloc(cma_heap->cma, nr_pages, align, false); + if (!pages) + goto free_buf; + + if (PageHighMem(pages)) { + unsigned long nr_clear_pages = nr_pages; + struct page *page = pages; + + while (nr_clear_pages > 0) { + void *vaddr = kmap_atomic(page); + + memset(vaddr, 0, PAGE_SIZE); + kunmap_atomic(vaddr); + page++; + nr_clear_pages--; + } + } else { + memset(page_address(pages), 0, size); + } + + table = kmalloc(sizeof(*table), GFP_KERNEL); + if (!table) + goto free_cma; + + ret = sg_alloc_table(table, 1, GFP_KERNEL); + if (ret) + goto free_table; + + sg_set_page(table->sgl, pages, size, 0); + + /* create the dmabuf */ + exp_info.ops = &heap_helper_ops; + exp_info.size = len; + exp_info.flags = O_RDWR; + exp_info.priv = &helper_buffer->heap_buffer; + dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(dmabuf)) { + ret = PTR_ERR(dmabuf); + goto free_table; + } + + helper_buffer->heap_buffer.dmabuf = dmabuf; + helper_buffer->priv_virt = pages; + helper_buffer->sg_table = table; + + ret = dma_buf_fd(dmabuf, O_CLOEXEC); + if (ret < 0) { + dma_buf_put(dmabuf); + /* just return, as put will call release and that will free */ + return ret; + } + + return ret; +free_table: + kfree(table); +free_cma: + cma_release(cma_heap->cma, pages, nr_pages); +free_buf: + kfree(helper_buffer); + return ret; +} + +static struct dma_heap_ops cma_heap_ops = { + .allocate = cma_heap_allocate, +}; + +static int __add_cma_heaps(struct cma *cma, void *data) +{ + struct cma_heap *cma_heap; + + cma_heap = kzalloc(sizeof(*cma_heap), GFP_KERNEL); + + if (!cma_heap) + return -ENOMEM; + + cma_heap->heap.name = cma_get_name(cma); + cma_heap->heap.ops = &cma_heap_ops; + cma_heap->cma = cma; + + dma_heap_add(&cma_heap->heap); + + return 0; +} + +static int add_cma_heaps(void) +{ + cma_for_each_area(__add_cma_heaps, NULL); + return 0; +} +device_initcall(add_cma_heaps); From patchwork Tue Mar 5 20:54:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 10840119 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D64E117E0 for ; Tue, 5 Mar 2019 20:54:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C48AF2CDE6 for ; Tue, 5 Mar 2019 20:54:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B88972CECD; Tue, 5 Mar 2019 20:54:56 +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=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED 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 4D9B42CDE6 for ; Tue, 5 Mar 2019 20:54:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E1B4A89DE5; Tue, 5 Mar 2019 20:54:51 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8FEF789DE5 for ; Tue, 5 Mar 2019 20:54:50 +0000 (UTC) Received: by mail-pf1-x443.google.com with SMTP id i19so6623781pfd.0 for ; Tue, 05 Mar 2019 12:54:50 -0800 (PST) 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=yRzxxqyWBOZSHUPCrEH0/twSX4oAAXNjDpDvvJwFuKY=; b=Dv8VcA8XXxxx96WPoGcLlOg//a+7/2BZlbhjcLO98tHAtAD9ET9UGA1+M/Q2nelNaY 5c9m+A+RHRuGfwZT0WP2SP6OfyN76h77Lhzl0dhG7JP54o0Q3GnmSuNdEGzgBEHSd2eP 7ArQ5N+MsxXS+4v0hlbkq/yNvZ0sm8cv9kxtFd2whxJzxsM27bJhPc0KPQv29uvx7p5S enxVo51czuMmBwyXz5Y8CgmFsQrryd3lsADSj+ZcZvJOuBseKjDI9iXWP2z1rCRURKTB YtYjClXKlc1WehcOfPl7mdnTVARlIDf7SAOx5uUb8igHMQJyWpn8zzqLfnSjte6LYpHu rdeQ== X-Gm-Message-State: APjAAAWsglNXVdBub/nKuJhniNnMKDp/ivROaX5h0KYLpcCfwyw8OKMB O4a6M3OEoVcRzvHWHLcLa1OF+g== X-Google-Smtp-Source: APXvYqxF7ykA/kf99QruolBopZYp5p4PGISA/FBp9efQscn5LVLJvQ9HEnAdWkYDlooRd84lKgzCzQ== X-Received: by 2002:a63:7444:: with SMTP id e4mr3119864pgn.398.1551819289844; Tue, 05 Mar 2019 12:54:49 -0800 (PST) Received: from localhost.localdomain ([2601:1c2:680:1319:4e72:b9ff:fe99:466a]) by smtp.gmail.com with ESMTPSA id i4sm13411788pfo.158.2019.03.05.12.54.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 05 Mar 2019 12:54:48 -0800 (PST) From: John Stultz To: lkml Subject: [RFC][PATCH 5/5 v2] kselftests: Add dma-heap test Date: Tue, 5 Mar 2019 12:54:33 -0800 Message-Id: <1551819273-640-6-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1551819273-640-1-git-send-email-john.stultz@linaro.org> References: <1551819273-640-1-git-send-email-john.stultz@linaro.org> X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yRzxxqyWBOZSHUPCrEH0/twSX4oAAXNjDpDvvJwFuKY=; b=Ig9NrpoLNuMDfa1+uWlGupfOqBCwIQ+ARCCn0xpftFCT3CL10AADvXWK6+JhSnvz4W p3k6GJJ2Z1mlHzqRsm5OHk/PK4cC6Dk23pAfM300lbS6bVkUcxds/Pspgzvci2Si0/bJ y2o8svN7nDilfgoFvx4QdJvS7od2QiEIx6knwSOtqD18tZf3je3SQirbipJ1VicIE/YN 5YqWpTO+nOXUaf8LIxcqMDMEnEXrvTQue+vlk1lS0l+KCI+3g8eR/oiEmcNmeTkHFKAJ kM3pIRH9pB6Zwzc6w2xAocRDCHT/LJ7HDwAS7pjS4XowquDPevvezNeVxmLOQSos47n3 OjqQ== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg KH , Chenbo Feng , Alistair Strachan , Liam Mark , dri-devel@lists.freedesktop.org, "Andrew F . Davis" MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add very trivial allocation test for dma-heaps. TODO: Need to actually do some validation on the returned dma-buf. Cc: Laura Abbott Cc: Benjamin Gaignard Cc: Greg KH Cc: Sumit Semwal Cc: Liam Mark Cc: Brian Starkey Cc: Andrew F. Davis Cc: Chenbo Feng Cc: Alistair Strachan Cc: dri-devel@lists.freedesktop.org Signed-off-by: John Stultz --- v2: Switched to use reworked dma-heap apis --- tools/testing/selftests/dmabuf-heaps/Makefile | 11 +++ tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c | 96 ++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 tools/testing/selftests/dmabuf-heaps/Makefile create mode 100644 tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c diff --git a/tools/testing/selftests/dmabuf-heaps/Makefile b/tools/testing/selftests/dmabuf-heaps/Makefile new file mode 100644 index 0000000..c414ad3 --- /dev/null +++ b/tools/testing/selftests/dmabuf-heaps/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0 +CFLAGS += -static -O3 -Wl,-no-as-needed -Wall +#LDLIBS += -lrt -lpthread -lm + +# these are all "safe" tests that don't modify +# system time or require escalated privileges +TEST_GEN_PROGS = dmabuf-heap + + +include ../lib.mk + diff --git a/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c b/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c new file mode 100644 index 0000000..06837a4 --- /dev/null +++ b/tools/testing/selftests/dmabuf-heaps/dmabuf-heap.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../../../include/uapi/linux/dma-heap.h" + +#define DEVPATH "/dev/dma_heap" + +int dmabuf_heap_open(char *name) +{ + int ret, fd; + char buf[256]; + + ret = sprintf(buf, "%s/%s", DEVPATH, name); + if (ret < 0) { + printf("sprintf failed!\n"); + return ret; + } + + fd = open(buf, O_RDWR); + if (fd < 0) + printf("open %s failed!\n", buf); + return fd; +} + +int dmabuf_heap_alloc(int fd, size_t len, unsigned int flags, int *dmabuf_fd) +{ + struct dma_heap_allocation_data data = { + .len = len, + .flags = flags, + }; + int ret; + + if (dmabuf_fd == NULL) + return -EINVAL; + + ret = ioctl(fd, DMA_HEAP_IOC_ALLOC, &data); + if (ret < 0) + return ret; + *dmabuf_fd = (int)data.fd; + return ret; +} + +#define ONE_MEG (1024*1024) + +void do_test(char *heap_name) +{ + int heap_fd = -1, dmabuf_fd = -1; + int ret; + + printf("Testing heap: %s\n", heap_name); + + heap_fd = dmabuf_heap_open(heap_name); + if (heap_fd < 0) + return; + + printf("Allocating 1 MEG\n"); + ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0, &dmabuf_fd); + if (ret) + goto out; + + /* DO SOMETHING WITH THE DMABUF HERE? */ + +out: + if (dmabuf_fd >= 0) + close(dmabuf_fd); + if (heap_fd >= 0) + close(heap_fd); +} + + +int main(void) +{ + DIR *d; + struct dirent *dir; + + d = opendir(DEVPATH); + if (!d) { + printf("No %s directory?\n", DEVPATH); + return -1; + } + + while ((dir = readdir(d)) != NULL) + do_test(dir->d_name); + + + return 0; +}