diff mbox

usb-storage: stop using block layer bounce buffers

Message ID 20180415145329.855-1-hch@lst.de (mailing list archive)
State Not Applicable
Headers show

Commit Message

Christoph Hellwig April 15, 2018, 2:53 p.m. UTC
USB host controllers now must handle highmem, so we can get rid of bounce
buffering highmem pages in the block layer.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 drivers/usb/storage/scsiglue.c | 9 ---------
 1 file changed, 9 deletions(-)

Comments

Alan Stern April 15, 2018, 3:24 p.m. UTC | #1
On Sun, 15 Apr 2018, Christoph Hellwig wrote:

> USB host controllers now must handle highmem, so we can get rid of bounce
> buffering highmem pages in the block layer.

Sorry, I don't quite understand what you are saying.  Do you mean that
all USB host controllers now magically _do_ handle highmem?  Or do you
mean that if they _don't_ handle highmem, we will not support them any
more?

Alan Stern

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  drivers/usb/storage/scsiglue.c | 9 ---------
>  1 file changed, 9 deletions(-)
> 
> diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
> index c267f2812a04..4e453d9d45d5 100644
> --- a/drivers/usb/storage/scsiglue.c
> +++ b/drivers/usb/storage/scsiglue.c
> @@ -130,15 +130,6 @@ static int slave_configure(struct scsi_device *sdev)
>  		blk_queue_max_hw_sectors(sdev->request_queue, 2048);
>  	}
>  
> -	/*
> -	 * Some USB host controllers can't do DMA; they have to use PIO.
> -	 * They indicate this by setting their dma_mask to NULL.  For
> -	 * such controllers we need to make sure the block layer sets
> -	 * up bounce buffers in addressable memory.
> -	 */
> -	if (!us->pusb_dev->bus->controller->dma_mask)
> -		blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_HIGH);
> -
>  	/*
>  	 * We can't put these settings in slave_alloc() because that gets
>  	 * called before the device type is known.  Consequently these
>
Christoph Hellwig April 27, 2018, 5:27 a.m. UTC | #2
On Sun, Apr 15, 2018 at 11:24:11AM -0400, Alan Stern wrote:
> On Sun, 15 Apr 2018, Christoph Hellwig wrote:
> 
> > USB host controllers now must handle highmem, so we can get rid of bounce
> > buffering highmem pages in the block layer.
> 
> Sorry, I don't quite understand what you are saying.  Do you mean that
> all USB host controllers now magically _do_ handle highmem?  Or do you
> mean that if they _don't_ handle highmem, we will not support them any
> more?

USB controller themselves never cared about highmem, drivers did.  For
PIO based controllers they'd have to kmap any address no in the kernel
drirect mapping.

Nothing in drivers/usb/host or the other diretories related to host
drivers calls page_address (only used in a single gadget) or sg_virt
(only used in a few upper level drivers), which makes me assume
semi-confidently that no USB host driver is not highmem aware these
days.

Greg, does this match your observation as the USB maintainer?
Alan Stern April 27, 2018, 2:09 p.m. UTC | #3
On Fri, 27 Apr 2018, Christoph Hellwig wrote:

> On Sun, Apr 15, 2018 at 11:24:11AM -0400, Alan Stern wrote:
> > On Sun, 15 Apr 2018, Christoph Hellwig wrote:
> > 
> > > USB host controllers now must handle highmem, so we can get rid of bounce
> > > buffering highmem pages in the block layer.
> > 
> > Sorry, I don't quite understand what you are saying.  Do you mean that
> > all USB host controllers now magically _do_ handle highmem?  Or do you
> > mean that if they _don't_ handle highmem, we will not support them any
> > more?
> 
> USB controller themselves never cared about highmem, drivers did.  For
> PIO based controllers they'd have to kmap any address no in the kernel
> drirect mapping.
> 
> Nothing in drivers/usb/host or the other diretories related to host
> drivers calls page_address (only used in a single gadget) or sg_virt
> (only used in a few upper level drivers), which makes me assume
> semi-confidently that no USB host driver is not highmem aware these
> days.

sg_virt is called in drivers/usb/core/message.c.  (Maybe that's what
you meant by "upper level drivers".)  I'm not sure just how important
that usage is.

Alan Stern

> Greg, does this match your observation as the USB maintainer?
Christoph Hellwig May 2, 2018, 12:47 p.m. UTC | #4
On Fri, Apr 27, 2018 at 10:09:17AM -0400, Alan Stern wrote:
> On Fri, 27 Apr 2018, Christoph Hellwig wrote:
> 
> > On Sun, Apr 15, 2018 at 11:24:11AM -0400, Alan Stern wrote:
> > > On Sun, 15 Apr 2018, Christoph Hellwig wrote:
> > > 
> > > > USB host controllers now must handle highmem, so we can get rid of bounce
> > > > buffering highmem pages in the block layer.
> > > 
> > > Sorry, I don't quite understand what you are saying.  Do you mean that
> > > all USB host controllers now magically _do_ handle highmem?  Or do you
> > > mean that if they _don't_ handle highmem, we will not support them any
> > > more?
> > 
> > USB controller themselves never cared about highmem, drivers did.  For
> > PIO based controllers they'd have to kmap any address no in the kernel
> > drirect mapping.
> > 
> > Nothing in drivers/usb/host or the other diretories related to host
> > drivers calls page_address (only used in a single gadget) or sg_virt
> > (only used in a few upper level drivers), which makes me assume
> > semi-confidently that no USB host driver is not highmem aware these
> > days.
> 
> sg_virt is called in drivers/usb/core/message.c.  (Maybe that's what
> you meant by "upper level drivers".)  I'm not sure just how important
> that usage is.

I don't really know either.  I'll need some guidance from the usb
maintainers on:

 - when drivers can submit urbs with a scatterlist
 - if there are any drivers that do not want to take highmem

Unfortunately the way dma mapping works in usb is just so deeply
convoluted that I have a hard time following it, and often wonder
what is intentional and what is accidental in it.
Alan Stern May 2, 2018, 2:48 p.m. UTC | #5
On Wed, 2 May 2018, Christoph Hellwig wrote:

> On Fri, Apr 27, 2018 at 10:09:17AM -0400, Alan Stern wrote:
> > On Fri, 27 Apr 2018, Christoph Hellwig wrote:
> > 
> > > On Sun, Apr 15, 2018 at 11:24:11AM -0400, Alan Stern wrote:
> > > > On Sun, 15 Apr 2018, Christoph Hellwig wrote:
> > > > 
> > > > > USB host controllers now must handle highmem, so we can get rid of bounce
> > > > > buffering highmem pages in the block layer.
> > > > 
> > > > Sorry, I don't quite understand what you are saying.  Do you mean that
> > > > all USB host controllers now magically _do_ handle highmem?  Or do you
> > > > mean that if they _don't_ handle highmem, we will not support them any
> > > > more?
> > > 
> > > USB controller themselves never cared about highmem, drivers did.  For
> > > PIO based controllers they'd have to kmap any address no in the kernel
> > > drirect mapping.
> > > 
> > > Nothing in drivers/usb/host or the other diretories related to host
> > > drivers calls page_address (only used in a single gadget) or sg_virt
> > > (only used in a few upper level drivers), which makes me assume
> > > semi-confidently that no USB host driver is not highmem aware these
> > > days.
> > 
> > sg_virt is called in drivers/usb/core/message.c.  (Maybe that's what
> > you meant by "upper level drivers".)  I'm not sure just how important
> > that usage is.
> 
> I don't really know either.  I'll need some guidance from the usb
> maintainers on:
> 
>  - when drivers can submit urbs with a scatterlist
>  - if there are any drivers that do not want to take highmem
> 
> Unfortunately the way dma mapping works in usb is just so deeply
> convoluted that I have a hard time following it, and often wonder
> what is intentional and what is accidental in it.

I can help explain some of this.

Drivers are allowed to submit bulk URBs with scatterlists.  
Isochronous definitely does not support scatterlists.  I suppose
control/interrupt might or might not support it (depending on how the
host controller driver is written), but (1) support is not guaranteed 
so drivers can't rely on it, and (2) nobody ever needs to use 
scatter-gather I/O for control or interrupt transfers anyway.

In practice, mass storage (usb_storage, uas, and f_tcm) is the only
important USB application that I know uses scatterlists.  The usbtest
driver includes scatter-gather support, but it is purely for testing
and verification purposes.  Also, the usbfs driver (core/devio.c) can
use SG, but in this case the scatterlist is constructed by the driver
itself rather than received from someone else.

Scatter-gather I/O is handled at two different levels in the USB
subsystem.  Some of the host controller drivers have native SG support;  
for them it isn't a problem, so we only have to worry about the other
ones.  Most of those use normal DMA transfers, so high memory issues
should be handled by the block layer and DMA core.  However, a few of
the drivers rely on PIO or special memory that is local to the
controller hardware.  You can see all the different possibilities if
you read through core/hcd.c: map_urb_for_dma() and
usb_hcd_map_urb_for_dma().  I don't remember which drivers are special,
but you can search the driver source code for dma_mask and
HCD_LOCAL_MEM.

At a higher level, there are some library routines in core/message.c
that provide a poor-man's form of SG for cases where the host
controller driver doesn't have native support; see usb_sg_init() and
the surrounding routines.  (The library predates the native SG support
by many years.)  This is really the only interesting case; the code
creates an individual URB for each entry in the scatterlist and submits
them all.  The question is whether the host controller driver will be 
able to access the data given by the scatterlist entries.

Do you have any particular questions about accidental vs. intentional 
aspects of the DMA support?

Alan Stern
diff mbox

Patch

diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index c267f2812a04..4e453d9d45d5 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -130,15 +130,6 @@  static int slave_configure(struct scsi_device *sdev)
 		blk_queue_max_hw_sectors(sdev->request_queue, 2048);
 	}
 
-	/*
-	 * Some USB host controllers can't do DMA; they have to use PIO.
-	 * They indicate this by setting their dma_mask to NULL.  For
-	 * such controllers we need to make sure the block layer sets
-	 * up bounce buffers in addressable memory.
-	 */
-	if (!us->pusb_dev->bus->controller->dma_mask)
-		blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_HIGH);
-
 	/*
 	 * We can't put these settings in slave_alloc() because that gets
 	 * called before the device type is known.  Consequently these