Message ID | 20221121214722.22563-4-umang.jain@ideasonboard.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp1852067wrr; Mon, 21 Nov 2022 13:50:18 -0800 (PST) X-Google-Smtp-Source: AA0mqf6hdVZFCSTJ+A5pDTuUtaKFhTSY8Ed7vHjzgRwrUp0UU9tu7Z5VgO2Z4E62vmsLma7dPxCt X-Received: by 2002:a17:90a:5801:b0:218:90b5:d1f2 with SMTP id h1-20020a17090a580100b0021890b5d1f2mr14949637pji.142.1669067417972; Mon, 21 Nov 2022 13:50:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669067417; cv=none; d=google.com; s=arc-20160816; b=QQYVXo7VqVhMyOzctJATb5bJC7H8Z5473kgGq+OGNICae8Cxr+iLO2dyT0c5Ncl4MA 80Apbme6M7LoDOtMo8yngkORNFiC6xOyTZgb02qCS2q5VYS2UCwSKybHEjnjsDz3RKFG /6cMGUaEh5JgNz+Cjnp09zU2/bZ6Rt1x/FlVOJps/m0Z6Wxnu0GDU8eeKhp8JwGHwkrR aM9Oibp7w9s4l6KRANCpxdUhMEO2DGOFX07FWKVvuRHLGhtA7wBhFmExDu9UfhX4e6n7 YF7hHaxwBzZK7VbcZSlX+0lNh96u4JEHgT8JEsynzeDkMt4tKaZQyt+r5GWW1sGtEIDr itxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ojvTe7uert5vZVokXoRyrNML4qa4S/G8hFPdnfpUFmY=; b=Ghq9c9W3n/I/KBlFg7LEXJfFDx85HsBlv7t2yI37CAKK7jYUr8Oc5A/p4JMkbd8BvT QDIFb+ChwX1v4kG3HP2Bn3tlcnEdEQngnudJQfPuiuB+BdB9Kl19Z3ZiDLM3Oqqa9zht uSNbtQDTcdr/WwedRlq4BScA5+gUXSuC4iE9nJ62H9qZj2XfPRLRlblAT78NaqoKkzTo /GpFWOLOyd0z6XXaKd0dFJzQt9716ctu3jrA6ZLtY9dOsCnyrCnuTn+mqgXL25bXAh34 gTxz72EauDQQ2Ugkhly5yKewAEPTEkbfrkk7QK662POmURIsegI8OR7R9QOduLQFRP7t IhNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b=HfqXFbKy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c7-20020a170903234700b001869b2c5f47si13592502plh.326.2022.11.21.13.50.03; Mon, 21 Nov 2022 13:50:17 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass (test mode) header.i=@ideasonboard.com header.s=mail header.b=HfqXFbKy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231879AbiKUVtE (ORCPT <rfc822;cjcooper78@gmail.com> + 99 others); Mon, 21 Nov 2022 16:49:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38536 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231783AbiKUVso (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 21 Nov 2022 16:48:44 -0500 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF051DA4C9; Mon, 21 Nov 2022 13:48:43 -0800 (PST) Received: from umang.jainideasonboard.com (unknown [103.86.18.138]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id A85AA74C; Mon, 21 Nov 2022 22:48:37 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1669067322; bh=FGKK8yxgi6riQck1s3OLo5W9TvjD+Dvhy1KA8E89qTw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HfqXFbKyPqTpzY5W7VDklPpxp/mUXZq85+S0rriagiOoC5epR7Q8PjClgyF80zQSs O688I5+NxUzRqS647gMNKcDXFky8oMZZxQTb7Z/U5F1A+51UFsYD/tzIfNKDqbPa6V s/MF2Hy0crBcDJhgCBG3elM4DWAideLr21gnnYAc= From: Umang Jain <umang.jain@ideasonboard.com> To: linux-media@vger.kernel.org, kernel-list@raspberrypi.com, linux-kernel@vger.kernel.org, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-staging@lists.linux.dev, Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com> Cc: Dave Stevenson <dave.stevenson@raspberrypi.com>, Florian Fainelli <f.fainelli@gmail.com>, Naushir Patuck <naush@raspberrypi.com>, David Plowman <david.plowman@raspberrypi.com>, Kieran Bingham <kieran.bingham@ideasonboard.com>, Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Dave Stevenson <dave.stevenson@raspberrypi.org>, Umang Jain <umang.jain@ideasonboard.com> Subject: [PATCH 03/14] media: videobuf2: Allow exporting of a struct dmabuf Date: Tue, 22 Nov 2022 03:17:11 +0530 Message-Id: <20221121214722.22563-4-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221121214722.22563-1-umang.jain@ideasonboard.com> References: <20221121214722.22563-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1750144036850014506?= X-GMAIL-MSGID: =?utf-8?q?1750144036850014506?= |
Series |
staging: vc04_services: bcm2835-isp support
|
|
Commit Message
Umang Jain
Nov. 21, 2022, 9:47 p.m. UTC
From: Dave Stevenson <dave.stevenson@raspberrypi.org> videobuf2 only allowed exporting a dmabuf as a file descriptor, but there are instances where having the struct dma_buf is useful within the kernel. Split the current implementation into two, one step which exports a struct dma_buf, and the second which converts that into an fd. Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> Signed-off-by: Umang Jain <umang.jain@ideasonboard.com> --- .../media/common/videobuf2/videobuf2-core.c | 36 +++++++++++++------ include/media/videobuf2-core.h | 15 ++++++++ 2 files changed, 40 insertions(+), 11 deletions(-)
Comments
Hi Umang and Dave, Thank you for the patch. On Tue, Nov 22, 2022 at 03:17:11AM +0530, Umang Jain wrote: > From: Dave Stevenson <dave.stevenson@raspberrypi.org> > > videobuf2 only allowed exporting a dmabuf as a file descriptor, > but there are instances where having the struct dma_buf is > useful within the kernel. > > Split the current implementation into two, one step which > exports a struct dma_buf, and the second which converts that > into an fd. > > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> > Signed-off-by: Umang Jain <umang.jain@ideasonboard.com> > --- > .../media/common/videobuf2/videobuf2-core.c | 36 +++++++++++++------ > include/media/videobuf2-core.h | 15 ++++++++ > 2 files changed, 40 insertions(+), 11 deletions(-) > > diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c > index ab9697f3b5f1..32b26737cac4 100644 > --- a/drivers/media/common/videobuf2/videobuf2-core.c > +++ b/drivers/media/common/videobuf2/videobuf2-core.c > @@ -2184,49 +2184,49 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, > return -EINVAL; > } > > -int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, > - unsigned int index, unsigned int plane, unsigned int flags) > +struct dma_buf *vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, > + unsigned int index, unsigned int plane, > + unsigned int flags) This function is used in the ISP driver, in bcm2835_isp_buf_prepare(), for MMAP buffers, and as far as I can tell, its only purpose is to create a dma_buf instance to then be imported in vchiq_mmal_submit_buffer() with a call to vc_sm_cma_import_dmabuf(). That sounds like a very complicated set of operations, and quite inefficient :-( > { > struct vb2_buffer *vb = NULL; > struct vb2_plane *vb_plane; > - int ret; > struct dma_buf *dbuf; > > if (q->memory != VB2_MEMORY_MMAP) { > dprintk(q, 1, "queue is not currently set up for mmap\n"); > - return -EINVAL; > + return ERR_PTR(-EINVAL); > } > > if (!q->mem_ops->get_dmabuf) { > dprintk(q, 1, "queue does not support DMA buffer exporting\n"); > - return -EINVAL; > + return ERR_PTR(-EINVAL); > } > > if (flags & ~(O_CLOEXEC | O_ACCMODE)) { > dprintk(q, 1, "queue does support only O_CLOEXEC and access mode flags\n"); > - return -EINVAL; > + return ERR_PTR(-EINVAL); > } > > if (type != q->type) { > dprintk(q, 1, "invalid buffer type\n"); > - return -EINVAL; > + return ERR_PTR(-EINVAL); > } > > if (index >= q->num_buffers) { > dprintk(q, 1, "buffer index out of range\n"); > - return -EINVAL; > + return ERR_PTR(-EINVAL); > } > > vb = q->bufs[index]; > > if (plane >= vb->num_planes) { > dprintk(q, 1, "buffer plane out of range\n"); > - return -EINVAL; > + return ERR_PTR(-EINVAL); > } > > if (vb2_fileio_is_active(q)) { > dprintk(q, 1, "expbuf: file io in progress\n"); > - return -EBUSY; > + return ERR_PTR(-EBUSY); > } > > vb_plane = &vb->planes[plane]; > @@ -2238,9 +2238,23 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, > if (IS_ERR_OR_NULL(dbuf)) { > dprintk(q, 1, "failed to export buffer %d, plane %d\n", > index, plane); > - return -EINVAL; > + return ERR_PTR(-EINVAL); > } > > + return dbuf; > +} > +EXPORT_SYMBOL_GPL(vb2_core_expbuf_dmabuf); > + > +int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, > + unsigned int index, unsigned int plane, unsigned int flags) > +{ > + struct dma_buf *dbuf; > + int ret; > + > + dbuf = vb2_core_expbuf_dmabuf(q, type, index, plane, flags); > + if (IS_ERR(dbuf)) > + return PTR_ERR(dbuf); > + > ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE); > if (ret < 0) { > dprintk(q, 3, "buffer %d, plane %d failed to export (%d)\n", > diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h > index 3253bd2f6fee..33629ed2b64f 100644 > --- a/include/media/videobuf2-core.h > +++ b/include/media/videobuf2-core.h > @@ -911,6 +911,21 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type); > */ > int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); > > +/** > + * vb2_core_expbuf_dmabuf() - Export a buffer as a dma_buf structure > + * @q: videobuf2 queue > + * @type: buffer type > + * @index: id number of the buffer > + * @plane: index of the plane to be exported, 0 for single plane queues > + * @flags: flags for newly created file, currently only O_CLOEXEC is > + * supported, refer to manual of open syscall for more details > + * > + * Return: Returns the dmabuf pointer > + */ > +struct dma_buf *vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, > + unsigned int index, unsigned int plane, > + unsigned int flags); > + > /** > * vb2_core_expbuf() - Export a buffer as a file descriptor. > * @q: pointer to &struct vb2_queue with videobuf2 queue.
On Mon, 21 Nov 2022 at 23:18, Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote: > > Hi Umang and Dave, > > Thank you for the patch. > > On Tue, Nov 22, 2022 at 03:17:11AM +0530, Umang Jain wrote: > > From: Dave Stevenson <dave.stevenson@raspberrypi.org> > > > > videobuf2 only allowed exporting a dmabuf as a file descriptor, > > but there are instances where having the struct dma_buf is > > useful within the kernel. > > > > Split the current implementation into two, one step which > > exports a struct dma_buf, and the second which converts that > > into an fd. > > > > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> > > Signed-off-by: Umang Jain <umang.jain@ideasonboard.com> > > --- > > .../media/common/videobuf2/videobuf2-core.c | 36 +++++++++++++------ > > include/media/videobuf2-core.h | 15 ++++++++ > > 2 files changed, 40 insertions(+), 11 deletions(-) > > > > diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c > > index ab9697f3b5f1..32b26737cac4 100644 > > --- a/drivers/media/common/videobuf2/videobuf2-core.c > > +++ b/drivers/media/common/videobuf2/videobuf2-core.c > > @@ -2184,49 +2184,49 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, > > return -EINVAL; > > } > > > > -int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, > > - unsigned int index, unsigned int plane, unsigned int flags) > > +struct dma_buf *vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, > > + unsigned int index, unsigned int plane, > > + unsigned int flags) > > This function is used in the ISP driver, in bcm2835_isp_buf_prepare(), > for MMAP buffers, and as far as I can tell, its only purpose is to > create a dma_buf instance to then be imported in > vchiq_mmal_submit_buffer() with a call to vc_sm_cma_import_dmabuf(). > That sounds like a very complicated set of operations, and quite > inefficient :-( Are you saying that dmabufs are not the preferred route for sharing buffers between kernel subsystems? What are you suggesting instead? If the VPU (firmware) has a handle to the buffer then we need to manage the lifetime such that it is not freed until the VPU has released it. That is handled for you with dmabufs, therefore why reinvent the wheel? Dave > > { > > struct vb2_buffer *vb = NULL; > > struct vb2_plane *vb_plane; > > - int ret; > > struct dma_buf *dbuf; > > > > if (q->memory != VB2_MEMORY_MMAP) { > > dprintk(q, 1, "queue is not currently set up for mmap\n"); > > - return -EINVAL; > > + return ERR_PTR(-EINVAL); > > } > > > > if (!q->mem_ops->get_dmabuf) { > > dprintk(q, 1, "queue does not support DMA buffer exporting\n"); > > - return -EINVAL; > > + return ERR_PTR(-EINVAL); > > } > > > > if (flags & ~(O_CLOEXEC | O_ACCMODE)) { > > dprintk(q, 1, "queue does support only O_CLOEXEC and access mode flags\n"); > > - return -EINVAL; > > + return ERR_PTR(-EINVAL); > > } > > > > if (type != q->type) { > > dprintk(q, 1, "invalid buffer type\n"); > > - return -EINVAL; > > + return ERR_PTR(-EINVAL); > > } > > > > if (index >= q->num_buffers) { > > dprintk(q, 1, "buffer index out of range\n"); > > - return -EINVAL; > > + return ERR_PTR(-EINVAL); > > } > > > > vb = q->bufs[index]; > > > > if (plane >= vb->num_planes) { > > dprintk(q, 1, "buffer plane out of range\n"); > > - return -EINVAL; > > + return ERR_PTR(-EINVAL); > > } > > > > if (vb2_fileio_is_active(q)) { > > dprintk(q, 1, "expbuf: file io in progress\n"); > > - return -EBUSY; > > + return ERR_PTR(-EBUSY); > > } > > > > vb_plane = &vb->planes[plane]; > > @@ -2238,9 +2238,23 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, > > if (IS_ERR_OR_NULL(dbuf)) { > > dprintk(q, 1, "failed to export buffer %d, plane %d\n", > > index, plane); > > - return -EINVAL; > > + return ERR_PTR(-EINVAL); > > } > > > > + return dbuf; > > +} > > +EXPORT_SYMBOL_GPL(vb2_core_expbuf_dmabuf); > > + > > +int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, > > + unsigned int index, unsigned int plane, unsigned int flags) > > +{ > > + struct dma_buf *dbuf; > > + int ret; > > + > > + dbuf = vb2_core_expbuf_dmabuf(q, type, index, plane, flags); > > + if (IS_ERR(dbuf)) > > + return PTR_ERR(dbuf); > > + > > ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE); > > if (ret < 0) { > > dprintk(q, 3, "buffer %d, plane %d failed to export (%d)\n", > > diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h > > index 3253bd2f6fee..33629ed2b64f 100644 > > --- a/include/media/videobuf2-core.h > > +++ b/include/media/videobuf2-core.h > > @@ -911,6 +911,21 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type); > > */ > > int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); > > > > +/** > > + * vb2_core_expbuf_dmabuf() - Export a buffer as a dma_buf structure > > + * @q: videobuf2 queue > > + * @type: buffer type > > + * @index: id number of the buffer > > + * @plane: index of the plane to be exported, 0 for single plane queues > > + * @flags: flags for newly created file, currently only O_CLOEXEC is > > + * supported, refer to manual of open syscall for more details > > + * > > + * Return: Returns the dmabuf pointer > > + */ > > +struct dma_buf *vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, > > + unsigned int index, unsigned int plane, > > + unsigned int flags); > > + > > /** > > * vb2_core_expbuf() - Export a buffer as a file descriptor. > > * @q: pointer to &struct vb2_queue with videobuf2 queue. > > -- > Regards, > > Laurent Pinchart
Hi Dave, On Tue, Nov 22, 2022 at 11:35:31AM +0000, Dave Stevenson wrote: > On Mon, 21 Nov 2022 at 23:18, Laurent Pinchart wrote: > > On Tue, Nov 22, 2022 at 03:17:11AM +0530, Umang Jain wrote: > > > From: Dave Stevenson <dave.stevenson@raspberrypi.org> > > > > > > videobuf2 only allowed exporting a dmabuf as a file descriptor, > > > but there are instances where having the struct dma_buf is > > > useful within the kernel. > > > > > > Split the current implementation into two, one step which > > > exports a struct dma_buf, and the second which converts that > > > into an fd. > > > > > > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org> > > > Signed-off-by: Umang Jain <umang.jain@ideasonboard.com> > > > --- > > > .../media/common/videobuf2/videobuf2-core.c | 36 +++++++++++++------ > > > include/media/videobuf2-core.h | 15 ++++++++ > > > 2 files changed, 40 insertions(+), 11 deletions(-) > > > > > > diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c > > > index ab9697f3b5f1..32b26737cac4 100644 > > > --- a/drivers/media/common/videobuf2/videobuf2-core.c > > > +++ b/drivers/media/common/videobuf2/videobuf2-core.c > > > @@ -2184,49 +2184,49 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, > > > return -EINVAL; > > > } > > > > > > -int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, > > > - unsigned int index, unsigned int plane, unsigned int flags) > > > +struct dma_buf *vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, > > > + unsigned int index, unsigned int plane, > > > + unsigned int flags) > > > > This function is used in the ISP driver, in bcm2835_isp_buf_prepare(), > > for MMAP buffers, and as far as I can tell, its only purpose is to > > create a dma_buf instance to then be imported in > > vchiq_mmal_submit_buffer() with a call to vc_sm_cma_import_dmabuf(). > > That sounds like a very complicated set of operations, and quite > > inefficient :-( > > Are you saying that dmabufs are not the preferred route for sharing > buffers between kernel subsystems? What are you suggesting instead? > > If the VPU (firmware) has a handle to the buffer then we need to > manage the lifetime such that it is not freed until the VPU has > released it. That is handled for you with dmabufs, therefore why > reinvent the wheel? When we go through userspace, dmabuf is certainly the way to go. Here, we need to share buffer information between two drivers that are specific to the platform, so we could avoid going through so many layers by using a custom abstraction. However, that would require additional development, and probably reinventing the wheel to some extent, so it's probably not worth it. I'd like to explore if we could avoid creating a second dmabuf in vc_sm_cma_import_dmabuf_internal() to make all this a bit more lightweight. Let's discuss it in replies to patch 01/14. > > > { > > > struct vb2_buffer *vb = NULL; > > > struct vb2_plane *vb_plane; > > > - int ret; > > > struct dma_buf *dbuf; > > > > > > if (q->memory != VB2_MEMORY_MMAP) { > > > dprintk(q, 1, "queue is not currently set up for mmap\n"); > > > - return -EINVAL; > > > + return ERR_PTR(-EINVAL); > > > } > > > > > > if (!q->mem_ops->get_dmabuf) { > > > dprintk(q, 1, "queue does not support DMA buffer exporting\n"); > > > - return -EINVAL; > > > + return ERR_PTR(-EINVAL); > > > } > > > > > > if (flags & ~(O_CLOEXEC | O_ACCMODE)) { > > > dprintk(q, 1, "queue does support only O_CLOEXEC and access mode flags\n"); > > > - return -EINVAL; > > > + return ERR_PTR(-EINVAL); > > > } > > > > > > if (type != q->type) { > > > dprintk(q, 1, "invalid buffer type\n"); > > > - return -EINVAL; > > > + return ERR_PTR(-EINVAL); > > > } > > > > > > if (index >= q->num_buffers) { > > > dprintk(q, 1, "buffer index out of range\n"); > > > - return -EINVAL; > > > + return ERR_PTR(-EINVAL); > > > } > > > > > > vb = q->bufs[index]; > > > > > > if (plane >= vb->num_planes) { > > > dprintk(q, 1, "buffer plane out of range\n"); > > > - return -EINVAL; > > > + return ERR_PTR(-EINVAL); > > > } > > > > > > if (vb2_fileio_is_active(q)) { > > > dprintk(q, 1, "expbuf: file io in progress\n"); > > > - return -EBUSY; > > > + return ERR_PTR(-EBUSY); > > > } > > > > > > vb_plane = &vb->planes[plane]; > > > @@ -2238,9 +2238,23 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, > > > if (IS_ERR_OR_NULL(dbuf)) { > > > dprintk(q, 1, "failed to export buffer %d, plane %d\n", > > > index, plane); > > > - return -EINVAL; > > > + return ERR_PTR(-EINVAL); > > > } > > > > > > + return dbuf; > > > +} > > > +EXPORT_SYMBOL_GPL(vb2_core_expbuf_dmabuf); > > > + > > > +int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, > > > + unsigned int index, unsigned int plane, unsigned int flags) > > > +{ > > > + struct dma_buf *dbuf; > > > + int ret; > > > + > > > + dbuf = vb2_core_expbuf_dmabuf(q, type, index, plane, flags); > > > + if (IS_ERR(dbuf)) > > > + return PTR_ERR(dbuf); > > > + > > > ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE); > > > if (ret < 0) { > > > dprintk(q, 3, "buffer %d, plane %d failed to export (%d)\n", > > > diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h > > > index 3253bd2f6fee..33629ed2b64f 100644 > > > --- a/include/media/videobuf2-core.h > > > +++ b/include/media/videobuf2-core.h > > > @@ -911,6 +911,21 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type); > > > */ > > > int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); > > > > > > +/** > > > + * vb2_core_expbuf_dmabuf() - Export a buffer as a dma_buf structure > > > + * @q: videobuf2 queue > > > + * @type: buffer type > > > + * @index: id number of the buffer > > > + * @plane: index of the plane to be exported, 0 for single plane queues > > > + * @flags: flags for newly created file, currently only O_CLOEXEC is > > > + * supported, refer to manual of open syscall for more details > > > + * > > > + * Return: Returns the dmabuf pointer > > > + */ > > > +struct dma_buf *vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, > > > + unsigned int index, unsigned int plane, > > > + unsigned int flags); > > > + > > > /** > > > * vb2_core_expbuf() - Export a buffer as a file descriptor. > > > * @q: pointer to &struct vb2_queue with videobuf2 queue.
diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index ab9697f3b5f1..32b26737cac4 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -2184,49 +2184,49 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, return -EINVAL; } -int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, - unsigned int index, unsigned int plane, unsigned int flags) +struct dma_buf *vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, + unsigned int index, unsigned int plane, + unsigned int flags) { struct vb2_buffer *vb = NULL; struct vb2_plane *vb_plane; - int ret; struct dma_buf *dbuf; if (q->memory != VB2_MEMORY_MMAP) { dprintk(q, 1, "queue is not currently set up for mmap\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } if (!q->mem_ops->get_dmabuf) { dprintk(q, 1, "queue does not support DMA buffer exporting\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } if (flags & ~(O_CLOEXEC | O_ACCMODE)) { dprintk(q, 1, "queue does support only O_CLOEXEC and access mode flags\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } if (type != q->type) { dprintk(q, 1, "invalid buffer type\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } if (index >= q->num_buffers) { dprintk(q, 1, "buffer index out of range\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } vb = q->bufs[index]; if (plane >= vb->num_planes) { dprintk(q, 1, "buffer plane out of range\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } if (vb2_fileio_is_active(q)) { dprintk(q, 1, "expbuf: file io in progress\n"); - return -EBUSY; + return ERR_PTR(-EBUSY); } vb_plane = &vb->planes[plane]; @@ -2238,9 +2238,23 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, if (IS_ERR_OR_NULL(dbuf)) { dprintk(q, 1, "failed to export buffer %d, plane %d\n", index, plane); - return -EINVAL; + return ERR_PTR(-EINVAL); } + return dbuf; +} +EXPORT_SYMBOL_GPL(vb2_core_expbuf_dmabuf); + +int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, + unsigned int index, unsigned int plane, unsigned int flags) +{ + struct dma_buf *dbuf; + int ret; + + dbuf = vb2_core_expbuf_dmabuf(q, type, index, plane, flags); + if (IS_ERR(dbuf)) + return PTR_ERR(dbuf); + ret = dma_buf_fd(dbuf, flags & ~O_ACCMODE); if (ret < 0) { dprintk(q, 3, "buffer %d, plane %d failed to export (%d)\n", diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 3253bd2f6fee..33629ed2b64f 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -911,6 +911,21 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type); */ int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); +/** + * vb2_core_expbuf_dmabuf() - Export a buffer as a dma_buf structure + * @q: videobuf2 queue + * @type: buffer type + * @index: id number of the buffer + * @plane: index of the plane to be exported, 0 for single plane queues + * @flags: flags for newly created file, currently only O_CLOEXEC is + * supported, refer to manual of open syscall for more details + * + * Return: Returns the dmabuf pointer + */ +struct dma_buf *vb2_core_expbuf_dmabuf(struct vb2_queue *q, unsigned int type, + unsigned int index, unsigned int plane, + unsigned int flags); + /** * vb2_core_expbuf() - Export a buffer as a file descriptor. * @q: pointer to &struct vb2_queue with videobuf2 queue.