Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp1330959pxf; Fri, 26 Mar 2021 06:05:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwwRvQoerYiF7fRzyPj6m/uSoswGUqqwqBifTlbmtZaQ6Utkd0h9ZFadxrgu3ZcoVYsQfXi X-Received: by 2002:aa7:c88e:: with SMTP id p14mr14702771eds.119.1616763953182; Fri, 26 Mar 2021 06:05:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616763953; cv=none; d=google.com; s=arc-20160816; b=cC3k1QsY/ymRQPpIYWAG4dxJdJIeTlTFeJxl3ihE4NohGRHgKO1ys3tHOVGGUilYqR 8VAsubJOyD6H0VQSVb/EtcfgRo91YK7/ESZgCkuRgztvwbsJQhzoq1B6FX8l4DBB4slJ kALvy3+RDbOjfrd9oS/tbaSc5l0bV0buk3B8RPXRiUV2Q2eJonTB4thUYnJDxjXGetfS zFjp/cK7J1ybPOi8+0PDVrK06O0ICPTbF0K3rj0D6j288/+sZdZF2fA25dGlZCsFJYfL 1GzVkUjzLnfErvq7O38deQGFGMcADT3i6LSX8E9DPD0Pb8fka/YMhS4uyQhInB98rKeE oqqg== 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 :user-agent:in-reply-to:references:message-id:date:subject:cc:to :from:dkim-signature; bh=pnByEdP+F8ySISIiRZhvGyObOtY7yMK7CtOka9IyJso=; b=cpqecWnBnSJ9vwACUF0hgc2MbtE8d9RKoCRsaA2v/bNFdn9oQboibdn375P4B3rmuH 8FkkEIe4gatfUm4dFZ7yKgX3GJIjXb8XIIH9vEYPawbss1+NEg7rTic+r/TU+ANQPV+2 4KLwmT70UwVahq1phM7UEaYNdTgz027F76S/4wVfIV875cX4aK30zR2d5TaZAICZcjVS LicRI2zLGMXfmb4QhXlea2SWXaim99QJnidpj3g1J5rmtRtRmQvl7Kx+M2ehi5ixlCLT KZ4Lc7zmFHEneAFmKlNnxocJf8CFbejs/6psVFE2rXCEY7i2SV9nsWUZi88Ehj4pDRoh l5sw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kynesim-co-uk.20150623.gappssmtp.com header.s=20150623 header.b=KFAboZN1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id t8si6769476edw.476.2021.03.26.06.05.29; Fri, 26 Mar 2021 06:05:53 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kynesim-co-uk.20150623.gappssmtp.com header.s=20150623 header.b=KFAboZN1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230057AbhCZNDw (ORCPT + 99 others); Fri, 26 Mar 2021 09:03:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33000 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230001AbhCZNDn (ORCPT ); Fri, 26 Mar 2021 09:03:43 -0400 Received: from mail-wm1-x32b.google.com (mail-wm1-x32b.google.com [IPv6:2a00:1450:4864:20::32b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0D94C0613B1 for ; Fri, 26 Mar 2021 06:03:42 -0700 (PDT) Received: by mail-wm1-x32b.google.com with SMTP id f22-20020a7bc8d60000b029010c024a1407so4886998wml.2 for ; Fri, 26 Mar 2021 06:03:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kynesim-co-uk.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:references:in-reply-to :user-agent:mime-version:content-transfer-encoding; bh=pnByEdP+F8ySISIiRZhvGyObOtY7yMK7CtOka9IyJso=; b=KFAboZN11OkLz2V2hb/BTp9pvQXtrkzQxmK3SrMsj1dzqindmlpSP51YqSQWREGGd8 gFy1LgWC4uX8xuPIpGIas8iFsfUzoOrTPn8BFc72Dc+RmvSC69xxPmRSbLqSPSlaNRQ1 V/YCMLbLSww4Q80k/DV269X2LqE+NIWqAgI0oHkntTcOhaQvSe55N3gCqBRYf87jI/2K PrXOXP0wo+weHiTlYs3fpvpIrDn1zZNS5eMT9LgEAFCi48k9uTxeRSL4xp4ygED9Oq5w GqdDzK9k3VhTuAaRWrxuk8mwS5p8ekC4azkq3JY/7Ib6msK0VVOtu1s872ZEcYEvTKpS 1ktw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:references :in-reply-to:user-agent:mime-version:content-transfer-encoding; bh=pnByEdP+F8ySISIiRZhvGyObOtY7yMK7CtOka9IyJso=; b=I3lWLGJZgML13hp7aII8rp1uaIzppUqLbewtv/WDnP1398y3+EnJhfjW+qzcHjBExT G2qlcBlc1KPPON1+DAvcpFQCgvgszTv0JSZTrrzh/cpWu7oEAA47ZOd9iCXaLvygdMp7 CNanodOZwyqSB67m/ZfJwlg/TnXrDjWSy7Kp4aN675v2X/XfQxk176AQVT/qmriwTf8a 6gN5XLZWqcl6q6WjrMYY0Ro43p1DW0JsQ7oI2xD1MqnD+s9DIPKaD2kplZf6S3fzEUyP cpIenLRI2Z+5Ua84b5aKfNm/DxKK4bwSfmkoyjL4aiugmmIPopVklZVkxEu79MfKiHLB vBog== X-Gm-Message-State: AOAM530idDmtWlBStvXTM2l2cf+xF6SJQp9ZB4J/DUYnKK74E4hFhPdg tDwh6I95LEDLDgUuUudRnrAmOw== X-Received: by 2002:a7b:ce16:: with SMTP id m22mr13319120wmc.65.1616763820853; Fri, 26 Mar 2021 06:03:40 -0700 (PDT) Received: from CTHALPA.outer.uphall.net (cpc1-cmbg20-2-0-cust759.5-4.cable.virginm.net. [86.21.218.248]) by smtp.gmail.com with ESMTPSA id t20sm11312759wmi.15.2021.03.26.06.03.39 (version=TLS1 cipher=ECDHE-ECDSA-AES128-SHA bits=128/128); Fri, 26 Mar 2021 06:03:40 -0700 (PDT) From: John Cox To: Helen Koike Cc: linux-media@vger.kernel.org, hverkuil@xs4all.nl, kernel@collabora.com, linux-kernel@vger.kernel.org, laurent.pinchart@ideasonboard.com, dave.stevenson@raspberrypi.org, tfiga@chromium.org Subject: Re: [PATCH 1/2] media: videobuf2: use dmabuf size for length Date: Fri, 26 Mar 2021 13:03:39 +0000 Message-ID: <8omr5gd5r4qm7d9l6l5grhlgj3c2h7di88@4ax.com> References: <20210325001712.197837-1-helen.koike@collabora.com> In-Reply-To: User-Agent: ForteAgent/8.00.32.1272 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Helen >Hi John, > >On 3/25/21 7:20 AM, John Cox wrote: >> Hi >>=20 >>> Always use dmabuf size when considering the length of the buffer. >>> Discard userspace provided length. >>> Fix length check error in _verify_length(), which was handling single= and >>> multiplanar diferently, and also not catching the case where = userspace >>> provides a bigger length and bytesused then the underlying buffer. >>> >>> Suggested-by: Hans Verkuil >>> Signed-off-by: Helen Koike >>> --- >>> >>> Hello, >>> >>> As discussed on >>> = https://patchwork.linuxtv.org/project/linux-media/patch/gh5kef5bkeel3o6b2= dkgc2dfagu9klj4c0@4ax.com/ >>> >>> This patch also helps the conversion layer of the Ext API patchset, >>> where we are not exposing the length field. >>> >>> It was discussed that userspace might use a smaller length field to >>> limit the usage of the underlying buffer, but I'm not sure if this is >>> really usefull and just complicates things. >>> >>> If this is usefull, then we should also expose a length field in the = Ext >>> API, and document this feature properly. >>> >>> What do you think? >>> --- >>> .../media/common/videobuf2/videobuf2-core.c | 21 = ++++++++++++++++--- >>> .../media/common/videobuf2/videobuf2-v4l2.c | 8 +++---- >>> include/uapi/linux/videodev2.h | 7 +++++-- >>> 3 files changed, 27 insertions(+), 9 deletions(-) >>> >>> diff --git a/drivers/media/common/videobuf2/videobuf2-core.c = b/drivers/media/common/videobuf2/videobuf2-core.c >>> index 02281d13505f..2cbde14af051 100644 >>> --- a/drivers/media/common/videobuf2/videobuf2-core.c >>> +++ b/drivers/media/common/videobuf2/videobuf2-core.c >>> @@ -1205,6 +1205,7 @@ static int __prepare_dmabuf(struct vb2_buffer = *vb) >>> >>> for (plane =3D 0; plane < vb->num_planes; ++plane) { >>> struct dma_buf *dbuf =3D dma_buf_get(planes[plane].m.fd); >>> + unsigned int bytesused; >>> >>> if (IS_ERR_OR_NULL(dbuf)) { >>> dprintk(q, 1, "invalid dmabuf fd for plane %d\n", >>> @@ -1213,9 +1214,23 @@ static int __prepare_dmabuf(struct vb2_buffer = *vb) >>> goto err; >>> } >>> >>> - /* use DMABUF size if length is not provided */ >>> - if (planes[plane].length =3D=3D 0) >>> - planes[plane].length =3D dbuf->size; >>> + planes[plane].length =3D dbuf->size; >>> + bytesused =3D planes[plane].bytesused ? >>> + planes[plane].bytesused : dbuf->size; >>> + >>> + if (planes[plane].bytesused > planes[plane].length) { >>> + dprintk(q, 1, "bytesused is bigger then dmabuf length for plane = %d\n", >>> + plane); >>> + ret =3D -EINVAL; >>> + goto err; >>> + } >>> + >>> + if (planes[plane].data_offset >=3D bytesused) { >>> + dprintk(q, 1, "data_offset >=3D bytesused for plane %d\n", >>> + plane); >>> + ret =3D -EINVAL; >>> + goto err; >>> + } >>> >>> if (planes[plane].length < vb->planes[plane].min_length) { >>> dprintk(q, 1, "invalid dmabuf length %u for plane %d, minimum = length %u\n", >>> diff --git a/drivers/media/common/videobuf2/videobuf2-v4l2.c = b/drivers/media/common/videobuf2/videobuf2-v4l2.c >>> index 7e96f67c60ba..ffc7ed46f74a 100644 >>> --- a/drivers/media/common/videobuf2/videobuf2-v4l2.c >>> +++ b/drivers/media/common/videobuf2/videobuf2-v4l2.c >>> @@ -98,14 +98,14 @@ static int __verify_length(struct vb2_buffer *vb,= const struct v4l2_buffer *b) >>> unsigned int bytesused; >>> unsigned int plane; >>> >>> - if (V4L2_TYPE_IS_CAPTURE(b->type)) >>> + /* length check for dmabuf is performed in _prepare_dmabuf() */ >>> + if (V4L2_TYPE_IS_CAPTURE(b->type) || b->memory =3D=3D = VB2_MEMORY_DMABUF) >>> return 0; >>> >>> if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) { >>> for (plane =3D 0; plane < vb->num_planes; ++plane) { >>> - length =3D (b->memory =3D=3D VB2_MEMORY_USERPTR || >>> - b->memory =3D=3D VB2_MEMORY_DMABUF) >>> - ? b->m.planes[plane].length >>> + length =3D b->memory =3D=3D VB2_MEMORY_USERPTR >>> + ? b->m.planes[plane].length >>> : vb->planes[plane].length; >>> bytesused =3D b->m.planes[plane].bytesused >>> ? b->m.planes[plane].bytesused : length; >>> diff --git a/include/uapi/linux/videodev2.h = b/include/uapi/linux/videodev2.h >>> index 8d15f6ccc4b4..79b3b2893513 100644 >>> --- a/include/uapi/linux/videodev2.h >>> +++ b/include/uapi/linux/videodev2.h >>> @@ -968,7 +968,9 @@ struct v4l2_requestbuffers { >>> /** >>> * struct v4l2_plane - plane info for multi-planar buffers >>> * @bytesused: number of bytes occupied by data in the plane = (payload) >>> - * @length: size of this plane (NOT the payload) in bytes >>> + * @length: size of this plane (NOT the payload) in bytes. Filled >>> + * by userspace for USERPTR and by the driver for DMABUF >>> + * and MMAP. >>> * @mem_offset: when memory in the associated struct v4l2_buffer is >>> * V4L2_MEMORY_MMAP, equals the offset from the start of >>> * the device memory for this plane (or is a "cookie" that >>> @@ -1025,7 +1027,8 @@ struct v4l2_plane { >>> * @m: union of @offset, @userptr, @planes and @fd >>> * @length: size in bytes of the buffer (NOT its payload) for = single-plane >>> * buffers (when type !=3D *_MPLANE); number of elements in the >>> - * planes array for multi-plane buffers >>> + * planes array for multi-plane buffers. Filled by userspace for >>> + * USERPTR and by the driver for DMABUF and MMAP. >>> * @reserved2: drivers and applications must zero this field >>> * @request_fd: fd of the request that this buffer should use >>> * @reserved: for backwards compatibility with applications that do = not know >>=20 >> I think this does what I want. But I'm going to restate my usage = desires >> and check that you agree that it covers them. >>=20 >> I'm interested in passing compressed bitstreams to a decoder. The = size >> of these buffers can be very variable and the worst case will nearly >> always be much larger than the typical case and that size cannot be >> known in advance of usage. It can be very wasteful to have to = allocate >> buffers that are over an order of magnitude bigger than are likely to >> ever be used. If you have a fixed pool of fixed size buffers = allocated >> at the start of time this wastefulness is unavoidable, but dmabufs can >> be dynamically sized to be as big as required and so there should be = no >> limitation on passing in buffers that are smaller than the maximum. = It > >Do you mean that the kernel should re-allocate the buffer dynamically >without userspace intervention? >I'm not entirely sure if this would be possible. No - I didn't mean that at all. Any reallocation would be done by the user. I was just setting out why damabufs are different from (and more useful than) MMAP buffers for bitstream-like purposes. Regards John Cox >Regards, >Helen > > >> also seems plausible that dmabufs that are larger than the maximum >> should be allowed as long as their bytesused is smaller or equal. >>=20 >> As an aside, even when using dynamically sized dmabufs they are often >> way larger than the data they contain and forcing cache flushes or = maps >> of their entire length rather than just the used portion is also >> wasteful. This might be a use for the incoming size field. >>=20 >> Regards >>=20 >> John Cox >>=20