Received: by 2002:a05:6358:f14:b0:e5:3b68:ec04 with SMTP id b20csp5026593rwj; Tue, 20 Dec 2022 19:16:25 -0800 (PST) X-Google-Smtp-Source: AMrXdXua7tju874hhhkrBiidz9sLWZgPMppxU1HPnNUn8uZN/hw7yZ6EAPGlYXEQnaoLTnSNVDzH X-Received: by 2002:a17:906:7ad8:b0:7c0:d1cb:2165 with SMTP id k24-20020a1709067ad800b007c0d1cb2165mr3902271ejo.56.1671592585676; Tue, 20 Dec 2022 19:16:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1671592585; cv=none; d=google.com; s=arc-20160816; b=swxbpKJp3E7C2NspB632mv130a9yNWxkJdbw1p2x0dGi43hXACJS7GbYgx2jCoUcpg Fixs1VmGxcEXMlP1ewZKvZFRSPAA+S6qAHEcWQOChGH8ATXrDF2cL3LDBnYq6Dl1hXi3 KGfx4dS/HNiv4qHc1nuWx8BrgREMaEq1AlQrc85cZP1ePztrFD008ujMCv/F6sC6u/HW TEqb21qzx9V35MXMUjXLnTnJdmImQPaqa4W9Q6B0voeAfz3GvVVp/lZo9UvNIsJgGPdI DEgqAkD/aMttGQiUCrHighpU2Qq6RhiT4mgWhEXurIy3mgYxhtGbJHayPwJIwXH5HUGy mZkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date; bh=LtTbxtPKRa8rdeVvzhw1SsuUS6zeGkjffIP/ol7QooI=; b=MA7tFuybxFgwVQqWQCAx+UBtj33aa+3EHeTZQqFzBbSlnl4AzEfJOowL6QW/dfk+Lk 1i04ZgwDmYB4e2P98BuP1UGPgxcfBb8wJHCwYL8XEykSOJOChEW9/xT/hjU6XH1jPZdp HFCl/hzDewrIimw0Af1hVod+oFrIY4oyuYG/68DgJ91++/1chEja0sCGp2sbBJDDUpEw Wd9vJRHbnV/HmIRwZFo8apXUF8in5y3Fn+lHgN/PKnUokSDPRUD35hM/7Xilh/wp3nRK q+sOuA2cD8sHhCw9+8AffwDZI5C+/LZkDIxEZUVM6nHwpiMfUDxfpGpbXswaWZBEKbw/ aTYQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e19-20020a17090658d300b0078d805901b1si3694693ejs.489.2022.12.20.19.16.09; Tue, 20 Dec 2022 19:16:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234268AbiLUCrc (ORCPT + 69 others); Tue, 20 Dec 2022 21:47:32 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234186AbiLUCra (ORCPT ); Tue, 20 Dec 2022 21:47:30 -0500 Received: from netrider.rowland.org (netrider.rowland.org [192.131.102.5]) by lindbergh.monkeyblade.net (Postfix) with SMTP id D9DD11D0EC for ; Tue, 20 Dec 2022 18:47:28 -0800 (PST) Received: (qmail 75129 invoked by uid 1000); 20 Dec 2022 21:47:28 -0500 Date: Tue, 20 Dec 2022 21:47:28 -0500 From: Alan Stern To: Ricardo Ribalda Cc: Christoph Hellwig , Greg Kroah-Hartman , Laurent Pinchart , Randy Dunlap , linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v2] USB: Improve usb_fill_* documentation Message-ID: References: <20221220-usb-dmadoc-v2-0-4dd4f198113e@chromium.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20221220-usb-dmadoc-v2-0-4dd4f198113e@chromium.org> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Dec 21, 2022 at 12:13:08AM +0100, Ricardo Ribalda wrote: > Make the developer aware of the requirements of transfer buffer. > > The buffer must be DMAble, if the developer uses an invalid buffer, data > corruption might happen. > > Signed-off-by: Ricardo Ribalda > --- > USB: Improve usb_fill_* documentation > > After trying to "cleanup" the uvc code, I was patiently explained about > the requirements of the urb transfer buffers. > > Lets make this explicit, so other developers do not make the same mistake. > > To: Randy Dunlap > To: Alan Stern > To: Christoph Hellwig > To: Laurent Pinchart > To: Greg Kroah-Hartman > Cc: linux-usb@vger.kernel.org > Cc: linux-kernel@vger.kernel.org > --- > Changes in v2: > - s/allocatiing/allocating/ Thanks Randy > - Link to v1: https://lore.kernel.org/r/20221220-usb-dmadoc-v1-0-28386d2eb6cd@chromium.org > --- > include/linux/usb.h | 27 ++++++++++++++++++++++++--- > 1 file changed, 24 insertions(+), 3 deletions(-) > > diff --git a/include/linux/usb.h b/include/linux/usb.h > index 7d5325d47c45..1144ef6e4151 100644 > --- a/include/linux/usb.h > +++ b/include/linux/usb.h > @@ -1627,13 +1627,20 @@ struct urb { > * @dev: pointer to the struct usb_device for this urb. > * @pipe: the endpoint pipe > * @setup_packet: pointer to the setup_packet buffer > - * @transfer_buffer: pointer to the transfer buffer > + * @transfer_buffer: pointer to the transfer buffer. Must be suitable for DMA. For control URBs, the setup_packet must also be suitable for DMA. It's a little less critical, though, because the setup_packet is only used for DMA out, never DMA in. > * @buffer_length: length of the transfer buffer > * @complete_fn: pointer to the usb_complete_t function > * @context: what to set the urb context to. > * > * Initializes a control urb with the proper information needed to submit > * it to a device. > + * > + * The transfer buffer might be filled via DMA. "might" is too weak. For nonzero-length IN transfers, the transfer buffer is certain to be filled via DMA (except for the very few cases of USB controller hardware using PIO instead of DMA). > The simplest way to get > + * a buffer that can be DMAed to, is allocating it via kmalloc() or > + * equivalent, even for very small buffers. If transfer_buffer is embedded > + * in a bigger structure, there is a risk that the previous and following > + * fields are left in a corrupted state by the DMA engine, if the platform > + * is not cache coherent. There is also a risk that data read from the device is corrupted. And accesses of the surrounding fields may well be slowed down because the DMA mapping evicts them from the cache. > */ > static inline void usb_fill_control_urb(struct urb *urb, > struct usb_device *dev, > @@ -1658,13 +1665,20 @@ static inline void usb_fill_control_urb(struct urb *urb, > * @urb: pointer to the urb to initialize. > * @dev: pointer to the struct usb_device for this urb. > * @pipe: the endpoint pipe > - * @transfer_buffer: pointer to the transfer buffer > + * @transfer_buffer: pointer to the transfer buffer. Must be suitable for DMA. > * @buffer_length: length of the transfer buffer > * @complete_fn: pointer to the usb_complete_t function > * @context: what to set the urb context to. > * > * Initializes a bulk urb with the proper information needed to submit it > * to a device. > + * > + * The transfer buffer might be filled via DMA. The simplest way to get > + * a buffer that can be DMAed to, is allocating it via kmalloc() or > + * equivalent, even for very small buffers. If transfer_buffer is embedded > + * in a bigger structure, there is a risk that the previous and following > + * fields are left in a corrupted state by the DMA engine, if the platform > + * is not cache coherent. I see no point in repeating exactly the same text multiple times. Instead, just put a reference to the original occurrence of this warning. Alan Stern > */ > static inline void usb_fill_bulk_urb(struct urb *urb, > struct usb_device *dev, > @@ -1687,7 +1701,7 @@ static inline void usb_fill_bulk_urb(struct urb *urb, > * @urb: pointer to the urb to initialize. > * @dev: pointer to the struct usb_device for this urb. > * @pipe: the endpoint pipe > - * @transfer_buffer: pointer to the transfer buffer > + * @transfer_buffer: pointer to the transfer buffer. Must be suitable for DMA. > * @buffer_length: length of the transfer buffer > * @complete_fn: pointer to the usb_complete_t function > * @context: what to set the urb context to. > @@ -1697,6 +1711,13 @@ static inline void usb_fill_bulk_urb(struct urb *urb, > * Initializes a interrupt urb with the proper information needed to submit > * it to a device. > * > + * The transfer buffer might be filled via DMA. The simplest way to get > + * a buffer that can be DMAed to, is allocating it via kmalloc() or > + * equivalent, even for very small buffers. If transfer_buffer is embedded > + * in a bigger structure, there is a risk that the previous and following > + * fields are left in a corrupted state by the DMA engine, if the platform > + * is not cache coherent. > + * > * Note that High Speed and SuperSpeed(+) interrupt endpoints use a logarithmic > * encoding of the endpoint interval, and express polling intervals in > * microframes (eight per millisecond) rather than in frames (one per > > --- > base-commit: b6bb9676f2165d518b35ba3bea5f1fcfc0d969bf > change-id: 20221220-usb-dmadoc-29384acebd48 > > Best regards, > -- > Ricardo Ribalda