All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thierry Reding <thierry.reding@gmail.com>
To: "Michał Mirosław" <mirq-linux@rere.qmqm.pl>
Cc: Peter Geis <pgwipeout@gmail.com>,
	Dmitry Osipenko <digetx@gmail.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Peter Chen <peter.chen@kernel.org>,
	Thierry Reding <treding@nvidia.com>,
	linux-kernel@vger.kernel.org, linux-tegra@vger.kernel.org,
	linux-usb@vger.kernel.org
Subject: Re: [PATCH v2 2/3] usb: chipidea: Simplify Tegra DMA alignment code
Date: Wed, 11 Oct 2023 23:53:28 +0200	[thread overview]
Message-ID: <ZScZWFJCCMr7oWwX@orome.fritz.box> (raw)
In-Reply-To: <a0d917d492b1f91ee0019e68b8e8bca9c585393f.1695934946.git.mirq-linux@rere.qmqm.pl>

[-- Attachment #1: Type: text/plain, Size: 4695 bytes --]

On Thu, Sep 28, 2023 at 11:06:03PM +0200, Michał Mirosław wrote:
> The USB host on Tegra3 works with 32-bit alignment. Previous code tried
> to align the buffer, but it did align the wrapper struct instead, so
> the buffer was at a constant offset of 8 bytes (two pointers) from
> expected alignment.  Since kmalloc() guarantees at least 8-byte
> alignment already, the alignment-extending is removed.
> 
> Fixes: fc53d5279094 ("usb: chipidea: tegra: Support host mode")
> Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
> ---
>  drivers/usb/chipidea/host.c | 45 +++++++++++++++----------------------
>  1 file changed, 18 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
> index abddd39d1ff1..0cce19208370 100644
> --- a/drivers/usb/chipidea/host.c
> +++ b/drivers/usb/chipidea/host.c
> @@ -30,8 +30,7 @@ struct ehci_ci_priv {
>  };
>  
>  struct ci_hdrc_dma_aligned_buffer {
> -	void *kmalloc_ptr;
> -	void *old_xfer_buffer;
> +	void *original_buffer;
>  	u8 data[];
>  };
>  
> @@ -380,60 +379,52 @@ static int ci_ehci_bus_suspend(struct usb_hcd *hcd)
>  	return 0;
>  }
>  
> -static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb)
> +static void ci_hdrc_free_dma_aligned_buffer(struct urb *urb, bool copy_back)
>  {
>  	struct ci_hdrc_dma_aligned_buffer *temp;
> -	size_t length;
>  
>  	if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
>  		return;
> +	urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;

This threw me off a bit until I realized it was already there
previously, just in a different place. Is there a particular reason why
this is moved?

Regardless, this looks fine, so:

Acked-by: Thierry Reding <treding@nvidia.com>

>  
>  	temp = container_of(urb->transfer_buffer,
>  			    struct ci_hdrc_dma_aligned_buffer, data);
> +	urb->transfer_buffer = temp->original_buffer;
> +
> +	if (copy_back && usb_urb_dir_in(urb)) {
> +		size_t length;
>  
> -	if (usb_urb_dir_in(urb)) {
>  		if (usb_pipeisoc(urb->pipe))
>  			length = urb->transfer_buffer_length;
>  		else
>  			length = urb->actual_length;
>  
> -		memcpy(temp->old_xfer_buffer, temp->data, length);
> +		memcpy(temp->original_buffer, temp->data, length);
>  	}
> -	urb->transfer_buffer = temp->old_xfer_buffer;
> -	kfree(temp->kmalloc_ptr);
>  
> -	urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
> +	kfree(temp);
>  }
>  
>  static int ci_hdrc_alloc_dma_aligned_buffer(struct urb *urb, gfp_t mem_flags)
>  {
> -	struct ci_hdrc_dma_aligned_buffer *temp, *kmalloc_ptr;
> -	const unsigned int ci_hdrc_usb_dma_align = 32;
> -	size_t kmalloc_size;
> +	struct ci_hdrc_dma_aligned_buffer *temp;
>  
>  	if (urb->num_sgs || urb->sg || urb->transfer_buffer_length == 0)
>  		return 0;
> -	if (!((uintptr_t)urb->transfer_buffer & (ci_hdrc_usb_dma_align - 1)) && !(urb->transfer_buffer_length & 3))
> +	if (IS_ALIGNED((uintptr_t)urb->transfer_buffer, 4)
> +	    && IS_ALIGNED(urb->transfer_buffer_length, 4))
>  		return 0;
>  
> -	/* Allocate a buffer with enough padding for alignment */
> -	kmalloc_size = ALIGN(urb->transfer_buffer_length, 4) +
> -		       sizeof(struct ci_hdrc_dma_aligned_buffer) +
> -		       ci_hdrc_usb_dma_align - 1;
> -
> -	kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
> -	if (!kmalloc_ptr)
> +	temp = kmalloc(sizeof(*temp) + ALIGN(urb->transfer_buffer_length, 4), mem_flags);
> +	if (!temp)
>  		return -ENOMEM;
>  
> -	/* Position our struct dma_aligned_buffer such that data is aligned */
> -	temp = PTR_ALIGN(kmalloc_ptr + 1, ci_hdrc_usb_dma_align) - 1;
> -	temp->kmalloc_ptr = kmalloc_ptr;
> -	temp->old_xfer_buffer = urb->transfer_buffer;
>  	if (usb_urb_dir_out(urb))
>  		memcpy(temp->data, urb->transfer_buffer,
>  		       urb->transfer_buffer_length);
> +
> +	temp->original_buffer = urb->transfer_buffer;
>  	urb->transfer_buffer = temp->data;
> -
>  	urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
>  
>  	return 0;
> @@ -450,7 +441,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
>  
>  	ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
>  	if (ret)
> -		ci_hdrc_free_dma_aligned_buffer(urb);
> +		ci_hdrc_free_dma_aligned_buffer(urb, false);
>  
>  	return ret;
>  }
> @@ -458,7 +449,7 @@ static int ci_hdrc_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
>  static void ci_hdrc_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
>  {
>  	usb_hcd_unmap_urb_for_dma(hcd, urb);
> -	ci_hdrc_free_dma_aligned_buffer(urb);
> +	ci_hdrc_free_dma_aligned_buffer(urb, true);
>  }
>  
>  #ifdef CONFIG_PM_SLEEP
> -- 
> 2.39.2
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  reply	other threads:[~2023-10-11 21:53 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-28 21:06 [PATCH v2 0/3] usb: chipidea: An USB DMA fix + cleanups for Tegra Michał Mirosław
2023-09-28 21:06 ` [PATCH v2 2/3] usb: chipidea: Simplify Tegra DMA alignment code Michał Mirosław
2023-10-11 21:53   ` Thierry Reding [this message]
2023-10-12 14:28     ` Peter Chen
2023-10-12 21:20     ` Michał Mirosław
2023-09-28 21:06 ` [PATCH v2 1/3] usb: chipidea: Fix DMA overwrite for Tegra Michał Mirosław
2023-10-11 21:51   ` Thierry Reding
2023-10-12 14:28   ` Peter Chen
2023-09-28 21:06 ` [PATCH v2 3/3] usb: chipidea: tegra: Consistently use dev_err_probe() Michał Mirosław
2023-10-11 21:53   ` Thierry Reding

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZScZWFJCCMr7oWwX@orome.fritz.box \
    --to=thierry.reding@gmail.com \
    --cc=digetx@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mirq-linux@rere.qmqm.pl \
    --cc=peter.chen@kernel.org \
    --cc=pgwipeout@gmail.com \
    --cc=treding@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.