From patchwork Fri Dec 7 16:35:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 153174 Delivered-To: patch@linaro.org Received: by 2002:a2e:299d:0:0:0:0:0 with SMTP id p29-v6csp703800ljp; Fri, 7 Dec 2018 08:35:40 -0800 (PST) X-Google-Smtp-Source: AFSGD/V+JgK/19ofMhTnT1pC2saOrqy3h06gs78PxSgaQgHkUvkHy0lVsbQKSgybIcN+FWBEjWFf X-Received: by 2002:a63:9a52:: with SMTP id e18mr2577990pgo.14.1544200539969; Fri, 07 Dec 2018 08:35:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544200539; cv=none; d=google.com; s=arc-20160816; b=rqjyaOiEgO6pVL7uwxkN1J6fNJ8cttFFhSwsVDH3MQIlcmuyjRF4VRdgWRTFCtbiC/ qdN6RrPezcQe/vJa1zayfL2wl3r3TyfoX9cb57atYkz1QnuFlVk5Y27gppNoOveSrU5Y lEs872V3feVyGylJJIsukdNlEEfIXAfwQC61OocmL6auAh7zGslPjBQrCgbKIxmsRCrR ttkT9Zeo9fvSNlmm9juT1844cRCjl4MODkFbUfOe48YMApMZVFgfxBuNf0RElPnFjk9L bnKXo8oK2dDwsxAaTKWOSdxkEKFuvxVBavlfVs88VztubLUI0XcWv/eiTXZWGpgpClAL Tf4Q== 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=vxbksEXKP3Ej1UNk0V3R+rU4dtyAkyM+QR7pndLVKTc=; b=VfjxH0pesLpsz3MUOFzC2VfnWjbqwEKGFlPT62vAhNYcLL2YTSbuT5t/bJ3vK5bOIL zNGqEH4e2v6LasliH8ec1/LUiURuaRS7wO6aJWVZ97uyK0fra36wj0g78yM0NEB6YNi5 tWZ1Kxu46z5oSJDMF8BYi46wc184g4oEq3SBt+ikVwdLKbVX5x0/H5NC1LT/i4RzNOsZ NUoAAlFygedY92Cj3+KTQapSzSLmTBytY4Fh0ana1yMI9dax5DnkMqP4RD7W05kTFuVZ w525ov1fGc6BUlghGxcoPGE6fUbN+z6dFOAAS472iS8NkW/+WhlElMtB2AiP3rFyVV7A ptHg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aXDIswSj; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-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 s59si3289345plb.237.2018.12.07.08.35.30; Fri, 07 Dec 2018 08:35:39 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-arm-msm-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=aXDIswSj; spf=pass (google.com: best guess record for domain of linux-arm-msm-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-arm-msm-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 S1726258AbeLGQf1 (ORCPT + 15 others); Fri, 7 Dec 2018 11:35:27 -0500 Received: from mail-wr1-f66.google.com ([209.85.221.66]:38376 "EHLO mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726230AbeLGQf1 (ORCPT ); Fri, 7 Dec 2018 11:35:27 -0500 Received: by mail-wr1-f66.google.com with SMTP id v13so4390453wrw.5 for ; Fri, 07 Dec 2018 08:35:24 -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=vxbksEXKP3Ej1UNk0V3R+rU4dtyAkyM+QR7pndLVKTc=; b=aXDIswSj1s6iktiX/M0NpgWNkaDnKnuukvaIcrWH/Ay6U3QYfp6sXJ/8NhkkkdtV+q Jy8xLLmF9xMc2IQgv7ft21BnxRkOSh6JdVijAghNl8XlubyC5ehPtxkNDx6NxRaJQ/DU cTq428w7AbhzKrUYxlQoYdRGwvkascWgsgY8k= 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=vxbksEXKP3Ej1UNk0V3R+rU4dtyAkyM+QR7pndLVKTc=; b=TM6ImiQcCMVEMbegcEvFsgYHCVQnz+Znml3/vI87PRrwO06vFFM2PLjpzZY3izNfLM bsgLa/hKuEM/qlDGlCMCaaS9JnCPEuosCV1EvI+H8f21r0LP2vmNrod3+DdlrUsmJmjJ wnSa4Iob7uWFt9nhOO6yVUmb44qQyy/LzLRZbafP7wqjZi3oMd5p9wlZravcoG8F7Td4 K/oRVo/XAJqnDEjueIWT+mHQzKttt+u2V4lMRLs8g5nbmRx3tFmj5bH2XXghpk+qxSUU yfFqdDHWos2Uv33cOzM7KAKMxAZmjnh66V7AKFF7JfdbD2rULTT7UWGv2+viYT8q9JXd KQ2A== X-Gm-Message-State: AA+aEWb8FgW+NCRJNHxxvSseTx8mXvFZ23TscZGLyRK5wSLD3yBKO5og dL91cLBXYo8FYKb2p74oeRgfcSwKnHs= X-Received: by 2002:a5d:448f:: with SMTP id j15mr2278632wrq.108.1544200523555; Fri, 07 Dec 2018 08:35:23 -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 w6sm4268752wme.46.2018.12.07.08.35.22 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 07 Dec 2018 08:35:23 -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, linux-arm-msm@vger.kernel.org, bkumar@qti.qualcomm.com, thierry.escande@linaro.org, Srinivas Kandagatla Subject: [PATCH v2 5/6] misc: fastrpc: Add support for dmabuf exporter Date: Fri, 7 Dec 2018 16:35:12 +0000 Message-Id: <20181207163513.16412-6-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181207163513.16412-1-srinivas.kandagatla@linaro.org> References: <20181207163513.16412-1-srinivas.kandagatla@linaro.org> MIME-Version: 1.0 Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@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 | 176 ++++++++++++++++++++++++++++++++++++ include/uapi/misc/fastrpc.h | 8 ++ 2 files changed, 184 insertions(+) -- 2.19.2 diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index fda674e9efe2..5ea2bba1e4bd 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; uint64_t phys; size_t 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 { @@ -249,6 +259,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; @@ -357,6 +370,110 @@ fastrpc_context_alloc(struct fastrpc_user *user, uint32_t kernel, return ERR_PTR(err); } +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, size_t len, struct fastrpc_map **ppmap) { @@ -876,6 +993,59 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) return 0; } +static long fastrpc_dmabuf_free(struct fastrpc_user *fl, char __user *argp) +{ + struct dma_buf *buf; + uint32_t 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 long 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; + + err = copy_from_user(&bp, argp, sizeof(bp)); + if (err) + return err; + + 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)) { + err = PTR_ERR(buf->dmabuf); + return err; + } + + 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; + } + + return copy_to_user(argp, &bp, sizeof(bp)); +} + static long fastrpc_init_attach(struct fastrpc_user *fl) { struct fastrpc_invoke_args args[1]; @@ -939,6 +1109,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 2f0afa5dab1f..e2eeec1f78d3 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) @@ -31,4 +33,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__ */