From patchwork Thu Jan 24 15:24:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 156481 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp2087506jaa; Thu, 24 Jan 2019 07:26:04 -0800 (PST) X-Google-Smtp-Source: ALg8bN7x8jr2Xs5LV8P6YgXjYvBEVXLIrGblSgbv5dRGJPQTxqLoX2wYWrpn5WRoFmVQub2QtEZb X-Received: by 2002:a63:c848:: with SMTP id l8mr6253805pgi.78.1548343564538; Thu, 24 Jan 2019 07:26:04 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548343564; cv=none; d=google.com; s=arc-20160816; b=wvpeTL5VidL5OZnbhW2NOA2ozNzatq6Gcj5zV3uFKjJU0OSzT2q/9dg7jfN0OJyrpX +FRJfZd3I6zjfmvl0G2h6Td4PssqkMHJ5VVcKw9u47ceaLPAhc9P7y3FPhMWzkfsXqcM 5OBEBtUuwP1e9S2azRAetxwr4fyDo0KMHDc6mrZkt5JrWm676l65pTSg6eOr1MZxc7YY ccCqEge0jR337bq3LNXB8335UVYkIAfMtp7Tpmj5Hvh+dB8HtpI1JoHKgnRYvsQ8spp5 b3TYPeQ8WAAo9SVKmRrROJ0fuMXZhrHUq0E2AH05Y2tkqopaE7dd4m3i9tKpprFbN98Z 1Y9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=bQ8pes4GHsiZiw2vkcdeL7hOjU0R14hDMazyZN4Ugo0=; b=zmYM6sIXNRSbujqbBOTaoDTi/SvevWH5CJhiTMzc+/woqdmThZKhu6GcfHj1+mYVGe id3UdTsHQPCQXR9y6pCIosXpdwxEslutCDdpD6BPPG9ReC8Isc+vadKckZvI16oYz9AY w78/fmqI5OM3o549jdYLLqOvbDNG0SFuMUo10cLqpoJPuTjarOQBcAe+u46Bdx52dMev Ej1nltb8Q26xReVB+J1oE9+3NqEkENz0G1fYAEIHvpIVsDnWrAvfTa/lvBMkImUhWg6h JWRgXrfGrAjhnvx2jCYs1mlB3F18DNCP120nryJ+nFKXbmWHQvMKn7JcDYCqGfjnZtYQ +pQw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=TFT0BDiR; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k11si23406780pgg.430.2019.01.24.07.26.04; Thu, 24 Jan 2019 07:26:04 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=TFT0BDiR; spf=pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728681AbfAXPZ4 (ORCPT + 7 others); Thu, 24 Jan 2019 10:25:56 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:44696 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728654AbfAXPZ4 (ORCPT ); Thu, 24 Jan 2019 10:25:56 -0500 Received: by mail-wr1-f68.google.com with SMTP id z5so6886798wrt.11 for ; Thu, 24 Jan 2019 07:25:55 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=bQ8pes4GHsiZiw2vkcdeL7hOjU0R14hDMazyZN4Ugo0=; b=TFT0BDiRPa78ZhWtS1dr0Jl1dbtXqHiVtMu6Lcz1K1SrEgTl1PMraFr+GsQn//6MNx EBKUOsZUmAK+tNy21KrMJPEee0o2GcHoI6qf8KIWov0KDSRnmXpenUGf5bfIooD9lnTW 7Oi7RjJTod85JqKFedwyp8fGVZbNfpGrdeNRw= 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:mime-version:content-transfer-encoding; bh=bQ8pes4GHsiZiw2vkcdeL7hOjU0R14hDMazyZN4Ugo0=; b=BhfFRVEIpNaYyGNvc7NBtNr9Vd290ribGUNW1umAUVhoNcuB/GS1lPA6kI8tDf3Zaq ldzjcqHGf2FuQpcUJBBw+M46jYmUjk32gM6Qpj8wOLG/ZZaieFHXcBDOpSz97e2rsjLW 4a0MgHGz1gwDjKXG6u6am5KA3W+UbAaJv8hwMRyRzLsCi/0XdZZ8YtoXTE9LOaBPle+a EiZPf56Ff9oYTTDeX9oBK29oiH52Z6HrfPQM4zfLvvRKnnvLBFLDtfAKAFI5lOvJ7SuI ncVIHyKAF8VPrGCOAEHLVZmO8Q1GluN3pCJDXKH+ZG/UhHhe4zOEoL0weYh3V7N4hIuw pn/A== X-Gm-Message-State: AJcUukeflAlmxWi9GJZi1cHKkKhs3UeB5zjbHRf/DiB6pYkenap/342s z65ADhByASA7XKMiD5f2mj0DGQ== X-Received: by 2002:adf:e9d1:: with SMTP id l17mr7187069wrn.73.1548343554339; Thu, 24 Jan 2019 07:25:54 -0800 (PST) Received: from srini-hackbox.lan (cpc89974-aztw32-2-0-cust43.18-1.cable.virginm.net. [86.30.250.44]) by smtp.gmail.com with ESMTPSA id z12sm80371157wrh.35.2019.01.24.07.25.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 24 Jan 2019 07:25:53 -0800 (PST) From: Srinivas Kandagatla To: robh+dt@kernel.org, gregkh@linuxfoundation.org, arnd@arndb.de Cc: mark.rutland@arm.com, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, bjorn.andersson@linaro.org, bkumar@qti.qualcomm.com, linux-arm-msm@vger.kernel.org, thierry.escande@linaro.org, Srinivas Kandagatla Subject: [PATCH v4 5/5] misc: fastrpc: Add support for dmabuf exporter Date: Thu, 24 Jan 2019 15:24:12 +0000 Message-Id: <20190124152412.10503-6-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190124152412.10503-1-srinivas.kandagatla@linaro.org> References: <20190124152412.10503-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org User process can involve dealing with big buffer sizes, and also passing buffers from one compute context bank to other compute context bank for complex dsp algorithms. This patch adds support to fastrpc to make it a proper dmabuf exporter to avoid making copies of buffers. Co-developed-by: Thierry Escande Signed-off-by: Thierry Escande Signed-off-by: Srinivas Kandagatla --- drivers/misc/fastrpc.c | 179 ++++++++++++++++++++++++++++++++++++ include/uapi/misc/fastrpc.h | 8 ++ 2 files changed, 187 insertions(+) -- 2.20.1 diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index b9972f1be9f4..77700ebf87c7 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -106,10 +106,20 @@ struct fastrpc_invoke_rsp { struct fastrpc_buf { struct fastrpc_user *fl; + struct dma_buf *dmabuf; struct device *dev; void *virt; u64 phys; u64 size; + /* Lock for dma buf attachments */ + struct mutex lock; + struct list_head attachments; +}; + +struct fastrpc_dma_buf_attachment { + struct device *dev; + struct sg_table sgt; + struct list_head node; }; struct fastrpc_map { @@ -246,6 +256,9 @@ static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, if (!buf) return -ENOMEM; + INIT_LIST_HEAD(&buf->attachments); + mutex_init(&buf->lock); + buf->fl = fl; buf->virt = NULL; buf->phys = 0; @@ -351,6 +364,110 @@ fastrpc_context_alloc(struct fastrpc_user *user, u32 kernel, u32 sc, return ERR_PTR(ret); } +static struct sg_table * +fastrpc_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction dir) +{ + struct fastrpc_dma_buf_attachment *a = attachment->priv; + struct sg_table *table; + + table = &a->sgt; + + if (!dma_map_sg(attachment->dev, table->sgl, table->nents, dir)) + return ERR_PTR(-ENOMEM); + + return table; +} + +static void fastrpc_unmap_dma_buf(struct dma_buf_attachment *attach, + struct sg_table *table, + enum dma_data_direction dir) +{ +} + +static void fastrpc_release(struct dma_buf *dmabuf) +{ + struct fastrpc_buf *buffer = dmabuf->priv; + + fastrpc_buf_free(buffer); +} + +static int fastrpc_dma_buf_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct fastrpc_dma_buf_attachment *a; + struct fastrpc_buf *buffer = dmabuf->priv; + int ret; + + a = kzalloc(sizeof(*a), GFP_KERNEL); + if (!a) + return -ENOMEM; + + ret = dma_get_sgtable(buffer->dev, &a->sgt, buffer->virt, + FASTRPC_PHYS(buffer->phys), buffer->size); + if (ret < 0) { + dev_err(buffer->dev, "failed to get scatterlist from DMA API\n"); + return -EINVAL; + } + + a->dev = attachment->dev; + INIT_LIST_HEAD(&a->node); + attachment->priv = a; + + mutex_lock(&buffer->lock); + list_add(&a->node, &buffer->attachments); + mutex_unlock(&buffer->lock); + + return 0; +} + +static void fastrpc_dma_buf_detatch(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct fastrpc_dma_buf_attachment *a = attachment->priv; + struct fastrpc_buf *buffer = dmabuf->priv; + + mutex_lock(&buffer->lock); + list_del(&a->node); + mutex_unlock(&buffer->lock); + kfree(a); +} + +static void *fastrpc_kmap(struct dma_buf *dmabuf, unsigned long pgnum) +{ + struct fastrpc_buf *buf = dmabuf->priv; + + return buf->virt ? buf->virt + pgnum * PAGE_SIZE : NULL; +} + +static void *fastrpc_vmap(struct dma_buf *dmabuf) +{ + struct fastrpc_buf *buf = dmabuf->priv; + + return buf->virt; +} + +static int fastrpc_mmap(struct dma_buf *dmabuf, + struct vm_area_struct *vma) +{ + struct fastrpc_buf *buf = dmabuf->priv; + size_t size = vma->vm_end - vma->vm_start; + + return dma_mmap_coherent(buf->dev, vma, buf->virt, + FASTRPC_PHYS(buf->phys), size); +} + +static const struct dma_buf_ops fastrpc_dma_buf_ops = { + .attach = fastrpc_dma_buf_attach, + .detach = fastrpc_dma_buf_detatch, + .map_dma_buf = fastrpc_map_dma_buf, + .unmap_dma_buf = fastrpc_unmap_dma_buf, + .mmap = fastrpc_mmap, + .map = fastrpc_kmap, + .vmap = fastrpc_vmap, + .release = fastrpc_release, +}; + static int fastrpc_map_create(struct fastrpc_user *fl, int fd, u64 len, struct fastrpc_map **ppmap) { @@ -869,6 +986,62 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) return 0; } +static int fastrpc_dmabuf_free(struct fastrpc_user *fl, char __user *argp) +{ + struct dma_buf *buf; + int info; + + if (copy_from_user(&info, argp, sizeof(info))) + return -EFAULT; + + buf = dma_buf_get(info); + if (IS_ERR_OR_NULL(buf)) + return -EINVAL; + /* + * one for the last get and other for the ALLOC_DMA_BUFF ioctl + */ + dma_buf_put(buf); + dma_buf_put(buf); + + return 0; +} + +static int fastrpc_dmabuf_alloc(struct fastrpc_user *fl, char __user *argp) +{ + struct fastrpc_alloc_dma_buf bp; + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct fastrpc_buf *buf = NULL; + int err; + + if (copy_from_user(&bp, argp, sizeof(bp))) + return -EFAULT; + + err = fastrpc_buf_alloc(fl, fl->sctx->dev, bp.size, &buf); + if (err) + return err; + exp_info.ops = &fastrpc_dma_buf_ops; + exp_info.size = bp.size; + exp_info.flags = O_RDWR; + exp_info.priv = buf; + buf->dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(buf->dmabuf)) + return PTR_ERR(buf->dmabuf); + + get_dma_buf(buf->dmabuf); + bp.fd = dma_buf_fd(buf->dmabuf, O_ACCMODE); + if (bp.fd < 0) { + dma_buf_put(buf->dmabuf); + return -EINVAL; + } + + if (copy_to_user(argp, &bp, sizeof(bp))) { + dma_buf_put(buf->dmabuf); + return -EFAULT; + } + + return 0; +} + static int fastrpc_init_attach(struct fastrpc_user *fl) { struct fastrpc_invoke_args args[1]; @@ -931,6 +1104,12 @@ static long fastrpc_device_ioctl(struct file *file, unsigned int cmd, case FASTRPC_IOCTL_INIT_CREATE: err = fastrpc_init_create_process(fl, argp); break; + case FASTRPC_IOCTL_FREE_DMA_BUFF: + err = fastrpc_dmabuf_free(fl, argp); + break; + case FASTRPC_IOCTL_ALLOC_DMA_BUFF: + err = fastrpc_dmabuf_alloc(fl, argp); + break; default: err = -ENOTTY; dev_err(fl->sctx->dev, "bad ioctl: %d\n", cmd); diff --git a/include/uapi/misc/fastrpc.h b/include/uapi/misc/fastrpc.h index 32d191c3b7bc..6d701af9fc42 100644 --- a/include/uapi/misc/fastrpc.h +++ b/include/uapi/misc/fastrpc.h @@ -5,6 +5,8 @@ #include +#define FASTRPC_IOCTL_ALLOC_DMA_BUFF _IOWR('R', 1, struct fastrpc_alloc_dma_buf) +#define FASTRPC_IOCTL_FREE_DMA_BUFF _IOWR('R', 2, __u32) #define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_invoke) #define FASTRPC_IOCTL_INIT_ATTACH _IO('R', 4) #define FASTRPC_IOCTL_INIT_CREATE _IOWR('R', 5, struct fastrpc_init_create) @@ -30,4 +32,10 @@ struct fastrpc_init_create { __u64 file; /* pointer to elf file */ }; +struct fastrpc_alloc_dma_buf { + __s32 fd; /* fd */ + __u32 flags; /* flags to map with */ + __u64 size; /* size */ +}; + #endif /* __QCOM_FASTRPC_H__ */