Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mmc: core: Delete bounce buffer Kconfig option

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 <linus.walleij@linaro.org>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>

authored by

Linus Walleij and committed by
Ulf Hansson
c3dccb74 9d08428a

+10 -34
-18
drivers/mmc/core/Kconfig
··· 61 61 62 62 If unsure, say 8 here. 63 63 64 - config MMC_BLOCK_BOUNCE 65 - bool "Use bounce buffer for simple hosts" 66 - depends on MMC_BLOCK 67 - default y 68 - help 69 - SD/MMC is a high latency protocol where it is crucial to 70 - send large requests in order to get high performance. Many 71 - controllers, however, are restricted to continuous memory 72 - (i.e. they can't do scatter-gather), something the kernel 73 - rarely can provide. 74 - 75 - Say Y here to help these restricted hosts by bouncing 76 - requests back and forth from a large buffer. You will get 77 - a big performance gain at the cost of up to 64 KiB of 78 - physical memory. 79 - 80 - If unsure, say Y here. 81 - 82 64 config SDIO_UART 83 65 tristate "SDIO UART/GPS class support" 84 66 depends on TTY
+1 -14
drivers/mmc/core/queue.c
··· 219 219 return mqrq; 220 220 } 221 221 222 - #ifdef CONFIG_MMC_BLOCK_BOUNCE 223 222 static int mmc_queue_alloc_bounce_bufs(struct mmc_queue_req *mqrq, int qdepth, 224 223 unsigned int bouncesz) 225 224 { ··· 257 258 { 258 259 unsigned int bouncesz = MMC_QUEUE_BOUNCESZ; 259 260 260 - if (host->max_segs != 1) 261 + if (host->max_segs != 1 || (host->caps & MMC_CAP_NO_BOUNCE_BUFF)) 261 262 return 0; 262 263 263 264 if (bouncesz > host->max_req_size) ··· 272 273 273 274 return bouncesz; 274 275 } 275 - #else 276 - static inline bool mmc_queue_alloc_bounce(struct mmc_queue_req *mqrq, 277 - int qdepth, unsigned int bouncesz) 278 - { 279 - return false; 280 - } 281 - 282 - static unsigned int mmc_queue_calc_bouncesz(struct mmc_host *host) 283 - { 284 - return 0; 285 - } 286 - #endif 287 276 288 277 static int mmc_queue_alloc_sgs(struct mmc_queue_req *mqrq, int qdepth, 289 278 int max_segs)
+3 -1
drivers/mmc/host/cavium.c
··· 1035 1035 * We only have a 3.3v supply, we cannot support any 1036 1036 * of the UHS modes. We do support the high speed DDR 1037 1037 * modes up to 52MHz. 1038 + * 1039 + * Disable bounce buffers for max_segs = 1 1038 1040 */ 1039 1041 mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | 1040 1042 MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_POWER_OFF_CARD | 1041 - MMC_CAP_3_3V_DDR; 1043 + MMC_CAP_3_3V_DDR | MMC_CAP_NO_BOUNCE_BUFF; 1042 1044 1043 1045 if (host->use_sg) 1044 1046 mmc->max_segs = 16;
+5 -1
drivers/mmc/host/pxamci.c
··· 702 702 703 703 pxamci_init_ocr(host); 704 704 705 - mmc->caps = 0; 705 + /* 706 + * This architecture used to disable bounce buffers through its 707 + * defconfig, now it is done at runtime as a host property. 708 + */ 709 + mmc->caps = MMC_CAP_NO_BOUNCE_BUFF; 706 710 host->cmdat = 0; 707 711 if (!cpu_is_pxa25x()) { 708 712 mmc->caps |= MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+1
include/linux/mmc/host.h
··· 271 271 #define MMC_CAP_UHS_SDR50 (1 << 18) /* Host supports UHS SDR50 mode */ 272 272 #define MMC_CAP_UHS_SDR104 (1 << 19) /* Host supports UHS SDR104 mode */ 273 273 #define MMC_CAP_UHS_DDR50 (1 << 20) /* Host supports UHS DDR50 mode */ 274 + #define MMC_CAP_NO_BOUNCE_BUFF (1 << 21) /* Disable bounce buffers on host */ 274 275 #define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */ 275 276 #define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */ 276 277 #define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */