Re: [PATCH] mmc: sdhci: use pipeline mmc requests to improve performance
On 9 December 2014 at 10:04, Haibo Chen haibo.c...@freescale.com wrote: This patch is based on the patches by Per Forlin, Tony Lin and Ryan QIAN. This patch complete the API 'post_req' and 'pre_req' in sdhci host side, Test Env: 1. i.MX6Q-SABREAUTO board, CPU @ 996MHz, use ADMA in uSDHC controller. 2. Test command: $ echo 1 /proc/sys/vm/drop_caches write to sd card: $ dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=2000 conv=fsync read the sd card: $ dd if=/dev/mmcblk0 of=/dev/null bs=1M count=2000 3. TOSHIBA 16GB SD3.0 card, running at 4 bit, SDR104 @ 198MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~76.7 MB/s | ~23.3 MB/s | | |without this patch | ~60.5 MB/s | ~22.5 MB/s | - 4. SanDisk 8GB SD3.0 card, running at 4 bit, DDR50 @ 50MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~40.5 MB/s | ~15.6 MB/s | | |without this patch | ~36.1 MB/s | ~14.1 MB/s | - 5. Kingston 8GB SD2.0 card, running at 4 bit, High-speed @ 50MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~22.7 MB/s | ~8.2 MB/s | | |without this patch | ~21.3 MB/s | ~8.0 MB/s | - 6. About eMMC, Sandisk 8GB eMMC on i.MX6DL-sabresd board, CPU @ 792MHZ, eMMC running at 8 bit, DDR52 @ 52MHZ. Performance with and without this patch: - || read speed | write speed | | | with this patch| ~37.3 MB/s | ~10.5 MB/s | | |without this patch | ~33.4 MB/s | ~10.5 MB/s | - Signed-off-by: Haibo Chen haibo.c...@freescale.com Thanks! I have applied this for my next branch to get it tested in linux-next. There were some minor conflicts, which I managed to resolve. Moreover, I decided to fix a checkpatch warning. Kind regards Uffe --- drivers/mmc/host/sdhci.c | 100 -- include/linux/mmc/sdhci.h | 6 +++ 2 files changed, 94 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ada1a3e..50f8a4f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -55,6 +55,9 @@ static void sdhci_finish_command(struct sdhci_host *); static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); static void sdhci_tuning_timer(unsigned long data); static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); +static int sdhci_pre_dma_transfer(struct sdhci_host *host, + struct mmc_data *data, + struct sdhci_host_next *next); #ifdef CONFIG_PM_RUNTIME static int sdhci_runtime_pm_get(struct sdhci_host *host); @@ -494,9 +497,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, goto fail; BUG_ON(host-align_addr 0x3); - host-sg_count = dma_map_sg(mmc_dev(host-mmc), - data-sg, data-sg_len, direction); - if (host-sg_count == 0) + host-sg_count = sdhci_pre_dma_transfer(host, data, NULL); + if (host-sg_count 0) goto unmap_align; desc = host-adma_desc; @@ -633,8 +635,9 @@ static void sdhci_adma_table_post(struct sdhci_host *host, } } - dma_unmap_sg(mmc_dev(host-mmc), data-sg, - data-sg_len, direction); + if (!data-host_cookie) + dma_unmap_sg(mmc_dev(host-mmc), data-sg, + data-sg_len, direction); } static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) @@ -826,11 +829,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) } else { int sg_cnt; -
RE: [PATCH] mmc: sdhci: use pipeline mmc requests to improve performance
Ping... -Original Message- From: Haibo Chen [mailto:haibo.c...@freescale.com] Sent: Tuesday, December 09, 2014 5:04 PM To: ch...@printf.net; ulf.hans...@linaro.org Cc: linux-mmc@vger.kernel.org; donga...@gmail.com; Chen Haibo-B51421 Subject: [PATCH] mmc: sdhci: use pipeline mmc requests to improve performance This patch is based on the patches by Per Forlin, Tony Lin and Ryan QIAN. This patch complete the API 'post_req' and 'pre_req' in sdhci host side, Test Env: 1. i.MX6Q-SABREAUTO board, CPU @ 996MHz, use ADMA in uSDHC controller. 2. Test command: $ echo 1 /proc/sys/vm/drop_caches write to sd card: $ dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=2000 conv=fsync read the sd card: $ dd if=/dev/mmcblk0 of=/dev/null bs=1M count=2000 3. TOSHIBA 16GB SD3.0 card, running at 4 bit, SDR104 @ 198MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~76.7 MB/s | ~23.3 MB/s | | |without this patch | ~60.5 MB/s | ~22.5 MB/s | - 4. SanDisk 8GB SD3.0 card, running at 4 bit, DDR50 @ 50MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~40.5 MB/s | ~15.6 MB/s | | |without this patch | ~36.1 MB/s | ~14.1 MB/s | - 5. Kingston 8GB SD2.0 card, running at 4 bit, High-speed @ 50MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~22.7 MB/s | ~8.2 MB/s | | |without this patch | ~21.3 MB/s | ~8.0 MB/s | - 6. About eMMC, Sandisk 8GB eMMC on i.MX6DL-sabresd board, CPU @ 792MHZ, eMMC running at 8 bit, DDR52 @ 52MHZ. Performance with and without this patch: - || read speed | write speed | | | with this patch| ~37.3 MB/s | ~10.5 MB/s | | |without this patch | ~33.4 MB/s | ~10.5 MB/s | - Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci.c | 100 -- include/linux/mmc/sdhci.h | 6 +++ 2 files changed, 94 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ada1a3e..50f8a4f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -55,6 +55,9 @@ static void sdhci_finish_command(struct sdhci_host *); static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); static void sdhci_tuning_timer(unsigned long data); static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); +static int sdhci_pre_dma_transfer(struct sdhci_host *host, +struct mmc_data *data, +struct sdhci_host_next *next); #ifdef CONFIG_PM_RUNTIME static int sdhci_runtime_pm_get(struct sdhci_host *host); @@ -494,9 +497,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, goto fail; BUG_ON(host-align_addr 0x3); - host-sg_count = dma_map_sg(mmc_dev(host-mmc), - data-sg, data-sg_len, direction); - if (host-sg_count == 0) + host-sg_count = sdhci_pre_dma_transfer(host, data, NULL); + if (host-sg_count 0) goto unmap_align; desc = host-adma_desc; @@ -633,8 +635,9 @@ static void sdhci_adma_table_post(struct sdhci_host *host, } } - dma_unmap_sg(mmc_dev(host-mmc), data-sg, - data-sg_len, direction); + if (!data-host_cookie) + dma_unmap_sg(mmc_dev(host-mmc), data-sg, + data-sg_len, direction); } static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) @@ -826,11 +829,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) } else { int sg_cnt; - sg_cnt = dma_map_sg(mmc_dev(host
Re: [PATCH] mmc: sdhci: use pipeline mmc requests to improve performance
On Tue, Dec 9, 2014 at 5:04 PM, Haibo Chen haibo.c...@freescale.com wrote: This patch is based on the patches by Per Forlin, Tony Lin and Ryan QIAN. This patch complete the API 'post_req' and 'pre_req' in sdhci host side, Test Env: 1. i.MX6Q-SABREAUTO board, CPU @ 996MHz, use ADMA in uSDHC controller. 2. Test command: $ echo 1 /proc/sys/vm/drop_caches write to sd card: $ dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=2000 conv=fsync read the sd card: $ dd if=/dev/mmcblk0 of=/dev/null bs=1M count=2000 3. TOSHIBA 16GB SD3.0 card, running at 4 bit, SDR104 @ 198MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~76.7 MB/s | ~23.3 MB/s | | |without this patch | ~60.5 MB/s | ~22.5 MB/s | - 4. SanDisk 8GB SD3.0 card, running at 4 bit, DDR50 @ 50MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~40.5 MB/s | ~15.6 MB/s | | |without this patch | ~36.1 MB/s | ~14.1 MB/s | - 5. Kingston 8GB SD2.0 card, running at 4 bit, High-speed @ 50MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~22.7 MB/s | ~8.2 MB/s | | |without this patch | ~21.3 MB/s | ~8.0 MB/s | - 6. About eMMC, Sandisk 8GB eMMC on i.MX6DL-sabresd board, CPU @ 792MHZ, eMMC running at 8 bit, DDR52 @ 52MHZ. Performance with and without this patch: - || read speed | write speed | | | with this patch| ~37.3 MB/s | ~10.5 MB/s | | |without this patch | ~33.4 MB/s | ~10.5 MB/s | - Signed-off-by: Haibo Chen haibo.c...@freescale.com Can someone else test and see if can get the same performance improvement? Regards Dong Aisheng --- drivers/mmc/host/sdhci.c | 100 -- include/linux/mmc/sdhci.h | 6 +++ 2 files changed, 94 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ada1a3e..50f8a4f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -55,6 +55,9 @@ static void sdhci_finish_command(struct sdhci_host *); static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); static void sdhci_tuning_timer(unsigned long data); static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); +static int sdhci_pre_dma_transfer(struct sdhci_host *host, + struct mmc_data *data, + struct sdhci_host_next *next); #ifdef CONFIG_PM_RUNTIME static int sdhci_runtime_pm_get(struct sdhci_host *host); @@ -494,9 +497,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, goto fail; BUG_ON(host-align_addr 0x3); - host-sg_count = dma_map_sg(mmc_dev(host-mmc), - data-sg, data-sg_len, direction); - if (host-sg_count == 0) + host-sg_count = sdhci_pre_dma_transfer(host, data, NULL); + if (host-sg_count 0) goto unmap_align; desc = host-adma_desc; @@ -633,8 +635,9 @@ static void sdhci_adma_table_post(struct sdhci_host *host, } } - dma_unmap_sg(mmc_dev(host-mmc), data-sg, - data-sg_len, direction); + if (!data-host_cookie) + dma_unmap_sg(mmc_dev(host-mmc), data-sg, + data-sg_len, direction); } static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) @@ -826,11 +829,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) } else { int sg_cnt; - sg_cnt = dma_map_sg(mmc_dev(host-mmc), - data-sg,
[PATCH] mmc: sdhci: use pipeline mmc requests to improve performance
This patch is based on the patches by Per Forlin, Tony Lin and Ryan QIAN. This patch complete the API 'post_req' and 'pre_req' in sdhci host side, Test Env: 1. i.MX6Q-SABREAUTO board, CPU @ 996MHz, use ADMA in uSDHC controller. 2. Test command: $ echo 1 /proc/sys/vm/drop_caches write to sd card: $ dd if=/dev/zero of=/dev/mmcblk0 bs=1M count=2000 conv=fsync read the sd card: $ dd if=/dev/mmcblk0 of=/dev/null bs=1M count=2000 3. TOSHIBA 16GB SD3.0 card, running at 4 bit, SDR104 @ 198MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~76.7 MB/s | ~23.3 MB/s | | |without this patch | ~60.5 MB/s | ~22.5 MB/s | - 4. SanDisk 8GB SD3.0 card, running at 4 bit, DDR50 @ 50MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~40.5 MB/s | ~15.6 MB/s | | |without this patch | ~36.1 MB/s | ~14.1 MB/s | - 5. Kingston 8GB SD2.0 card, running at 4 bit, High-speed @ 50MHZ Performance with and without this patch: - || read speed | write speed | | | with this patch| ~22.7 MB/s | ~8.2 MB/s | | |without this patch | ~21.3 MB/s | ~8.0 MB/s | - 6. About eMMC, Sandisk 8GB eMMC on i.MX6DL-sabresd board, CPU @ 792MHZ, eMMC running at 8 bit, DDR52 @ 52MHZ. Performance with and without this patch: - || read speed | write speed | | | with this patch| ~37.3 MB/s | ~10.5 MB/s | | |without this patch | ~33.4 MB/s | ~10.5 MB/s | - Signed-off-by: Haibo Chen haibo.c...@freescale.com --- drivers/mmc/host/sdhci.c | 100 -- include/linux/mmc/sdhci.h | 6 +++ 2 files changed, 94 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ada1a3e..50f8a4f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -55,6 +55,9 @@ static void sdhci_finish_command(struct sdhci_host *); static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); static void sdhci_tuning_timer(unsigned long data); static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); +static int sdhci_pre_dma_transfer(struct sdhci_host *host, + struct mmc_data *data, + struct sdhci_host_next *next); #ifdef CONFIG_PM_RUNTIME static int sdhci_runtime_pm_get(struct sdhci_host *host); @@ -494,9 +497,8 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, goto fail; BUG_ON(host-align_addr 0x3); - host-sg_count = dma_map_sg(mmc_dev(host-mmc), - data-sg, data-sg_len, direction); - if (host-sg_count == 0) + host-sg_count = sdhci_pre_dma_transfer(host, data, NULL); + if (host-sg_count 0) goto unmap_align; desc = host-adma_desc; @@ -633,8 +635,9 @@ static void sdhci_adma_table_post(struct sdhci_host *host, } } - dma_unmap_sg(mmc_dev(host-mmc), data-sg, - data-sg_len, direction); + if (!data-host_cookie) + dma_unmap_sg(mmc_dev(host-mmc), data-sg, + data-sg_len, direction); } static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) @@ -826,11 +829,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) } else { int sg_cnt; - sg_cnt = dma_map_sg(mmc_dev(host-mmc), - data-sg, data-sg_len, - (data-flags MMC_DATA_READ) ? - DMA_FROM_DEVICE : - DMA_TO_DEVICE); + sg_cnt =