From patchwork Thu Sep 9 11:24:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 12482935 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C882BC433EF for ; Thu, 9 Sep 2021 11:24:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AED8F61100 for ; Thu, 9 Sep 2021 11:24:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235455AbhIILZv (ORCPT ); Thu, 9 Sep 2021 07:25:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235422AbhIILZu (ORCPT ); Thu, 9 Sep 2021 07:25:50 -0400 Received: from mail-pg1-x534.google.com (mail-pg1-x534.google.com [IPv6:2607:f8b0:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 622A9C061756 for ; Thu, 9 Sep 2021 04:24:41 -0700 (PDT) Received: by mail-pg1-x534.google.com with SMTP id e7so1453213pgk.2 for ; Thu, 09 Sep 2021 04:24:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ixZhHKTV6J4XQCZXvrGZk4OcWHR+nnVHvsuotJkWtqQ=; b=fcahkJY7/ofP00yMuxn75m+FGNVw7KR5cEs1cqMJBYGVHF00v98Ui0vhr6EnkXqhof D0UOV4oyK7mSyiGmpR14EQ29gZ8dbV4tcqMoPhChaFylt/RE0FGI8nLKUOjoCceibKdB mdknLsevCcVQ+E9gtBv68lYo8yYQqwXVE2ZT4= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ixZhHKTV6J4XQCZXvrGZk4OcWHR+nnVHvsuotJkWtqQ=; b=eVYdi32H8nOdIuQMp+N53fSPQbKCk3waxXGPXsaYLptAYq+DIROFCKb6Bkw/FCgsua yR1jmqvvQH792K4NtVTa5BnAlL1sHXQwrxbk20ceGxKyfXqTEuOIRsp8WWk+72ahhIK/ IvgHRlxJCgoCL53ToRF3iKzDbtiove96ANfpejGGO6YqK9QAkN3+bX4cH1kq8YRW1Y1h 9mHNlzbnGdj6q9IaYv/Ym2q+Hhm3xgSCm3oZI7JvJQAS2IF5uy1NZEiaztI2cTiRZdzF FndWjzLiq8V81S3NcgXsRGARkxCl7hYyXYUmEkvpS7lnIRLvlCvwjy/sSgxuwt2NRomm KVuQ== X-Gm-Message-State: AOAM533zK62jqRvRTFRIGlqatAyhLvcAbX8AnfYGggLcP1ju6y3XK3w1 tLhfAQ+YGBTBZLMZHwObYVSVSA== X-Google-Smtp-Source: ABdhPJw9V7/8f5zpeA0wUrvPQdo78JZvPpCj+gtkLtBjFzbHdSzIj23AYhJ5n2BCB2EIBiJhguVHRw== X-Received: by 2002:a63:551a:: with SMTP id j26mr2269125pgb.142.1631186680829; Thu, 09 Sep 2021 04:24:40 -0700 (PDT) Received: from senozhatsky.flets-east.jp ([2409:10:2e40:5100:166b:dcfc:dcf2:bbe2]) by smtp.gmail.com with ESMTPSA id 141sm2046860pgg.16.2021.09.09.04.24.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 04:24:40 -0700 (PDT) From: Sergey Senozhatsky To: Tomasz Figa , Hans Verkuil Cc: Marek Szyprowski , Dafna Hirschfeld , Ricardo Ribalda , Christoph Hellwig , Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Senozhatsky Subject: [PATCHv6 1/8] videobuf2: rework vb2_mem_ops API Date: Thu, 9 Sep 2021 20:24:23 +0900 Message-Id: <20210909112430.61243-2-senozhatsky@chromium.org> X-Mailer: git-send-email 2.33.0.153.gba50c8fa24-goog In-Reply-To: <20210909112430.61243-1-senozhatsky@chromium.org> References: <20210909112430.61243-1-senozhatsky@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org With the new DMA API we need an extension of the videobuf2 API. Previously, videobuf2 core would set the non-coherent DMA bit in the vb2_queue dma_attr field (if user-space would pass a corresponding memory hint); the vb2 core then would pass the vb2_queue dma_attrs to the vb2 allocators. The vb2 allocator would use the queue's dma_attr and the DMA API would allocate either coherent or non-coherent memory. But we cannot do this anymore, since there is no corresponding DMA attr flag and, hence, there is no way for the allocator to become aware of what type of allocation user-space has requested. So we need to pass more context from videobuf2 core to the allocators. Fix this by changing the call_ptr_memop() macro to pass the vb2 pointer to the corresponding op callbacks. Signed-off-by: Sergey Senozhatsky --- .../media/common/videobuf2/videobuf2-core.c | 42 +++++++++++-------- .../common/videobuf2/videobuf2-dma-contig.c | 36 +++++++++------- .../media/common/videobuf2/videobuf2-dma-sg.c | 33 ++++++++------- .../common/videobuf2/videobuf2-vmalloc.c | 30 ++++++------- include/media/videobuf2-core.h | 37 ++++++++-------- 5 files changed, 98 insertions(+), 80 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 38ce7c274727..c4ff356da600 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -68,13 +68,13 @@ module_param(debug, int, 0644); err; \ }) -#define call_ptr_memop(vb, op, args...) \ +#define call_ptr_memop(op, vb, args...) \ ({ \ struct vb2_queue *_q = (vb)->vb2_queue; \ void *ptr; \ \ log_memop(vb, op); \ - ptr = _q->mem_ops->op ? _q->mem_ops->op(args) : NULL; \ + ptr = _q->mem_ops->op ? _q->mem_ops->op(vb, args) : NULL; \ if (!IS_ERR_OR_NULL(ptr)) \ (vb)->cnt_mem_ ## op++; \ ptr; \ @@ -144,9 +144,9 @@ module_param(debug, int, 0644); ((vb)->vb2_queue->mem_ops->op ? \ (vb)->vb2_queue->mem_ops->op(args) : 0) -#define call_ptr_memop(vb, op, args...) \ +#define call_ptr_memop(op, vb, args...) \ ((vb)->vb2_queue->mem_ops->op ? \ - (vb)->vb2_queue->mem_ops->op(args) : NULL) + (vb)->vb2_queue->mem_ops->op(vb, args) : NULL) #define call_void_memop(vb, op, args...) \ do { \ @@ -230,9 +230,10 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) if (size < vb->planes[plane].length) goto free; - mem_priv = call_ptr_memop(vb, alloc, - q->alloc_devs[plane] ? : q->dev, - q->dma_attrs, size, q->dma_dir, q->gfp_flags); + mem_priv = call_ptr_memop(alloc, + vb, + q->alloc_devs[plane] ? : q->dev, + size); if (IS_ERR_OR_NULL(mem_priv)) { if (mem_priv) ret = PTR_ERR(mem_priv); @@ -975,7 +976,7 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no) if (plane_no >= vb->num_planes || !vb->planes[plane_no].mem_priv) return NULL; - return call_ptr_memop(vb, vaddr, vb->planes[plane_no].mem_priv); + return call_ptr_memop(vaddr, vb, vb->planes[plane_no].mem_priv); } EXPORT_SYMBOL_GPL(vb2_plane_vaddr); @@ -985,7 +986,7 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no) if (plane_no >= vb->num_planes || !vb->planes[plane_no].mem_priv) return NULL; - return call_ptr_memop(vb, cookie, vb->planes[plane_no].mem_priv); + return call_ptr_memop(cookie, vb, vb->planes[plane_no].mem_priv); } EXPORT_SYMBOL_GPL(vb2_plane_cookie); @@ -1125,10 +1126,11 @@ static int __prepare_userptr(struct vb2_buffer *vb) vb->planes[plane].data_offset = 0; /* Acquire each plane's memory */ - mem_priv = call_ptr_memop(vb, get_userptr, - q->alloc_devs[plane] ? : q->dev, - planes[plane].m.userptr, - planes[plane].length, q->dma_dir); + mem_priv = call_ptr_memop(get_userptr, + vb, + q->alloc_devs[plane] ? : q->dev, + planes[plane].m.userptr, + planes[plane].length); if (IS_ERR(mem_priv)) { dprintk(q, 1, "failed acquiring userspace memory for plane %d\n", plane); @@ -1249,9 +1251,11 @@ static int __prepare_dmabuf(struct vb2_buffer *vb) vb->planes[plane].data_offset = 0; /* Acquire each plane's memory */ - mem_priv = call_ptr_memop(vb, attach_dmabuf, - q->alloc_devs[plane] ? : q->dev, - dbuf, planes[plane].length, q->dma_dir); + mem_priv = call_ptr_memop(attach_dmabuf, + vb, + q->alloc_devs[plane] ? : q->dev, + dbuf, + planes[plane].length); if (IS_ERR(mem_priv)) { dprintk(q, 1, "failed to attach dmabuf\n"); ret = PTR_ERR(mem_priv); @@ -2197,8 +2201,10 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, vb_plane = &vb->planes[plane]; - dbuf = call_ptr_memop(vb, get_dmabuf, vb_plane->mem_priv, - flags & O_ACCMODE); + dbuf = call_ptr_memop(get_dmabuf, + vb, + vb_plane->mem_priv, + flags & O_ACCMODE); if (IS_ERR_OR_NULL(dbuf)) { dprintk(q, 1, "failed to export buffer %d, plane %d\n", index, plane); diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index a7f61ba85440..019c3843dc6d 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -40,6 +40,8 @@ struct vb2_dc_buf { /* DMABUF related */ struct dma_buf_attachment *db_attach; + + struct vb2_buffer *vb; }; /*********************************************/ @@ -66,14 +68,14 @@ static unsigned long vb2_dc_get_contiguous_size(struct sg_table *sgt) /* callbacks for all buffers */ /*********************************************/ -static void *vb2_dc_cookie(void *buf_priv) +static void *vb2_dc_cookie(struct vb2_buffer *vb, void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; return &buf->dma_addr; } -static void *vb2_dc_vaddr(void *buf_priv) +static void *vb2_dc_vaddr(struct vb2_buffer *vb, void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; struct dma_buf_map map; @@ -137,9 +139,9 @@ static void vb2_dc_put(void *buf_priv) kfree(buf); } -static void *vb2_dc_alloc(struct device *dev, unsigned long attrs, - unsigned long size, enum dma_data_direction dma_dir, - gfp_t gfp_flags) +static void *vb2_dc_alloc(struct vb2_buffer *vb, + struct device *dev, + unsigned long size) { struct vb2_dc_buf *buf; @@ -150,9 +152,10 @@ static void *vb2_dc_alloc(struct device *dev, unsigned long attrs, if (!buf) return ERR_PTR(-ENOMEM); - buf->attrs = attrs; + buf->attrs = vb->vb2_queue->dma_attrs; buf->cookie = dma_alloc_attrs(dev, size, &buf->dma_addr, - GFP_KERNEL | gfp_flags, buf->attrs); + GFP_KERNEL | vb->vb2_queue->gfp_flags, + buf->attrs); if (!buf->cookie) { dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); kfree(buf); @@ -165,11 +168,12 @@ static void *vb2_dc_alloc(struct device *dev, unsigned long attrs, /* Prevent the device from being released while the buffer is used */ buf->dev = get_device(dev); buf->size = size; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dc_put; buf->handler.arg = buf; + buf->vb = vb; refcount_set(&buf->refcount, 1); @@ -397,7 +401,9 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf) return sgt; } -static struct dma_buf *vb2_dc_get_dmabuf(void *buf_priv, unsigned long flags) +static struct dma_buf *vb2_dc_get_dmabuf(struct vb2_buffer *vb, + void *buf_priv, + unsigned long flags) { struct vb2_dc_buf *buf = buf_priv; struct dma_buf *dbuf; @@ -459,8 +465,8 @@ static void vb2_dc_put_userptr(void *buf_priv) kfree(buf); } -static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, - unsigned long size, enum dma_data_direction dma_dir) +static void *vb2_dc_get_userptr(struct vb2_buffer *vb, struct device *dev, + unsigned long vaddr, unsigned long size) { struct vb2_dc_buf *buf; struct frame_vector *vec; @@ -490,7 +496,7 @@ static void *vb2_dc_get_userptr(struct device *dev, unsigned long vaddr, return ERR_PTR(-ENOMEM); buf->dev = dev; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; offset = lower_32_bits(offset_in_page(vaddr)); vec = vb2_create_framevec(vaddr, size); @@ -660,8 +666,8 @@ static void vb2_dc_detach_dmabuf(void *mem_priv) kfree(buf); } -static void *vb2_dc_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, - unsigned long size, enum dma_data_direction dma_dir) +static void *vb2_dc_attach_dmabuf(struct vb2_buffer *vb, struct device *dev, + struct dma_buf *dbuf, unsigned long size) { struct vb2_dc_buf *buf; struct dma_buf_attachment *dba; @@ -685,7 +691,7 @@ static void *vb2_dc_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, return dba; } - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->size = size; buf->db_attach = dba; diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index c5b06a509566..50265080cfc8 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -51,6 +51,8 @@ struct vb2_dma_sg_buf { struct vb2_vmarea_handler handler; struct dma_buf_attachment *db_attach; + + struct vb2_buffer *vb; }; static void vb2_dma_sg_put(void *buf_priv); @@ -96,9 +98,8 @@ static int vb2_dma_sg_alloc_compacted(struct vb2_dma_sg_buf *buf, return 0; } -static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, - unsigned long size, enum dma_data_direction dma_dir, - gfp_t gfp_flags) +static void *vb2_dma_sg_alloc(struct vb2_buffer *vb, struct device *dev, + unsigned long size) { struct vb2_dma_sg_buf *buf; struct sg_table *sgt; @@ -113,7 +114,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, return ERR_PTR(-ENOMEM); buf->vaddr = NULL; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->offset = 0; buf->size = size; /* size is already page aligned */ @@ -130,7 +131,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, if (!buf->pages) goto fail_pages_array_alloc; - ret = vb2_dma_sg_alloc_compacted(buf, gfp_flags); + ret = vb2_dma_sg_alloc_compacted(buf, vb->vb2_queue->gfp_flags); if (ret) goto fail_pages_alloc; @@ -154,6 +155,7 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dma_sg_put; buf->handler.arg = buf; + buf->vb = vb; refcount_set(&buf->refcount, 1); @@ -213,9 +215,8 @@ static void vb2_dma_sg_finish(void *buf_priv) dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir); } -static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, - unsigned long size, - enum dma_data_direction dma_dir) +static void *vb2_dma_sg_get_userptr(struct vb2_buffer *vb, struct device *dev, + unsigned long vaddr, unsigned long size) { struct vb2_dma_sg_buf *buf; struct sg_table *sgt; @@ -230,7 +231,7 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, buf->vaddr = NULL; buf->dev = dev; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->offset = vaddr & ~PAGE_MASK; buf->size = size; buf->dma_sgt = &buf->sg_table; @@ -292,7 +293,7 @@ static void vb2_dma_sg_put_userptr(void *buf_priv) kfree(buf); } -static void *vb2_dma_sg_vaddr(void *buf_priv) +static void *vb2_dma_sg_vaddr(struct vb2_buffer *vb, void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv; struct dma_buf_map map; @@ -511,7 +512,9 @@ static const struct dma_buf_ops vb2_dma_sg_dmabuf_ops = { .release = vb2_dma_sg_dmabuf_ops_release, }; -static struct dma_buf *vb2_dma_sg_get_dmabuf(void *buf_priv, unsigned long flags) +static struct dma_buf *vb2_dma_sg_get_dmabuf(struct vb2_buffer *vb, + void *buf_priv, + unsigned long flags) { struct vb2_dma_sg_buf *buf = buf_priv; struct dma_buf *dbuf; @@ -605,8 +608,8 @@ static void vb2_dma_sg_detach_dmabuf(void *mem_priv) kfree(buf); } -static void *vb2_dma_sg_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, - unsigned long size, enum dma_data_direction dma_dir) +static void *vb2_dma_sg_attach_dmabuf(struct vb2_buffer *vb, struct device *dev, + struct dma_buf *dbuf, unsigned long size) { struct vb2_dma_sg_buf *buf; struct dma_buf_attachment *dba; @@ -630,14 +633,14 @@ static void *vb2_dma_sg_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, return dba; } - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->size = size; buf->db_attach = dba; return buf; } -static void *vb2_dma_sg_cookie(void *buf_priv) +static void *vb2_dma_sg_cookie(struct vb2_buffer *vb, void *buf_priv) { struct vb2_dma_sg_buf *buf = buf_priv; diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c index 83f95258ec8c..ef36abd912dc 100644 --- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c +++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c @@ -34,13 +34,12 @@ struct vb2_vmalloc_buf { static void vb2_vmalloc_put(void *buf_priv); -static void *vb2_vmalloc_alloc(struct device *dev, unsigned long attrs, - unsigned long size, enum dma_data_direction dma_dir, - gfp_t gfp_flags) +static void *vb2_vmalloc_alloc(struct vb2_buffer *vb, struct device *dev, + unsigned long size) { struct vb2_vmalloc_buf *buf; - buf = kzalloc(sizeof(*buf), GFP_KERNEL | gfp_flags); + buf = kzalloc(sizeof(*buf), GFP_KERNEL | vb->vb2_queue->gfp_flags); if (!buf) return ERR_PTR(-ENOMEM); @@ -52,7 +51,7 @@ static void *vb2_vmalloc_alloc(struct device *dev, unsigned long attrs, return ERR_PTR(-ENOMEM); } - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_vmalloc_put; buf->handler.arg = buf; @@ -71,9 +70,8 @@ static void vb2_vmalloc_put(void *buf_priv) } } -static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr, - unsigned long size, - enum dma_data_direction dma_dir) +static void *vb2_vmalloc_get_userptr(struct vb2_buffer *vb, struct device *dev, + unsigned long vaddr, unsigned long size) { struct vb2_vmalloc_buf *buf; struct frame_vector *vec; @@ -84,7 +82,7 @@ static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr, if (!buf) return ERR_PTR(-ENOMEM); - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; offset = vaddr & ~PAGE_MASK; buf->size = size; vec = vb2_create_framevec(vaddr, size); @@ -147,7 +145,7 @@ static void vb2_vmalloc_put_userptr(void *buf_priv) kfree(buf); } -static void *vb2_vmalloc_vaddr(void *buf_priv) +static void *vb2_vmalloc_vaddr(struct vb2_buffer *vb, void *buf_priv) { struct vb2_vmalloc_buf *buf = buf_priv; @@ -339,7 +337,9 @@ static const struct dma_buf_ops vb2_vmalloc_dmabuf_ops = { .release = vb2_vmalloc_dmabuf_ops_release, }; -static struct dma_buf *vb2_vmalloc_get_dmabuf(void *buf_priv, unsigned long flags) +static struct dma_buf *vb2_vmalloc_get_dmabuf(struct vb2_buffer *vb, + void *buf_priv, + unsigned long flags) { struct vb2_vmalloc_buf *buf = buf_priv; struct dma_buf *dbuf; @@ -403,8 +403,10 @@ static void vb2_vmalloc_detach_dmabuf(void *mem_priv) kfree(buf); } -static void *vb2_vmalloc_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, - unsigned long size, enum dma_data_direction dma_dir) +static void *vb2_vmalloc_attach_dmabuf(struct vb2_buffer *vb, + struct device *dev, + struct dma_buf *dbuf, + unsigned long size) { struct vb2_vmalloc_buf *buf; @@ -416,7 +418,7 @@ static void *vb2_vmalloc_attach_dmabuf(struct device *dev, struct dma_buf *dbuf, return ERR_PTR(-ENOMEM); buf->dbuf = dbuf; - buf->dma_dir = dma_dir; + buf->dma_dir = vb->vb2_queue->dma_dir; buf->size = size; return buf; diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 12955cb460d2..3b5986cee073 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -46,6 +46,7 @@ enum vb2_memory { struct vb2_fileio_data; struct vb2_threadio_data; +struct vb2_buffer; /** * struct vb2_mem_ops - memory handling/memory allocator operations. @@ -53,10 +54,8 @@ struct vb2_threadio_data; * return ERR_PTR() on failure or a pointer to allocator private, * per-buffer data on success; the returned private structure * will then be passed as @buf_priv argument to other ops in this - * structure. Additional gfp_flags to use when allocating the - * are also passed to this operation. These flags are from the - * gfp_flags field of vb2_queue. The size argument to this function - * shall be *page aligned*. + * structure. The size argument to this function shall be + * *page aligned*. * @put: inform the allocator that the buffer will no longer be used; * usually will result in the allocator freeing the buffer (if * no other users of this buffer are present); the @buf_priv @@ -117,31 +116,33 @@ struct vb2_threadio_data; * map_dmabuf, unmap_dmabuf. */ struct vb2_mem_ops { - void *(*alloc)(struct device *dev, unsigned long attrs, - unsigned long size, - enum dma_data_direction dma_dir, - gfp_t gfp_flags); + void *(*alloc)(struct vb2_buffer *vb, + struct device *dev, + unsigned long size); void (*put)(void *buf_priv); - struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags); - - void *(*get_userptr)(struct device *dev, unsigned long vaddr, - unsigned long size, - enum dma_data_direction dma_dir); + struct dma_buf *(*get_dmabuf)(struct vb2_buffer *vb, + void *buf_priv, + unsigned long flags); + + void *(*get_userptr)(struct vb2_buffer *vb, + struct device *dev, + unsigned long vaddr, + unsigned long size); void (*put_userptr)(void *buf_priv); void (*prepare)(void *buf_priv); void (*finish)(void *buf_priv); - void *(*attach_dmabuf)(struct device *dev, + void *(*attach_dmabuf)(struct vb2_buffer *vb, + struct device *dev, struct dma_buf *dbuf, - unsigned long size, - enum dma_data_direction dma_dir); + unsigned long size); void (*detach_dmabuf)(void *buf_priv); int (*map_dmabuf)(void *buf_priv); void (*unmap_dmabuf)(void *buf_priv); - void *(*vaddr)(void *buf_priv); - void *(*cookie)(void *buf_priv); + void *(*vaddr)(struct vb2_buffer *vb, void *buf_priv); + void *(*cookie)(struct vb2_buffer *vb, void *buf_priv); unsigned int (*num_users)(void *buf_priv); From patchwork Thu Sep 9 11:24:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 12482937 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 23C00C433EF for ; Thu, 9 Sep 2021 11:24:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0A2DB61108 for ; Thu, 9 Sep 2021 11:24:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235610AbhIILZ4 (ORCPT ); Thu, 9 Sep 2021 07:25:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235607AbhIILZx (ORCPT ); Thu, 9 Sep 2021 07:25:53 -0400 Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0342C061575 for ; Thu, 9 Sep 2021 04:24:44 -0700 (PDT) Received: by mail-pf1-x42b.google.com with SMTP id m26so1500063pff.3 for ; Thu, 09 Sep 2021 04:24:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=swwocjCHwnFhDv18CR9iA/cY9VhySGC5NfoAXdQgSF0=; b=I8Me92RYM8/W/ZtrBDZ9IiE82t7fBH+u3XzkZe/uYnbERfvUjkDmQ9tB8z8pOU3mqv 2q1Oo7TTaMjt3ZfOFmx1iEXl2rzYSYp96/M7OIWPV5Hh1XpN5+4DE8aGo3krrldNFTk9 dztPcZMbv689plhnx8PCCIIJqcKKkCOCU4gc0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=swwocjCHwnFhDv18CR9iA/cY9VhySGC5NfoAXdQgSF0=; b=eulMtay9poK4LmX0zsqrd8Fw3UGxSUYU8Vxgvb9zX/Y6n6ZCb6h7qYYWUktT4am+oH cLiev5jUW8i4Uu9NfSNXiL433jr1yC5H340gdyAEkw1XjTg6W1/M2pdkeKr/4Yb4FaK4 MFuZ20MekpyQuhQPGhLeRcUw2Jxa+SvXSXhAhNTeGR5mf2H2iTY6oAp9yxjFd1XSGyfb QFA/1PUC/P4rFPzn8yH6YFNpciLXrexEOU1o6LVesL+c6xnQvdmJbnvpYKuQqZ74nMJk YH9AzVOcEXqrko/yS47S1XytF8xSnpU8Zo8DwfGoQe26V3cTnx5EjWJA0yyIq5Rey5qb Lf7w== X-Gm-Message-State: AOAM533BfwGroQA0KGMAn6bxUPpBBI6bptmsdzhrBtduducda1YgTiJd AtQzMkQshFusSYjVnOwRWpNx3A== X-Google-Smtp-Source: ABdhPJzRB2sUjO1t7wJDhEzuCyQoiG8FGy1za7PQD/DCbSph/An5vJPqh4hmca5qiMgXVG5sC86rJA== X-Received: by 2002:a63:f40b:: with SMTP id g11mr2198564pgi.401.1631186684131; Thu, 09 Sep 2021 04:24:44 -0700 (PDT) Received: from senozhatsky.flets-east.jp ([2409:10:2e40:5100:166b:dcfc:dcf2:bbe2]) by smtp.gmail.com with ESMTPSA id 141sm2046860pgg.16.2021.09.09.04.24.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 04:24:43 -0700 (PDT) From: Sergey Senozhatsky To: Tomasz Figa , Hans Verkuil Cc: Marek Szyprowski , Dafna Hirschfeld , Ricardo Ribalda , Christoph Hellwig , Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Senozhatsky Subject: [PATCHv6 2/8] videobuf2: inverse buffer cache_hints flags Date: Thu, 9 Sep 2021 20:24:24 +0900 Message-Id: <20210909112430.61243-3-senozhatsky@chromium.org> X-Mailer: git-send-email 2.33.0.153.gba50c8fa24-goog In-Reply-To: <20210909112430.61243-1-senozhatsky@chromium.org> References: <20210909112430.61243-1-senozhatsky@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org It would be less error prone if the default cache hints value (we kzalloc() structs, so it's zeroed out by default) would be to "always sync/flush" caches. Inverse and rename cache hints flags. Signed-off-by: Sergey Senozhatsky --- .../media/common/videobuf2/videobuf2-core.c | 31 ++++++------------- .../media/common/videobuf2/videobuf2-v4l2.c | 17 +++------- include/media/videobuf2-core.h | 12 +++---- 3 files changed, 21 insertions(+), 39 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index c4ff356da600..9d57df348b5f 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -327,12 +327,12 @@ static void __vb2_buf_mem_prepare(struct vb2_buffer *vb) if (vb->synced) return; - if (vb->need_cache_sync_on_prepare) { - for (plane = 0; plane < vb->num_planes; ++plane) - call_void_memop(vb, prepare, - vb->planes[plane].mem_priv); - } vb->synced = 1; + if (vb->skip_cache_sync_on_prepare) + return; + + for (plane = 0; plane < vb->num_planes; ++plane) + call_void_memop(vb, prepare, vb->planes[plane].mem_priv); } /* @@ -346,12 +346,12 @@ static void __vb2_buf_mem_finish(struct vb2_buffer *vb) if (!vb->synced) return; - if (vb->need_cache_sync_on_finish) { - for (plane = 0; plane < vb->num_planes; ++plane) - call_void_memop(vb, finish, - vb->planes[plane].mem_priv); - } vb->synced = 0; + if (vb->skip_cache_sync_on_finish) + return; + + for (plane = 0; plane < vb->num_planes; ++plane) + call_void_memop(vb, finish, vb->planes[plane].mem_priv); } /* @@ -415,17 +415,6 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, vb->index = q->num_buffers + buffer; vb->type = q->type; vb->memory = memory; - /* - * We need to set these flags here so that the videobuf2 core - * will call ->prepare()/->finish() cache sync/flush on vb2 - * buffers when appropriate. However, we can avoid explicit - * ->prepare() and ->finish() cache sync for DMABUF buffers, - * because DMA exporter takes care of it. - */ - if (q->memory != VB2_MEMORY_DMABUF) { - vb->need_cache_sync_on_prepare = 1; - vb->need_cache_sync_on_finish = 1; - } for (plane = 0; plane < num_planes; ++plane) { vb->planes[plane].length = plane_sizes[plane]; vb->planes[plane].min_length = plane_sizes[plane]; diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 2988bb38ceb1..454d58268602 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -351,18 +351,11 @@ static void set_buffer_cache_hints(struct vb2_queue *q, * we always need ->prepare() or/and ->finish() cache sync. */ if (q->memory == VB2_MEMORY_DMABUF) { - vb->need_cache_sync_on_finish = 0; - vb->need_cache_sync_on_prepare = 0; + vb->skip_cache_sync_on_finish = 1; + vb->skip_cache_sync_on_prepare = 1; return; } - /* - * Cache sync/invalidation flags are set by default in order to - * preserve existing behaviour for old apps/drivers. - */ - vb->need_cache_sync_on_prepare = 1; - vb->need_cache_sync_on_finish = 1; - if (!vb2_queue_allows_cache_hints(q)) { /* * Clear buffer cache flags if queue does not support user @@ -379,13 +372,13 @@ static void set_buffer_cache_hints(struct vb2_queue *q, * TO_DEVICE. */ if (q->dma_dir == DMA_TO_DEVICE) - vb->need_cache_sync_on_finish = 0; + vb->skip_cache_sync_on_finish = 1; if (b->flags & V4L2_BUF_FLAG_NO_CACHE_INVALIDATE) - vb->need_cache_sync_on_finish = 0; + vb->skip_cache_sync_on_finish = 1; if (b->flags & V4L2_BUF_FLAG_NO_CACHE_CLEAN) - vb->need_cache_sync_on_prepare = 0; + vb->skip_cache_sync_on_prepare = 1; } static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct media_device *mdev, diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 3b5986cee073..66e548268242 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -267,10 +267,10 @@ struct vb2_buffer { * after the 'buf_finish' op is called. * copied_timestamp: the timestamp of this capture buffer was copied * from an output buffer. - * need_cache_sync_on_prepare: when set buffer's ->prepare() function - * performs cache sync/invalidation. - * need_cache_sync_on_finish: when set buffer's ->finish() function - * performs cache sync/invalidation. + * skip_cache_sync_on_prepare: when set buffer's ->prepare() function + * skips cache sync/invalidation. + * skip_cache_sync_on_finish: when set buffer's ->finish() function + * skips cache sync/invalidation. * queued_entry: entry on the queued buffers list, which holds * all buffers queued from userspace * done_entry: entry on the list that stores all buffers ready @@ -281,8 +281,8 @@ struct vb2_buffer { unsigned int synced:1; unsigned int prepared:1; unsigned int copied_timestamp:1; - unsigned int need_cache_sync_on_prepare:1; - unsigned int need_cache_sync_on_finish:1; + unsigned int skip_cache_sync_on_prepare:1; + unsigned int skip_cache_sync_on_finish:1; struct vb2_plane planes[VB2_MAX_PLANES]; struct list_head queued_entry; From patchwork Thu Sep 9 11:24:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 12482939 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 069F3C433F5 for ; Thu, 9 Sep 2021 11:24:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C6CF761108 for ; Thu, 9 Sep 2021 11:24:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235563AbhIILZ6 (ORCPT ); Thu, 9 Sep 2021 07:25:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235537AbhIILZ4 (ORCPT ); Thu, 9 Sep 2021 07:25:56 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E258C061757 for ; Thu, 9 Sep 2021 04:24:47 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id gp20-20020a17090adf1400b00196b761920aso1172633pjb.3 for ; Thu, 09 Sep 2021 04:24:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EqY9Du2dCXm5e2YFE5a0cZBsTxcPxVjIu2njFipHgHw=; b=G19+y9z5CDEaaALpL+7ifsbNZytT/v8P3hpg3dUCiiVCfmZw0VBEFke0AEIHXHi69T HlmygCNlKYwNR3cAN7M7qbkFHQaPxkMjNKCaVb4bj9/UI1hAx0LA7gdvVApClMET+aGk G9hbhW3qX06ospNQ/xLRM0XJZIdGMLlzbN5VU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EqY9Du2dCXm5e2YFE5a0cZBsTxcPxVjIu2njFipHgHw=; b=d6Ar/0FjdFmb71fo6Em101gdZ7MumPw7u7L5vr3H1vQ69mstXjA/aCb/MQNItybERQ lXo4IFX+3po3cZAKFmh9b4mjcY6q7KJhn8OmwU3BQ8qJVd4FIycLh/WUYGg7Muos+5f1 X4muzdz7HY7O4zURE9acaGmMHM67VDcyCFXTuD5CUHrx4ZWWVzsQHyY25RQZzdQrsulw 3yAOmb2MtYAWB+Zj/p9CdSQVVqDVxcZqug/9pZUkL374fI9dcC/YMyOcvDRxh+xzNy4o VLL9RyBcY0OzezFkUYtXYJmzahVtXKMK3zItZJeP+22mNWgM4Svm3L4VbDejrzGfD4rh uBlg== X-Gm-Message-State: AOAM533HsrenJ5iT5OXvzdme1ViA02W7gn5Yfz2TRzoehbiTkcYCjtoK z6ZVqhgMF873D9PLNWHTVuw+ig== X-Google-Smtp-Source: ABdhPJxlLkIpJJ/qbHZRgkgC1g1sHHamTpvn45qjjIseTOO9naTPcSmT0PPgBb6eJsZzc2h4X1V0XQ== X-Received: by 2002:a17:90b:4b90:: with SMTP id lr16mr3053589pjb.210.1631186687142; Thu, 09 Sep 2021 04:24:47 -0700 (PDT) Received: from senozhatsky.flets-east.jp ([2409:10:2e40:5100:166b:dcfc:dcf2:bbe2]) by smtp.gmail.com with ESMTPSA id 141sm2046860pgg.16.2021.09.09.04.24.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 04:24:46 -0700 (PDT) From: Sergey Senozhatsky To: Tomasz Figa , Hans Verkuil Cc: Marek Szyprowski , Dafna Hirschfeld , Ricardo Ribalda , Christoph Hellwig , Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Senozhatsky Subject: [PATCHv6 3/8] videobuf2: split buffer cache_hints initialisation Date: Thu, 9 Sep 2021 20:24:25 +0900 Message-Id: <20210909112430.61243-4-senozhatsky@chromium.org> X-Mailer: git-send-email 2.33.0.153.gba50c8fa24-goog In-Reply-To: <20210909112430.61243-1-senozhatsky@chromium.org> References: <20210909112430.61243-1-senozhatsky@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org V4L2 is not the perfect place to manage vb2 buffer cache hints. It works for V4L2 users, but there are backends that use vb2 core and don't use V4L2. Factor out buffer cache hints initialisation and call it when we allocate vb2 buffer. Signed-off-by: Sergey Senozhatsky --- .../media/common/videobuf2/videobuf2-core.c | 22 +++++++++++++++++++ .../media/common/videobuf2/videobuf2-v4l2.c | 18 --------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 9d57df348b5f..59bd781c9a34 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -382,6 +382,27 @@ static void __setup_offsets(struct vb2_buffer *vb) } } +static void init_buffer_cache_hints(struct vb2_queue *q, struct vb2_buffer *vb) +{ + /* + * DMA exporter should take care of cache syncs, so we can avoid + * explicit ->prepare()/->finish() syncs. For other ->memory types + * we always need ->prepare() or/and ->finish() cache sync. + */ + if (q->memory == VB2_MEMORY_DMABUF) { + vb->skip_cache_sync_on_finish = 1; + vb->skip_cache_sync_on_prepare = 1; + return; + } + + /* + * ->finish() cache sync can be avoided when queue direction is + * TO_DEVICE. + */ + if (q->dma_dir == DMA_TO_DEVICE) + vb->skip_cache_sync_on_finish = 1; +} + /* * __vb2_queue_alloc() - allocate videobuf buffer structures and (for MMAP type) * video buffer memory for all buffers/planes on the queue and initializes the @@ -415,6 +436,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum vb2_memory memory, vb->index = q->num_buffers + buffer; vb->type = q->type; vb->memory = memory; + init_buffer_cache_hints(q, vb); for (plane = 0; plane < num_planes; ++plane) { vb->planes[plane].length = plane_sizes[plane]; vb->planes[plane].min_length = plane_sizes[plane]; diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 454d58268602..2fbae9bd7b52 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -345,17 +345,6 @@ static void set_buffer_cache_hints(struct vb2_queue *q, struct vb2_buffer *vb, struct v4l2_buffer *b) { - /* - * DMA exporter should take care of cache syncs, so we can avoid - * explicit ->prepare()/->finish() syncs. For other ->memory types - * we always need ->prepare() or/and ->finish() cache sync. - */ - if (q->memory == VB2_MEMORY_DMABUF) { - vb->skip_cache_sync_on_finish = 1; - vb->skip_cache_sync_on_prepare = 1; - return; - } - if (!vb2_queue_allows_cache_hints(q)) { /* * Clear buffer cache flags if queue does not support user @@ -367,13 +356,6 @@ static void set_buffer_cache_hints(struct vb2_queue *q, return; } - /* - * ->finish() cache sync can be avoided when queue direction is - * TO_DEVICE. - */ - if (q->dma_dir == DMA_TO_DEVICE) - vb->skip_cache_sync_on_finish = 1; - if (b->flags & V4L2_BUF_FLAG_NO_CACHE_INVALIDATE) vb->skip_cache_sync_on_finish = 1; From patchwork Thu Sep 9 11:24:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 12482941 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72FD5C433EF for ; Thu, 9 Sep 2021 11:24:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 503BC61100 for ; Thu, 9 Sep 2021 11:24:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235739AbhIIL0D (ORCPT ); Thu, 9 Sep 2021 07:26:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60474 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235738AbhIIL0A (ORCPT ); Thu, 9 Sep 2021 07:26:00 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A4ABBC061757 for ; Thu, 9 Sep 2021 04:24:50 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id g13-20020a17090a3c8d00b00196286963b9so1199108pjc.3 for ; Thu, 09 Sep 2021 04:24:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XfTVnM+Kdt1HMBYOgi0OID403DvPUnw+Oe4D7AokcIc=; b=TXa6Dh43j/RiJZcZfGp/U/VMI+kPFpebUW9dJNRgCKOI8Rkz3AqIXHDOcLjE4jOHZU zsG5+VjKHQpcIow4nejBjuuyDQJKo7pC/ClLLcCpI3wvY4p3IBlEGV4ZyHCVgkyj965P BhrhuBZoTAhWscYuMsZE2jSZSbL/geboBEpxA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XfTVnM+Kdt1HMBYOgi0OID403DvPUnw+Oe4D7AokcIc=; b=jEexwMLfw3uXqtRvAnupUSh/AwEOzI3HGGncirzmJE+Q57Dgr4l7e1jJpQBcy35Nv/ AUrgmxJErNUQLaBanj7e4EE+awvxsN/QxxZNQt4XCyiGhHpvbYhIzKw3sNBjuia0Wmb7 vUpYPAaVtFKMDW0QI6ps/1CR2CfJhS3doDu6wNor+1IoiMx5hqAlfAkP9npB2r/OYpPm Ee6Ia7sU0iVutwMuMj7COlvchb0Uxoxcrn6RXkNujiWf/uqdOKRovEbFsVOEaMaksI7n H9yItSwfeyBzdNW9FxwyTOxQ6VhgS8cjvZXxOOJNRUiM7KUsOawAp3E6MnopBR1e74W+ U/CQ== X-Gm-Message-State: AOAM532+dJ5QEWEShU8bmA3dHIQwhaXhWZ8L4odCm0HIqKYiu1nYo/HJ nXAZtzA7DtTmC/pnTEQmBt7mTw== X-Google-Smtp-Source: ABdhPJyYcIxqMXzbTTXZ+BGYIqnO0OtUvhfEBnjB2NdtsZQsyV5eTybm60VfLtu7rj7YAHjskwgpXQ== X-Received: by 2002:a17:902:9008:b0:12d:8258:e07c with SMTP id a8-20020a170902900800b0012d8258e07cmr2304758plp.42.1631186690246; Thu, 09 Sep 2021 04:24:50 -0700 (PDT) Received: from senozhatsky.flets-east.jp ([2409:10:2e40:5100:166b:dcfc:dcf2:bbe2]) by smtp.gmail.com with ESMTPSA id 141sm2046860pgg.16.2021.09.09.04.24.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 04:24:49 -0700 (PDT) From: Sergey Senozhatsky To: Tomasz Figa , Hans Verkuil Cc: Marek Szyprowski , Dafna Hirschfeld , Ricardo Ribalda , Christoph Hellwig , Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Senozhatsky Subject: [PATCHv6 4/8] videobuf2: move cache_hints handling to allocators Date: Thu, 9 Sep 2021 20:24:26 +0900 Message-Id: <20210909112430.61243-5-senozhatsky@chromium.org> X-Mailer: git-send-email 2.33.0.153.gba50c8fa24-goog In-Reply-To: <20210909112430.61243-1-senozhatsky@chromium.org> References: <20210909112430.61243-1-senozhatsky@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org This moves cache hints handling from the videobuf2 core down to the allocator's level, because allocators do the sync/flush caches eventually and may take better decisions. Besides, allocators already decide whether cache sync/flush should be done or can be skipped. This patch moves the scattered buffer cache sync logic to one common place. Signed-off-by: Sergey Senozhatsky --- drivers/media/common/videobuf2/videobuf2-core.c | 6 ------ drivers/media/common/videobuf2/videobuf2-dma-contig.c | 6 ++++++ drivers/media/common/videobuf2/videobuf2-dma-sg.c | 6 ++++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 59bd781c9a34..8fa9f92ed028 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -328,9 +328,6 @@ static void __vb2_buf_mem_prepare(struct vb2_buffer *vb) return; vb->synced = 1; - if (vb->skip_cache_sync_on_prepare) - return; - for (plane = 0; plane < vb->num_planes; ++plane) call_void_memop(vb, prepare, vb->planes[plane].mem_priv); } @@ -347,9 +344,6 @@ static void __vb2_buf_mem_finish(struct vb2_buffer *vb) return; vb->synced = 0; - if (vb->skip_cache_sync_on_finish) - return; - for (plane = 0; plane < vb->num_planes; ++plane) call_void_memop(vb, finish, vb->planes[plane].mem_priv); } diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index 019c3843dc6d..1e218bc440c6 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -101,6 +101,9 @@ static void vb2_dc_prepare(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; + if (buf->vb->skip_cache_sync_on_prepare) + return; + if (!sgt) return; @@ -112,6 +115,9 @@ static void vb2_dc_finish(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; + if (buf->vb->skip_cache_sync_on_finish) + return; + if (!sgt) return; diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index 50265080cfc8..33ee63a99139 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -204,6 +204,9 @@ static void vb2_dma_sg_prepare(void *buf_priv) struct vb2_dma_sg_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; + if (buf->vb->skip_cache_sync_on_prepare) + return; + dma_sync_sgtable_for_device(buf->dev, sgt, buf->dma_dir); } @@ -212,6 +215,9 @@ static void vb2_dma_sg_finish(void *buf_priv) struct vb2_dma_sg_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; + if (buf->vb->skip_cache_sync_on_finish) + return; + dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir); } From patchwork Thu Sep 9 11:24:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 12482943 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3CD8EC433F5 for ; Thu, 9 Sep 2021 11:24:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2473461104 for ; Thu, 9 Sep 2021 11:24:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235738AbhIIL0F (ORCPT ); Thu, 9 Sep 2021 07:26:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60490 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235845AbhIIL0D (ORCPT ); Thu, 9 Sep 2021 07:26:03 -0400 Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CB006C061756 for ; Thu, 9 Sep 2021 04:24:53 -0700 (PDT) Received: by mail-pj1-x1030.google.com with SMTP id g13-20020a17090a3c8d00b00196286963b9so1199226pjc.3 for ; Thu, 09 Sep 2021 04:24:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0z+xAl8TBWOblx8EQFOc7DA5ndExlKG16qGdAhcTw4k=; b=KIqKlWJ9AhCGKUZHkvsIYEdOyFphbN8Obq1xleTyiHby/e7OYnXAC5Nnut2v90TpOS hCzcZztAJdye8M1cdIyyvs5fXU1heM6JFS8LFQSyYDhT6u78nZqYDGcIopIUClX+pNJO 9DiNSphLv5fpFtyx7YkESXclYjlv1WcrKjINg= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0z+xAl8TBWOblx8EQFOc7DA5ndExlKG16qGdAhcTw4k=; b=EJXs0b+TjKhApg4r0m1fZrokzRSKb83YiwO6iB4muXB/jUAw78En8yzndnYHvSHNYp xkHFZjZkw7B5ZpZmWjAkAzyrRhAcPV9XofqVHnizK8ab5MVbwlSumVHZoLn8F4KKvUNU zWZ8HVKl6zMkyOUMZovIkzb3nC61rB9hSmsQIP++ZlllGW0z41PqnBVKjxnJIVHNSc8u RCeOJFfyf0O2Mkiem+/7fqynEngCYGdsmYIv9KRGIjBfeCrR2XRKDdadMReDx8f3Djlg MzdGvCdt9EHN7KcZU5eSBAjjHQibO2fwxzdEE5e1zDl5uqvPKilg51zQeaqDwEnWEhYw Ctyw== X-Gm-Message-State: AOAM531jK1gOmdawSRX20Zhc1WRdP41ryFLwNmxz2RHYpK0MCq8EhUyT FcxqfIDz7VF3gop+w8OMkFD5VVjfaLmeZQ== X-Google-Smtp-Source: ABdhPJz1hkxUCfnCXXB/PqeJyW8EkAMmShIJg0e5kURcKrw9bzPnpqFOBV0XIvi5SdEhGPBHa4BKCw== X-Received: by 2002:a17:902:bb10:b0:13a:3cc4:8242 with SMTP id im16-20020a170902bb1000b0013a3cc48242mr2248513plb.58.1631186693340; Thu, 09 Sep 2021 04:24:53 -0700 (PDT) Received: from senozhatsky.flets-east.jp ([2409:10:2e40:5100:166b:dcfc:dcf2:bbe2]) by smtp.gmail.com with ESMTPSA id 141sm2046860pgg.16.2021.09.09.04.24.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 04:24:52 -0700 (PDT) From: Sergey Senozhatsky To: Tomasz Figa , Hans Verkuil Cc: Marek Szyprowski , Dafna Hirschfeld , Ricardo Ribalda , Christoph Hellwig , Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Senozhatsky Subject: [PATCHv6 5/8] videobuf2: add V4L2_MEMORY_FLAG_NON_COHERENT flag Date: Thu, 9 Sep 2021 20:24:27 +0900 Message-Id: <20210909112430.61243-6-senozhatsky@chromium.org> X-Mailer: git-send-email 2.33.0.153.gba50c8fa24-goog In-Reply-To: <20210909112430.61243-1-senozhatsky@chromium.org> References: <20210909112430.61243-1-senozhatsky@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org By setting or clearing the V4L2_MEMORY_FLAG_NON_COHERENT flag user-space should be able to hint vb2 that either non-coherent (if supported) or coherent memory should be used for the buffer allocation. Signed-off-by: Sergey Senozhatsky --- .../userspace-api/media/v4l/buffer.rst | 40 ++++++++++++++++++- .../media/v4l/vidioc-reqbufs.rst | 5 ++- include/uapi/linux/videodev2.h | 2 + 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/buffer.rst b/Documentation/userspace-api/media/v4l/buffer.rst index e991ba73d873..4638ec64db00 100644 --- a/Documentation/userspace-api/media/v4l/buffer.rst +++ b/Documentation/userspace-api/media/v4l/buffer.rst @@ -676,8 +676,6 @@ Buffer Flags \normalsize -.. _memory-flags: - enum v4l2_memory ================ @@ -701,6 +699,44 @@ enum v4l2_memory - 4 - The buffer is used for :ref:`DMA shared buffer ` I/O. +.. _memory-flags: + +Memory Consistency Flags +------------------------ + +.. raw:: latex + + \small + +.. tabularcolumns:: |p{7.0cm}|p{2.1cm}|p{8.4cm}| + +.. cssclass:: longtable + +.. flat-table:: + :header-rows: 0 + :stub-columns: 0 + :widths: 3 1 4 + + * .. _`V4L2-MEMORY-FLAG-NON-COHERENT`: + + - ``V4L2_MEMORY_FLAG_NON_COHERENT`` + - 0x00000001 + - A buffer is allocated either in coherent (it will be automatically + coherent between the CPU and the bus) or non-coherent memory. The + latter can provide performance gains, for instance the CPU cache + sync/flush operations can be avoided if the buffer is accessed by the + corresponding device only and the CPU does not read/write to/from that + buffer. However, this requires extra care from the driver -- it must + guarantee memory consistency by issuing a cache flush/sync when + consistency is needed. If this flag is set V4L2 will attempt to + allocate the buffer in non-coherent memory. The flag takes effect + only if the buffer is used for :ref:`memory mapping ` I/O and the + queue reports the :ref:`V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS + ` capability. + +.. raw:: latex + + \normalsize Timecodes ========= diff --git a/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst index 50ea72043bb0..e59306aba2b0 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst @@ -158,8 +158,9 @@ aborting or finishing any DMA in progress, an implicit - This capability is set by the driver to indicate that the queue supports cache and memory management hints. However, it's only valid when the queue is used for :ref:`memory mapping ` streaming I/O. See - :ref:`V4L2_BUF_FLAG_NO_CACHE_INVALIDATE ` and - :ref:`V4L2_BUF_FLAG_NO_CACHE_CLEAN `. + :ref:`V4L2_BUF_FLAG_NO_CACHE_INVALIDATE `, + :ref:`V4L2_BUF_FLAG_NO_CACHE_CLEAN ` and + :ref:`V4L2_MEMORY_FLAG_NON_COHERENT `. .. raw:: latex diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 5cc9545feb40..9b7032abb2c7 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -962,6 +962,8 @@ struct v4l2_requestbuffers { __u32 reserved[1]; }; +#define V4L2_MEMORY_FLAG_NON_COHERENT (1 << 0) + /* capabilities for struct v4l2_requestbuffers and v4l2_create_buffers */ #define V4L2_BUF_CAP_SUPPORTS_MMAP (1 << 0) #define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1) From patchwork Thu Sep 9 11:24:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 12482945 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 45DA6C433EF for ; Thu, 9 Sep 2021 11:25:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2CE7961108 for ; Thu, 9 Sep 2021 11:25:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235939AbhIIL0J (ORCPT ); Thu, 9 Sep 2021 07:26:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235980AbhIIL0G (ORCPT ); Thu, 9 Sep 2021 07:26:06 -0400 Received: from mail-pg1-x52a.google.com (mail-pg1-x52a.google.com [IPv6:2607:f8b0:4864:20::52a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 23C82C061575 for ; Thu, 9 Sep 2021 04:24:57 -0700 (PDT) Received: by mail-pg1-x52a.google.com with SMTP id q68so1440440pga.9 for ; Thu, 09 Sep 2021 04:24:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=O8CM0f8scW5RQspnEWbPj2Rku0hsxQtzo6NTJqy7EvU=; b=RVSd9kD0gcnGn9KQT98QXnTYPdJ71uZ+bLQ1MwAim+jzoxE1YoH6i5YzYQ3gUF8WUq mJRh+CTqPKrV2aHkNwTlhsBMT1B7xrie4uYBNWfrZ+FKsdckUxpMJFgR2oFTQzk8dBnq tIvYogsTlCFlC30QD4vrT2bRGI0+w1vk7JC90= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=O8CM0f8scW5RQspnEWbPj2Rku0hsxQtzo6NTJqy7EvU=; b=iJzdTvzlK/zusd4S5Z0edgAs6uTK/8EGsBodfhE20ApB6OC5S+25Jds58ubce3W1dI Llb8dspgNvHARZ+hsizHG0Gc1polQnq9erWbHnJ0m6VUjl/DhICt8LlvEd80c94/fiaQ YGYPhh9iyEJUJqXyC/FXfRBvfQewsW0ahUx4KDTBrOBXtg8QccO3yiU5XsiwBZde0TnC 48jzey8DtAiqA11Xd82wTvERTaPdUP7fuqQ6H/rk/eRQ8WbncmOGnwOzAuYw5gPwI49Z hG4tz5t6RI6VKy3ehsq/ujNbAK6wd3FbOFxw9RXQM2xP8I/80Iq5w5sFfRaTkssfFZqr YCTQ== X-Gm-Message-State: AOAM5311J1HgzG7ZDnbzVhFCyJkFAEcFjerkDgWJCi6KXhHQsUCTZ2Gx DlzzDCquG7kmAUNbyxJNBSk22w== X-Google-Smtp-Source: ABdhPJx9V1T2vkni8g81sG4ngse9u+awmiJM6Ut2DI+bIf1vnbe8I8FSNDg3xtRPiKQjIdZCwEJhdA== X-Received: by 2002:a63:6f06:: with SMTP id k6mr2203841pgc.281.1631186696611; Thu, 09 Sep 2021 04:24:56 -0700 (PDT) Received: from senozhatsky.flets-east.jp ([2409:10:2e40:5100:166b:dcfc:dcf2:bbe2]) by smtp.gmail.com with ESMTPSA id 141sm2046860pgg.16.2021.09.09.04.24.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 04:24:56 -0700 (PDT) From: Sergey Senozhatsky To: Tomasz Figa , Hans Verkuil Cc: Marek Szyprowski , Dafna Hirschfeld , Ricardo Ribalda , Christoph Hellwig , Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Senozhatsky Subject: [PATCHv6 6/8] videobuf2: add queue memory coherency parameter Date: Thu, 9 Sep 2021 20:24:28 +0900 Message-Id: <20210909112430.61243-7-senozhatsky@chromium.org> X-Mailer: git-send-email 2.33.0.153.gba50c8fa24-goog In-Reply-To: <20210909112430.61243-1-senozhatsky@chromium.org> References: <20210909112430.61243-1-senozhatsky@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Preparations for future V4L2_MEMORY_FLAG_NON_COHERENT support. Extend the vb2_core_reqbufs() parameters list to accept requests' ->flags, which will be used for memory coherency configuration. An attempt to allocate a buffer with coherency requirements that do not match the queue's consistency model will fail. Signed-off-by: Sergey Senozhatsky --- .../media/common/videobuf2/videobuf2-core.c | 37 ++++++++++++++++--- .../media/common/videobuf2/videobuf2-v4l2.c | 5 ++- drivers/media/dvb-core/dvb_vb2.c | 2 +- include/media/videobuf2-core.h | 10 ++++- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 8fa9f92ed028..60fb43b8f134 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -738,11 +738,30 @@ int vb2_verify_memory_type(struct vb2_queue *q, } EXPORT_SYMBOL(vb2_verify_memory_type); +static void set_queue_coherency(struct vb2_queue *q, bool non_coherent_mem) +{ + q->non_coherent_mem = 0; + + if (!vb2_queue_allows_cache_hints(q)) + return; + q->non_coherent_mem = non_coherent_mem; +} + +static bool verify_coherency_flags(struct vb2_queue *q, bool non_coherent_mem) +{ + if (non_coherent_mem != q->non_coherent_mem) { + dprintk(q, 1, "memory coherency model mismatch\n"); + return false; + } + return true; +} + int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, - unsigned int *count) + unsigned int flags, unsigned int *count) { unsigned int num_buffers, allocated_buffers, num_planes = 0; unsigned plane_sizes[VB2_MAX_PLANES] = { }; + bool non_coherent_mem = false; unsigned int i; int ret; @@ -757,7 +776,8 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, } if (*count == 0 || q->num_buffers != 0 || - (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory)) { + (q->memory != VB2_MEMORY_UNKNOWN && q->memory != memory) || + !verify_coherency_flags(q, non_coherent_mem)) { /* * We already have buffers allocated, so first check if they * are not in use and can be freed. @@ -794,6 +814,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, num_buffers = min_t(unsigned int, num_buffers, VB2_MAX_FRAME); memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); q->memory = memory; + set_queue_coherency(q, non_coherent_mem); /* * Ask the driver how many buffers and planes per buffer it requires. @@ -878,12 +899,13 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, EXPORT_SYMBOL_GPL(vb2_core_reqbufs); int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, - unsigned int *count, + unsigned int flags, unsigned int *count, unsigned int requested_planes, const unsigned int requested_sizes[]) { unsigned int num_planes = 0, num_buffers, allocated_buffers; unsigned plane_sizes[VB2_MAX_PLANES] = { }; + bool non_coherent_mem = false; int ret; if (q->num_buffers == VB2_MAX_FRAME) { @@ -899,11 +921,14 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, memset(q->alloc_devs, 0, sizeof(q->alloc_devs)); q->memory = memory; q->waiting_for_buffers = !q->is_output; + set_queue_coherency(q, non_coherent_mem); } else { if (q->memory != memory) { dprintk(q, 1, "memory model mismatch\n"); return -EINVAL; } + if (!verify_coherency_flags(q, non_coherent_mem)) + return -EINVAL; } num_buffers = min(*count, VB2_MAX_FRAME - q->num_buffers); @@ -2608,7 +2633,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) fileio->memory = VB2_MEMORY_MMAP; fileio->type = q->type; q->fileio = fileio; - ret = vb2_core_reqbufs(q, fileio->memory, &fileio->count); + ret = vb2_core_reqbufs(q, fileio->memory, 0, &fileio->count); if (ret) goto err_kfree; @@ -2665,7 +2690,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) err_reqbufs: fileio->count = 0; - vb2_core_reqbufs(q, fileio->memory, &fileio->count); + vb2_core_reqbufs(q, fileio->memory, 0, &fileio->count); err_kfree: q->fileio = NULL; @@ -2685,7 +2710,7 @@ static int __vb2_cleanup_fileio(struct vb2_queue *q) vb2_core_streamoff(q, q->type); q->fileio = NULL; fileio->count = 0; - vb2_core_reqbufs(q, fileio->memory, &fileio->count); + vb2_core_reqbufs(q, fileio->memory, 0, &fileio->count); kfree(fileio); dprintk(q, 3, "file io emulator closed\n"); } diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index 2fbae9bd7b52..b4f70ddb09b0 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -697,7 +697,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) int ret = vb2_verify_memory_type(q, req->memory, req->type); fill_buf_caps(q, &req->capabilities); - return ret ? ret : vb2_core_reqbufs(q, req->memory, &req->count); + return ret ? ret : vb2_core_reqbufs(q, req->memory, 0, &req->count); } EXPORT_SYMBOL_GPL(vb2_reqbufs); @@ -772,6 +772,7 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) if (requested_sizes[i] == 0) return -EINVAL; return ret ? ret : vb2_core_create_bufs(q, create->memory, + 0, &create->count, requested_planes, requested_sizes); @@ -974,7 +975,7 @@ int vb2_ioctl_reqbufs(struct file *file, void *priv, return res; if (vb2_queue_is_busy(vdev, file)) return -EBUSY; - res = vb2_core_reqbufs(vdev->queue, p->memory, &p->count); + res = vb2_core_reqbufs(vdev->queue, p->memory, 0, &p->count); /* If count == 0, then the owner has released all buffers and he is no longer owner of the queue. Otherwise we have a new owner. */ if (res == 0) diff --git a/drivers/media/dvb-core/dvb_vb2.c b/drivers/media/dvb-core/dvb_vb2.c index 6974f1731529..959d110407a4 100644 --- a/drivers/media/dvb-core/dvb_vb2.c +++ b/drivers/media/dvb-core/dvb_vb2.c @@ -342,7 +342,7 @@ int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req) ctx->buf_siz = req->size; ctx->buf_cnt = req->count; - ret = vb2_core_reqbufs(&ctx->vb_q, VB2_MEMORY_MMAP, &req->count); + ret = vb2_core_reqbufs(&ctx->vb_q, VB2_MEMORY_MMAP, 0, &req->count); if (ret) { ctx->state = DVB_VB2_STATE_NONE; dprintk(1, "[%s] count=%d size=%d errno=%d\n", ctx->name, diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 66e548268242..2467284e5f26 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -504,6 +504,8 @@ struct vb2_buf_ops { * @allow_cache_hints: when set user-space can pass cache management hints in * order to skip cache flush/invalidation on ->prepare() or/and * ->finish(). + * @non_coherent_mem: when set queue will attempt to allocate buffers using + * non-coherent memory. * @lock: pointer to a mutex that protects the &struct vb2_queue. The * driver can set this to a mutex to let the v4l2 core serialize * the queuing ioctls. If the driver wants to handle locking @@ -583,6 +585,7 @@ struct vb2_queue { unsigned int uses_qbuf:1; unsigned int uses_requests:1; unsigned int allow_cache_hints:1; + unsigned int non_coherent_mem:1; struct mutex *lock; void *owner; @@ -748,6 +751,8 @@ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb); * vb2_core_reqbufs() - Initiate streaming. * @q: pointer to &struct vb2_queue with videobuf2 queue. * @memory: memory type, as defined by &enum vb2_memory. + * @flags: auxiliary queue/buffer management flags. Currently, the only + * used flag is %V4L2_MEMORY_FLAG_NON_COHERENT. * @count: requested buffer count. * * Videobuf2 core helper to implement VIDIOC_REQBUF() operation. It is called @@ -772,12 +777,13 @@ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb); * Return: returns zero on success; an error code otherwise. */ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, - unsigned int *count); + unsigned int flags, unsigned int *count); /** * vb2_core_create_bufs() - Allocate buffers and any required auxiliary structs * @q: pointer to &struct vb2_queue with videobuf2 queue. * @memory: memory type, as defined by &enum vb2_memory. + * @flags: auxiliary queue/buffer management flags. * @count: requested buffer count. * @requested_planes: number of planes requested. * @requested_sizes: array with the size of the planes. @@ -795,7 +801,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, * Return: returns zero on success; an error code otherwise. */ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, - unsigned int *count, + unsigned int flags, unsigned int *count, unsigned int requested_planes, const unsigned int requested_sizes[]); From patchwork Thu Sep 9 11:24:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 12482947 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C7D3C433F5 for ; Thu, 9 Sep 2021 11:25:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 61A3B61100 for ; Thu, 9 Sep 2021 11:25:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235932AbhIIL0N (ORCPT ); Thu, 9 Sep 2021 07:26:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60542 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236022AbhIIL0J (ORCPT ); Thu, 9 Sep 2021 07:26:09 -0400 Received: from mail-pl1-x62c.google.com (mail-pl1-x62c.google.com [IPv6:2607:f8b0:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3E580C061575 for ; Thu, 9 Sep 2021 04:25:00 -0700 (PDT) Received: by mail-pl1-x62c.google.com with SMTP id j2so866857pll.1 for ; Thu, 09 Sep 2021 04:25:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6jwcZvsoijDAGwBg8IA2/PrpZJI/9tiv+liR+PCSCRA=; b=GHrVNHsS7nRnzdyYRkrXlBCxfGNnYH7yn+BFP1RpCOi7gn7mKwA1uGR3XwWLM3TezG STffHWjUZweIvRo4z6ZwKtWaN6v48gA7x5kJIf3d8EUfLlBP9xH7dq09uxOlgM6/fdGv 3DcEeOw2u7Hohvpph0Hz4DCcm6QbHkucXrJlQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6jwcZvsoijDAGwBg8IA2/PrpZJI/9tiv+liR+PCSCRA=; b=FcXEGUAf55x7mtE9LtCvgqGYOS989I10/XlpQZF1H+4vSqF7rpoRkUzS8miburEpOO kdZvGTElvHIjCK5D0RRtX8WhzB+XvdCexND5cxQ2IBTlTzmFdJWff7RrdkA8rsDxyuXh F1YrgyyipZhnS64hXSh9V72X/pG4hmQzTsvhZmOz3/LpTvma96ifxMaCjn1OhmPYWRg+ kwuHaWFHPSXd/yqtGNHHymqu2yB1RPZ1XEQjPpy/YRlYQ7csr8s2Tm07u1EO8W2b+l6Z Jfrny88sWgroFKdVyaRo0ddXx3R9hf5lG4pIxOm+xhVvezbAnRIhmF3aQt9uYkgQNMVk icWg== X-Gm-Message-State: AOAM5324xZsDB3YB2rPIbnRhomdlb5OhVWfCDMewG3H0uQ68o8a3cN0p vf/Ist/10v1/7CGyBrx/pCsPbA== X-Google-Smtp-Source: ABdhPJx7fxzKJEX+6cbR5BoA3Gh4slAr3VWW/An/BhSRSyKn7gGCVTMQetR8BSvZjugCutonwcbv3Q== X-Received: by 2002:a17:903:230b:b0:138:2913:1bc3 with SMTP id d11-20020a170903230b00b0013829131bc3mr2256042plh.44.1631186699692; Thu, 09 Sep 2021 04:24:59 -0700 (PDT) Received: from senozhatsky.flets-east.jp ([2409:10:2e40:5100:166b:dcfc:dcf2:bbe2]) by smtp.gmail.com with ESMTPSA id 141sm2046860pgg.16.2021.09.09.04.24.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 04:24:59 -0700 (PDT) From: Sergey Senozhatsky To: Tomasz Figa , Hans Verkuil Cc: Marek Szyprowski , Dafna Hirschfeld , Ricardo Ribalda , Christoph Hellwig , Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Senozhatsky Subject: [PATCHv6 7/8] videobuf2: handle V4L2_MEMORY_FLAG_NON_COHERENT flag Date: Thu, 9 Sep 2021 20:24:29 +0900 Message-Id: <20210909112430.61243-8-senozhatsky@chromium.org> X-Mailer: git-send-email 2.33.0.153.gba50c8fa24-goog In-Reply-To: <20210909112430.61243-1-senozhatsky@chromium.org> References: <20210909112430.61243-1-senozhatsky@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org This patch lets user-space request a non-coherent memory allocation during CREATE_BUFS and REQBUFS ioctl calls. = CREATE_BUFS struct v4l2_create_buffers has seven 4-byte reserved areas, so reserved[0] is renamed to ->flags. The struct, thus, now has six reserved 4-byte regions. = CREATE_BUFS32 struct v4l2_create_buffers32 has seven 4-byte reserved areas, so reserved[0] is renamed to ->flags. The struct, thus, now has six reserved 4-byte regions. = REQBUFS We use one byte of a 4 byte ->reserved[1] member of struct v4l2_requestbuffers. The struct, thus, now has reserved 3 bytes. Signed-off-by: Sergey Senozhatsky --- .../media/v4l/vidioc-create-bufs.rst | 7 ++++- .../media/v4l/vidioc-reqbufs.rst | 11 ++++--- .../media/common/videobuf2/videobuf2-core.c | 4 +-- .../media/common/videobuf2/videobuf2-v4l2.c | 31 +++++++++++++++++-- drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 9 +++++- drivers/media/v4l2-core/v4l2-ioctl.c | 4 +-- include/uapi/linux/videodev2.h | 9 ++++-- 7 files changed, 60 insertions(+), 15 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/vidioc-create-bufs.rst b/Documentation/userspace-api/media/v4l/vidioc-create-bufs.rst index f98f18c9e91c..a048a9f6b7b6 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-create-bufs.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-create-bufs.rst @@ -113,7 +113,12 @@ than the number requested. ``V4L2_MEMORY_MMAP`` and ``format.type`` to the buffer type. * - __u32 - - ``reserved``\ [7] + - ``flags`` + - Specifies additional buffer management attributes. + See :ref:`memory-flags`. + + * - __u32 + - ``reserved``\ [6] - A place holder for future extensions. Drivers and applications must set the array to zero. diff --git a/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst index e59306aba2b0..099fa6695167 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-reqbufs.rst @@ -104,10 +104,13 @@ aborting or finishing any DMA in progress, an implicit ``V4L2_MEMORY_MMAP`` and ``type`` set to the buffer type. This will free any previously allocated buffers, so this is typically something that will be done at the start of the application. - * - __u32 - - ``reserved``\ [1] - - A place holder for future extensions. Drivers and applications - must set the array to zero. + * - __u8 + - ``flags`` + - Specifies additional buffer management attributes. + See :ref:`memory-flags`. + * - __u8 + - ``reserved``\ [3] + - Reserved for future extensions. .. _v4l2-buf-capabilities: .. _V4L2-BUF-CAP-SUPPORTS-MMAP: diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 60fb43b8f134..2266bbd239ab 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -761,7 +761,7 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, { unsigned int num_buffers, allocated_buffers, num_planes = 0; unsigned plane_sizes[VB2_MAX_PLANES] = { }; - bool non_coherent_mem = false; + bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT; unsigned int i; int ret; @@ -905,7 +905,7 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, { unsigned int num_planes = 0, num_buffers, allocated_buffers; unsigned plane_sizes[VB2_MAX_PLANES] = { }; - bool non_coherent_mem = false; + bool non_coherent_mem = flags & V4L2_MEMORY_FLAG_NON_COHERENT; int ret; if (q->num_buffers == VB2_MAX_FRAME) { diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c b/drivers/media/common/videobuf2/videobuf2-v4l2.c index b4f70ddb09b0..6edf4508c636 100644 --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c @@ -692,12 +692,32 @@ static void fill_buf_caps(struct vb2_queue *q, u32 *caps) #endif } +static void validate_memory_flags(struct vb2_queue *q, + int memory, + u32 *flags) +{ + if (!q->allow_cache_hints || memory != V4L2_MEMORY_MMAP) { + /* + * This needs to clear V4L2_MEMORY_FLAG_NON_COHERENT only, + * but in order to avoid bugs we zero out all bits. + */ + *flags = 0; + } else { + /* Clear all unknown flags. */ + *flags &= V4L2_MEMORY_FLAG_NON_COHERENT; + } +} + int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) { int ret = vb2_verify_memory_type(q, req->memory, req->type); + u32 flags = req->flags; fill_buf_caps(q, &req->capabilities); - return ret ? ret : vb2_core_reqbufs(q, req->memory, 0, &req->count); + validate_memory_flags(q, req->memory, &flags); + req->flags = flags; + return ret ? ret : vb2_core_reqbufs(q, req->memory, + req->flags, &req->count); } EXPORT_SYMBOL_GPL(vb2_reqbufs); @@ -729,6 +749,7 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) unsigned i; fill_buf_caps(q, &create->capabilities); + validate_memory_flags(q, create->memory, &create->flags); create->index = q->num_buffers; if (create->count == 0) return ret != -EBUSY ? ret : 0; @@ -772,7 +793,7 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) if (requested_sizes[i] == 0) return -EINVAL; return ret ? ret : vb2_core_create_bufs(q, create->memory, - 0, + create->flags, &create->count, requested_planes, requested_sizes); @@ -969,13 +990,16 @@ int vb2_ioctl_reqbufs(struct file *file, void *priv, { struct video_device *vdev = video_devdata(file); int res = vb2_verify_memory_type(vdev->queue, p->memory, p->type); + u32 flags = p->flags; fill_buf_caps(vdev->queue, &p->capabilities); + validate_memory_flags(vdev->queue, p->memory, &flags); + p->flags = flags; if (res) return res; if (vb2_queue_is_busy(vdev, file)) return -EBUSY; - res = vb2_core_reqbufs(vdev->queue, p->memory, 0, &p->count); + res = vb2_core_reqbufs(vdev->queue, p->memory, p->flags, &p->count); /* If count == 0, then the owner has released all buffers and he is no longer owner of the queue. Otherwise we have a new owner. */ if (res == 0) @@ -993,6 +1017,7 @@ int vb2_ioctl_create_bufs(struct file *file, void *priv, p->index = vdev->queue->num_buffers; fill_buf_caps(vdev->queue, &p->capabilities); + validate_memory_flags(vdev->queue, p->memory, &p->flags); /* * If count == 0, then just check if memory and type are valid. * Any -EBUSY result from vb2_verify_memory_type can be mapped to 0. diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c index 47aff3b19742..8176769a89fa 100644 --- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c @@ -126,6 +126,9 @@ struct v4l2_format32 { * @memory: buffer memory type * @format: frame format, for which buffers are requested * @capabilities: capabilities of this buffer type. + * @flags: additional buffer management attributes (ignored unless the + * queue has V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS capability and + * configured for MMAP streaming I/O). * @reserved: future extensions */ struct v4l2_create_buffers32 { @@ -134,7 +137,8 @@ struct v4l2_create_buffers32 { __u32 memory; /* enum v4l2_memory */ struct v4l2_format32 format; __u32 capabilities; - __u32 reserved[7]; + __u32 flags; + __u32 reserved[6]; }; static int get_v4l2_format32(struct v4l2_format *p64, @@ -182,6 +186,8 @@ static int get_v4l2_create32(struct v4l2_create_buffers *p64, if (copy_from_user(p64, p32, offsetof(struct v4l2_create_buffers32, format))) return -EFAULT; + if (copy_from_user(&p64->flags, &p32->flags, sizeof(p32->flags))) + return -EFAULT; return get_v4l2_format32(&p64->format, &p32->format); } @@ -227,6 +233,7 @@ static int put_v4l2_create32(struct v4l2_create_buffers *p64, if (copy_to_user(p32, p64, offsetof(struct v4l2_create_buffers32, format)) || put_user(p64->capabilities, &p32->capabilities) || + put_user(p64->flags, &p32->flags) || copy_to_user(p32->reserved, p64->reserved, sizeof(p64->reserved))) return -EFAULT; return put_v4l2_format32(&p64->format, &p32->format); diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c index d4f97ab1b237..842ad84490ca 100644 --- a/drivers/media/v4l2-core/v4l2-ioctl.c +++ b/drivers/media/v4l2-core/v4l2-ioctl.c @@ -2006,7 +2006,7 @@ static int v4l_reqbufs(const struct v4l2_ioctl_ops *ops, if (ret) return ret; - CLEAR_AFTER_FIELD(p, capabilities); + CLEAR_AFTER_FIELD(p, flags); return ops->vidioc_reqbufs(file, fh, p); } @@ -2047,7 +2047,7 @@ static int v4l_create_bufs(const struct v4l2_ioctl_ops *ops, if (ret) return ret; - CLEAR_AFTER_FIELD(create, capabilities); + CLEAR_AFTER_FIELD(create, flags); v4l_sanitize_format(&create->format); diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 9b7032abb2c7..f118fe7a9f58 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -959,7 +959,8 @@ struct v4l2_requestbuffers { __u32 type; /* enum v4l2_buf_type */ __u32 memory; /* enum v4l2_memory */ __u32 capabilities; - __u32 reserved[1]; + __u8 flags; + __u8 reserved[3]; }; #define V4L2_MEMORY_FLAG_NON_COHERENT (1 << 0) @@ -2507,6 +2508,9 @@ struct v4l2_dbg_chip_info { * @memory: enum v4l2_memory; buffer memory type * @format: frame format, for which buffers are requested * @capabilities: capabilities of this buffer type. + * @flags: additional buffer management attributes (ignored unless the + * queue has V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS capability + * and configured for MMAP streaming I/O). * @reserved: future extensions */ struct v4l2_create_buffers { @@ -2515,7 +2519,8 @@ struct v4l2_create_buffers { __u32 memory; struct v4l2_format format; __u32 capabilities; - __u32 reserved[7]; + __u32 flags; + __u32 reserved[6]; }; /* From patchwork Thu Sep 9 11:24:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Senozhatsky X-Patchwork-Id: 12482949 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D7B2C4332F for ; Thu, 9 Sep 2021 11:25:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 36ABE611CE for ; Thu, 9 Sep 2021 11:25:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236231AbhIIL0Q (ORCPT ); Thu, 9 Sep 2021 07:26:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60566 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235985AbhIIL0M (ORCPT ); Thu, 9 Sep 2021 07:26:12 -0400 Received: from mail-pj1-x102a.google.com (mail-pj1-x102a.google.com [IPv6:2607:f8b0:4864:20::102a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2F671C0617AE for ; Thu, 9 Sep 2021 04:25:03 -0700 (PDT) Received: by mail-pj1-x102a.google.com with SMTP id n13-20020a17090a4e0d00b0017946980d8dso1198031pjh.5 for ; Thu, 09 Sep 2021 04:25:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=63y+Nvbu3ZhbvvsHZ5iki7ccOe2n+6icYzDmluSM4VA=; b=jPGT+14bKZaoYAHz/5KtHy7p1uKq7L3S7XucQ9PPI58jmS5DlmENtRfTnvVWaJOlbc 7XiZzv/BMTMw604tg/13yAnuFHf61gcr85GoloFYw+67QMSvfCnpBtY1gJ41lLHHI+wH oxYtZihqvxpmyVN8pBlzznbIROa/2ye+cg0NE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=63y+Nvbu3ZhbvvsHZ5iki7ccOe2n+6icYzDmluSM4VA=; b=R50oZWREGtkz5vpCNjmJcUO65Q/mLvoUAlIONkDVe7AxY8lz1YbZWSGJ7ZuBhYvtHq LEVrb9gQUIL9wRLNTmzMvmdKQ4bRoqo3jPacOSVIEZ+lfImD+BtJtN74ij0eTAKKn0el BHiwa6Dyt4nbtUUOchxTluweJBg/SBqDOtFXCsLhADggvJ6c3dkTiUjQ5Wx0FvqInFmB 4vbHuOn0pRb5ZS7E99QfZO9lXJ4BrMRin9J9XUwc/xk2cufRXoMGAnb3F1yb83RgCxaZ eF78iPLD77mx3YMP/w2tXdFIjJgqvhHVQPCm7Vmi/xz9g9WMncC/MwMTlOqzO+EyY0ka TCkQ== X-Gm-Message-State: AOAM533wAeafg0zP9EfWW92XyzvTw5GCQzehp02OGAEjnVVpsI962soS Jt9CEsbTTXY8H5Pf7KO14r0bMA== X-Google-Smtp-Source: ABdhPJw/fuN/2PZfis/IeehsuU+UapJHLB9IMty8UK5u7t+g63TV8DOPkeJVLYGYIWExlQY/MtqguQ== X-Received: by 2002:a17:902:9346:b0:132:6ba5:109 with SMTP id g6-20020a170902934600b001326ba50109mr2251585plp.19.1631186702682; Thu, 09 Sep 2021 04:25:02 -0700 (PDT) Received: from senozhatsky.flets-east.jp ([2409:10:2e40:5100:166b:dcfc:dcf2:bbe2]) by smtp.gmail.com with ESMTPSA id 141sm2046860pgg.16.2021.09.09.04.24.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Sep 2021 04:25:02 -0700 (PDT) From: Sergey Senozhatsky To: Tomasz Figa , Hans Verkuil Cc: Marek Szyprowski , Dafna Hirschfeld , Ricardo Ribalda , Christoph Hellwig , Mauro Carvalho Chehab , linux-media@vger.kernel.org, linux-kernel@vger.kernel.org, Sergey Senozhatsky Subject: [PATCHv6 8/8] videobuf2: handle non-contiguous DMA allocations Date: Thu, 9 Sep 2021 20:24:30 +0900 Message-Id: <20210909112430.61243-9-senozhatsky@chromium.org> X-Mailer: git-send-email 2.33.0.153.gba50c8fa24-goog In-Reply-To: <20210909112430.61243-1-senozhatsky@chromium.org> References: <20210909112430.61243-1-senozhatsky@chromium.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org This adds support for the new noncontiguous DMA API, which requires allocators to have two execution branches: one for the current API, and one for the new one. Signed-off-by: Sergey Senozhatsky Acked-by: Christoph Hellwig --- .../common/videobuf2/videobuf2-dma-contig.c | 161 ++++++++++++++---- 1 file changed, 130 insertions(+), 31 deletions(-) diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index 1e218bc440c6..b052a4e36961 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,7 @@ struct vb2_dc_buf { struct dma_buf_attachment *db_attach; struct vb2_buffer *vb; + bool non_coherent_mem; }; /*********************************************/ @@ -75,17 +77,39 @@ static void *vb2_dc_cookie(struct vb2_buffer *vb, void *buf_priv) return &buf->dma_addr; } +/* + * This function may fail if: + * + * - dma_buf_vmap() fails + * E.g. due to lack of virtual mapping address space, or due to + * dmabuf->ops misconfiguration. + * + * - dma_vmap_noncontiguous() fails + * For instance, when requested buffer size is larger than totalram_pages(). + * Relevant for buffers that use non-coherent memory. + * + * - Queue DMA attrs have DMA_ATTR_NO_KERNEL_MAPPING set + * Relevant for buffers that use coherent memory. + */ static void *vb2_dc_vaddr(struct vb2_buffer *vb, void *buf_priv) { struct vb2_dc_buf *buf = buf_priv; - struct dma_buf_map map; - int ret; - if (!buf->vaddr && buf->db_attach) { - ret = dma_buf_vmap(buf->db_attach->dmabuf, &map); - buf->vaddr = ret ? NULL : map.vaddr; + if (buf->vaddr) + return buf->vaddr; + + if (buf->db_attach) { + struct dma_buf_map map; + + if (!dma_buf_vmap(buf->db_attach->dmabuf, &map)) + buf->vaddr = map.vaddr; + + return buf->vaddr; } + if (buf->non_coherent_mem) + buf->vaddr = dma_vmap_noncontiguous(buf->dev, buf->size, + buf->dma_sgt); return buf->vaddr; } @@ -101,13 +125,19 @@ static void vb2_dc_prepare(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; + /* This takes care of DMABUF and user-enforced cache sync hint */ if (buf->vb->skip_cache_sync_on_prepare) return; - if (!sgt) + if (!buf->non_coherent_mem) return; + /* For both USERPTR and non-coherent MMAP */ dma_sync_sgtable_for_device(buf->dev, sgt, buf->dma_dir); + + /* Non-coherent MMAP only */ + if (buf->vaddr) + flush_kernel_vmap_range(buf->vaddr, buf->size); } static void vb2_dc_finish(void *buf_priv) @@ -115,13 +145,19 @@ static void vb2_dc_finish(void *buf_priv) struct vb2_dc_buf *buf = buf_priv; struct sg_table *sgt = buf->dma_sgt; + /* This takes care of DMABUF and user-enforced cache sync hint */ if (buf->vb->skip_cache_sync_on_finish) return; - if (!sgt) + if (!buf->non_coherent_mem) return; + /* For both USERPTR and non-coherent MMAP */ dma_sync_sgtable_for_cpu(buf->dev, sgt, buf->dma_dir); + + /* Non-coherent MMAP only */ + if (buf->vaddr) + invalidate_kernel_vmap_range(buf->vaddr, buf->size); } /*********************************************/ @@ -135,21 +171,69 @@ static void vb2_dc_put(void *buf_priv) if (!refcount_dec_and_test(&buf->refcount)) return; - if (buf->sgt_base) { - sg_free_table(buf->sgt_base); - kfree(buf->sgt_base); + if (buf->non_coherent_mem) { + if (buf->vaddr) + dma_vunmap_noncontiguous(buf->dev, buf->vaddr); + dma_free_noncontiguous(buf->dev, buf->size, + buf->dma_sgt, buf->dma_dir); + } else { + if (buf->sgt_base) { + sg_free_table(buf->sgt_base); + kfree(buf->sgt_base); + } + dma_free_attrs(buf->dev, buf->size, buf->cookie, + buf->dma_addr, buf->attrs); } - dma_free_attrs(buf->dev, buf->size, buf->cookie, buf->dma_addr, - buf->attrs); put_device(buf->dev); kfree(buf); } +static int vb2_dc_alloc_coherent(struct vb2_dc_buf *buf) +{ + struct vb2_queue *q = buf->vb->vb2_queue; + + buf->cookie = dma_alloc_attrs(buf->dev, + buf->size, + &buf->dma_addr, + GFP_KERNEL | q->gfp_flags, + buf->attrs); + if (!buf->cookie) + return -ENOMEM; + + if (q->dma_attrs & DMA_ATTR_NO_KERNEL_MAPPING) + return 0; + + buf->vaddr = buf->cookie; + return 0; +} + +static int vb2_dc_alloc_non_coherent(struct vb2_dc_buf *buf) +{ + struct vb2_queue *q = buf->vb->vb2_queue; + + buf->dma_sgt = dma_alloc_noncontiguous(buf->dev, + buf->size, + buf->dma_dir, + GFP_KERNEL | q->gfp_flags, + buf->attrs); + if (!buf->dma_sgt) + return -ENOMEM; + + buf->dma_addr = sg_dma_address(buf->dma_sgt->sgl); + + /* + * For non-coherent buffers the kernel mapping is created on demand + * in vb2_dc_vaddr(). + */ + return 0; +} + static void *vb2_dc_alloc(struct vb2_buffer *vb, struct device *dev, unsigned long size) { struct vb2_dc_buf *buf; + int ret; if (WARN_ON(!dev)) return ERR_PTR(-EINVAL); @@ -159,27 +243,28 @@ static void *vb2_dc_alloc(struct vb2_buffer *vb, return ERR_PTR(-ENOMEM); buf->attrs = vb->vb2_queue->dma_attrs; - buf->cookie = dma_alloc_attrs(dev, size, &buf->dma_addr, - GFP_KERNEL | vb->vb2_queue->gfp_flags, - buf->attrs); - if (!buf->cookie) { - dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); - kfree(buf); - return ERR_PTR(-ENOMEM); - } - - if ((buf->attrs & DMA_ATTR_NO_KERNEL_MAPPING) == 0) - buf->vaddr = buf->cookie; + buf->dma_dir = vb->vb2_queue->dma_dir; + buf->vb = vb; + buf->non_coherent_mem = vb->vb2_queue->non_coherent_mem; + buf->size = size; /* Prevent the device from being released while the buffer is used */ buf->dev = get_device(dev); - buf->size = size; - buf->dma_dir = vb->vb2_queue->dma_dir; + + if (buf->non_coherent_mem) + ret = vb2_dc_alloc_non_coherent(buf); + else + ret = vb2_dc_alloc_coherent(buf); + + if (ret) { + dev_err(dev, "dma alloc of size %ld failed\n", size); + kfree(buf); + return ERR_PTR(-ENOMEM); + } buf->handler.refcount = &buf->refcount; buf->handler.put = vb2_dc_put; buf->handler.arg = buf; - buf->vb = vb; refcount_set(&buf->refcount, 1); @@ -196,9 +281,12 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) return -EINVAL; } - ret = dma_mmap_attrs(buf->dev, vma, buf->cookie, - buf->dma_addr, buf->size, buf->attrs); - + if (buf->non_coherent_mem) + ret = dma_mmap_noncontiguous(buf->dev, vma, buf->size, + buf->dma_sgt); + else + ret = dma_mmap_attrs(buf->dev, vma, buf->cookie, buf->dma_addr, + buf->size, buf->attrs); if (ret) { pr_err("Remapping memory failed, error: %d\n", ret); return ret; @@ -360,9 +448,15 @@ vb2_dc_dmabuf_ops_end_cpu_access(struct dma_buf *dbuf, static int vb2_dc_dmabuf_ops_vmap(struct dma_buf *dbuf, struct dma_buf_map *map) { - struct vb2_dc_buf *buf = dbuf->priv; + struct vb2_dc_buf *buf; + void *vaddr; - dma_buf_map_set_vaddr(map, buf->vaddr); + buf = dbuf->priv; + vaddr = vb2_dc_vaddr(buf->vb, buf); + if (!vaddr) + return -EINVAL; + + dma_buf_map_set_vaddr(map, vaddr); return 0; } @@ -390,6 +484,9 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf) int ret; struct sg_table *sgt; + if (buf->non_coherent_mem) + return buf->dma_sgt; + sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); if (!sgt) { dev_err(buf->dev, "failed to alloc sg table\n"); @@ -567,6 +664,8 @@ static void *vb2_dc_get_userptr(struct vb2_buffer *vb, struct device *dev, buf->dma_addr = sg_dma_address(sgt->sgl); buf->dma_sgt = sgt; + buf->non_coherent_mem = 1; + out: buf->size = size;