On 18 May 2017 at 11:29, Linus Walleij <[email protected]> wrote:
> This option is activated by all multiplatform configs and what
> not so we almost always have it turned on, and the memory it
> saves is negligible, even more so moving forward. The actual
> bounce buffer only gets allocated only when used, the only
> thing the ifdefs are saving is a little bit of code.
>
> It is highly improper to have this as a Kconfig option that
> get turned on by Kconfig, make this a pure runtime-thing and
> let the host decide whether we use bounce buffers. We add a
> new property "disable_bounce" to the host struct.
>
> Notice that mmc_queue_calc_bouncesz() already disables the
> bounce buffers if host->max_segs != 1, so any arch that has a
> maximum number of segments higher than 1 will have bounce
> buffers disabled.
>
> The option CONFIG_MMC_BLOCK_BOUNCE is default y so the
> majority of platforms in the kernel already have it on, and
> it then gets turned off at runtime since most of these have
> a host->max_segs > 1. The few exceptions that have
> host->max_segs == 1 and still turn off the bounce buffering
> are those that disable it in their defconfig.
>
> Those are the following:
>
> arch/arm/configs/colibri_pxa300_defconfig
> arch/arm/configs/zeus_defconfig
> - Uses MMC_PXA, drivers/mmc/host/pxamci.c
> - Sets host->max_segs = NR_SG, which is 1
> - This needs its bounce buffer deactivated so we set
> host->disable_bounce to true in the host driver
>
> arch/arm/configs/davinci_all_defconfig
> - Uses MMC_DAVINCI, drivers/mmc/host/davinci_mmc.c
> - This driver sets host->max_segs to MAX_NR_SG, which is 16
> - That means this driver anyways disabled bounce buffers
> - No special action needed for this platform
>
> arch/arm/configs/lpc32xx_defconfig
> arch/arm/configs/nhk8815_defconfig
> arch/arm/configs/u300_defconfig
> - Uses MMC_ARMMMCI, drivers/mmc/host/mmci.[c|h]
> - This driver by default sets host->max_segs to NR_SG,
> which is 128, unless a DMA engine is used, and in that case
> the number of segments are also > 1
> - That means this driver already disables bounce buffers
> - No special action needed for these platforms
>
> arch/arm/configs/sama5_defconfig
> - Uses MMC_SDHCI, MMC_SDHCI_PLTFM, MMC_SDHCI_OF_AT91, MMC_ATMELMCI
> - Uses drivers/mmc/host/sdhci.c
> - Normally sets host->max_segs to SDHCI_MAX_SEGS which is 128 and
> thus disables bounce buffers
> - Sets host->max_segs to 1 if SDHCI_USE_SDMA is set
> - SDHCI_USE_SDMA is only set by SDHCI on PCI adapers
> - That means that for this platform bounce buffers are already
> disabled at runtime
> - No special action needed for this platform
>
> arch/blackfin/configs/CM-BF533_defconfig
> arch/blackfin/configs/CM-BF537E_defconfig
> - Uses MMC_SPI (a simple MMC card connected on SPI pins)
> - Uses drivers/mmc/host/mmc_spi.c
> - Sets host->max_segs to MMC_SPI_BLOCKSATONCE which is 128
> - That means this platform already disables bounce buffers at
> runtime
> - No special action needed for these platforms
>
> arch/mips/configs/cavium_octeon_defconfig
> - Uses MMC_CAVIUM_OCTEON, drivers/mmc/host/cavium.c
> - Sets host->max_segs to 16 or 1
> - Setting host->disable_bounce to be sure for the 1 case
>
> arch/mips/configs/qi_lb60_defconfig
> - Uses MMC_JZ4740, drivers/mmc/host/jz4740_mmc.c
> - This sets host->max_segs to 128 so bounce buffers are
> already runtime disabled
> - No action needed for this platform
>
> It would be interesting to come up with a list of the platforms
> that actually end up using bounce buffers. I have not been
> able to infer such a list, but it occurs when
> host->max_segs == 1 and the bounce buffering is not explicitly
> disabled.
>
> Signed-off-by: Linus Walleij <[email protected]>
Thanks, the *series* applied for next! (Responding to patch1 as
couldn't find the cover-letter for v2).
Kind regards
Uffe
> ---
> ChangeLog v1->v2:
> - Instead of adding a new bool "disable_bounce" we use the host
> caps variable, reuse the free bit 21 to indicate that bounce
> buffers should be disabled on the host.
> ---
> drivers/mmc/core/Kconfig | 18 ------------------
> drivers/mmc/core/queue.c | 15 +--------------
> drivers/mmc/host/cavium.c | 4 +++-
> drivers/mmc/host/pxamci.c | 6 +++++-
> include/linux/mmc/host.h | 1 +
> 5 files changed, 10 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/mmc/core/Kconfig b/drivers/mmc/core/Kconfig
> index fc1ecdaaa9ca..42e89060cd41 100644
> --- a/drivers/mmc/core/Kconfig
> +++ b/drivers/mmc/core/Kconfig
> @@ -61,24 +61,6 @@ config MMC_BLOCK_MINORS
>
> If unsure, say 8 here.
>
> -config MMC_BLOCK_BOUNCE
> - bool "Use bounce buffer for simple hosts"
> - depends on MMC_BLOCK
> - default y
> - help
> - SD/MMC is a high latency protocol where it is crucial to
> - send large requests in order to get high performance. Many
> - controllers, however, are restricted to continuous memory
> - (i.e. they can't do scatter-gather), something the kernel
> - rarely can provide.
> -
> - Say Y here to help these restricted hosts by bouncing
> - requests back and forth from a large buffer. You will get
> - a big performance gain at the cost of up to 64 KiB of
> - physical memory.
> -
> - If unsure, say Y here.
> -
> config SDIO_UART
> tristate "SDIO UART/GPS class support"
> depends on TTY
> diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c
> index 5c37b6be3e7b..70ba7f94c706 100644
> --- a/drivers/mmc/core/queue.c
> +++ b/drivers/mmc/core/queue.c
> @@ -219,7 +219,6 @@ static struct mmc_queue_req *mmc_queue_alloc_mqrqs(int
> qdepth)
> return mqrq;
> }
>
> -#ifdef CONFIG_MMC_BLOCK_BOUNCE
> static int mmc_queue_alloc_bounce_bufs(struct mmc_queue_req *mqrq, int
> qdepth,
> unsigned int bouncesz)
> {
> @@ -258,7 +257,7 @@ static unsigned int mmc_queue_calc_bouncesz(struct
> mmc_host *host)
> {
> unsigned int bouncesz = MMC_QUEUE_BOUNCESZ;
>
> - if (host->max_segs != 1)
> + if (host->max_segs != 1 || (host->caps & MMC_CAP_NO_BOUNCE_BUFF))
> return 0;
>
> if (bouncesz > host->max_req_size)
> @@ -273,18 +272,6 @@ static unsigned int mmc_queue_calc_bouncesz(struct
> mmc_host *host)
>
> return bouncesz;
> }
> -#else
> -static inline bool mmc_queue_alloc_bounce(struct mmc_queue_req *mqrq,
> - int qdepth, unsigned int bouncesz)
> -{
> - return false;
> -}
> -
> -static unsigned int mmc_queue_calc_bouncesz(struct mmc_host *host)
> -{
> - return 0;
> -}
> -#endif
>
> static int mmc_queue_alloc_sgs(struct mmc_queue_req *mqrq, int qdepth,
> int max_segs)
> diff --git a/drivers/mmc/host/cavium.c b/drivers/mmc/host/cavium.c
> index 58b51ba6aabd..9c1575f7c1fb 100644
> --- a/drivers/mmc/host/cavium.c
> +++ b/drivers/mmc/host/cavium.c
> @@ -1040,10 +1040,12 @@ int cvm_mmc_of_slot_probe(struct device *dev, struct
> cvm_mmc_host *host)
> * We only have a 3.3v supply, we cannot support any
> * of the UHS modes. We do support the high speed DDR
> * modes up to 52MHz.
> + *
> + * Disable bounce buffers for max_segs = 1
> */
> mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
> MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_POWER_OFF_CARD |
> - MMC_CAP_3_3V_DDR;
> + MMC_CAP_3_3V_DDR | MMC_CAP_NO_BOUNCE_BUFF;
>
> if (host->use_sg)
> mmc->max_segs = 16;
> diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
> index c763b404510f..59ab194cb009 100644
> --- a/drivers/mmc/host/pxamci.c
> +++ b/drivers/mmc/host/pxamci.c
> @@ -702,7 +702,11 @@ static int pxamci_probe(struct platform_device *pdev)
>
> pxamci_init_ocr(host);
>
> - mmc->caps = 0;
> + /*
> + * This architecture used to disable bounce buffers through its
> + * defconfig, now it is done at runtime as a host property.
> + */
> + mmc->caps = MMC_CAP_NO_BOUNCE_BUFF;
> host->cmdat = 0;
> if (!cpu_is_pxa25x()) {
> mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 21385ac0c9b1..67f6abe5c3af 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -270,6 +270,7 @@ struct mmc_host {
> #define MMC_CAP_UHS_SDR50 (1 << 18) /* Host supports UHS SDR50
> mode */
> #define MMC_CAP_UHS_SDR104 (1 << 19) /* Host supports UHS SDR104
> mode */
> #define MMC_CAP_UHS_DDR50 (1 << 20) /* Host supports UHS DDR50
> mode */
> +#define MMC_CAP_NO_BOUNCE_BUFF (1 << 21) /* Disable bounce buffers on
> host */
> #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type
> A */
> #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type
> C */
> #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type
> D */
> --
> 2.9.3
>