mbox series

[0/3] mmc: Fix scatter/gather on SDHCI

Message ID 20190909125658.30559-1-thierry.reding@gmail.com (mailing list archive)
Headers show
Series mmc: Fix scatter/gather on SDHCI | expand

Message

Thierry Reding Sept. 9, 2019, 12:56 p.m. UTC
From: Thierry Reding <treding@nvidia.com>

Commit 158a6d3ce3bc ("iommu/dma: add a new dma_map_ops of
get_merge_boundary()") causes scatter/gather to break for SDHCI and
potentially other MMC hosts.

The reason is that the commit ends up tricking the block layer into
believing that there's effectively no limit on the segment size. While
this may be true for some device, it's certainly not true for all. The
DMA descriptors used by SDHCI, for example, have a 16-bit field that
contains the number of bytes to transmit for that particular transfer.
As a result of the segment size exceeding the capabilities of the
hardware, the scatterlist ends up containing entries that are too large
to fit into a single descriptor.

This small series fixes this by making the block layer respect the
segment size restrictions set for the device. It also prevents the MMC
queue code to attempt to overwrite the maximum segment size of a device
that may already have been set up. Finally it configures the maximum
segment size for SDHCI. The last step is technically not required
because the maximum segment size for SDHCI coincides with the default,
but I think it's better to be explicit here.

As a result, all entries in the scatterlist are now small enough to fit
into SDHCI DMA descriptors. Some improvements could be made to how the
scatterlist is packed. For example, the dma-iommu code compacts the SG
entries so that they result in segments less than the maximum segment,
but doesn't split up individual entries. This often results in holes in
the individual segments. In order to create full 64 KiB segments with
only the last segment being partial, the code would have to split up
individual entries. This should be possible but is not done as part of
this series.

Thierry

Thierry Reding (3):
  block: Respect the device's maximum segment size
  mmc: core: Respect MMC host's maximum segment size
  mmc: sdhci: Set DMA maximum segment size to 64 KiB

 block/blk-settings.c     | 24 +++++++++++++++---------
 drivers/mmc/core/queue.c |  2 --
 drivers/mmc/host/sdhci.c |  5 +++++
 drivers/mmc/host/sdhci.h |  1 +
 4 files changed, 21 insertions(+), 11 deletions(-)