From: nicolas.ferre@atmel.com (Nicolas Ferre)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH RESEND] mmc: sdio: rw extended, use a sg entry for each block
Date: Thu, 06 Oct 2011 16:45:40 +0200 [thread overview]
Message-ID: <4E8DBF14.6010903@atmel.com> (raw)
In-Reply-To: <1316598039-30238-1-git-send-email-nicolas.ferre@atmel.com>
On 09/21/2011 11:40 AM, Nicolas Ferre :
> While using io multiple blocks operations, change the way that sg is built:
> use one sg entry for each block instead of aggregating the whole buffer
> in a single sg entry.
> Using a single sg entry for a multiple block command may lead to
> misunderstanding between the sd/mmc and the DMA controllers. In fact, the
> knowledge of the block length will allow both controllers to optimize burst
> sizes on internal bus while dealing with those data.
After having performed some tests I realize that it seems quite
difficult to benchmark this particular case (SDIO, CMD53, multi-block
case). Moreover, the SDIO card that I use is triggering this case on
pretty small blocks (16 x 32 bytes). For the record, I use Marvell 8686
with libertas driver.
The benchmark results hardly show an improvement! I guess that the
benefit of having optimized transfers on internal bus is completely
concealed by the overhead of multiple small blocks management by DMA...
Hopefully another SDIO card can use bigger multiple blocks but it could
be difficult to adapt this piece of code to the size of the block itself...
So, do you have ideas about how I can trigger bigger multiple SDIO and
test further?
> Use a sg table to store start addresses of blocks within the data buffer.
>
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
> drivers/mmc/core/sdio_ops.c | 38 +++++++++++++++++++++++++++++---------
For my platform the alternative would be to re-configure at runtime the
chunck size (max size of bursts between sd controller and DMA).
This operation will be conditioned by the identification of this case
(SDIO, CMD53, multi-block) and will involve both DMA and sd/mmc drivers.
I fear that it can be heavyweight.
> 1 files changed, 29 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
> index f087d87..aea6978 100644
> --- a/drivers/mmc/core/sdio_ops.c
> +++ b/drivers/mmc/core/sdio_ops.c
> @@ -124,7 +124,7 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
> struct mmc_request mrq = {0};
> struct mmc_command cmd = {0};
> struct mmc_data data = {0};
> - struct scatterlist sg;
> + struct sg_table sgt;
>
> BUG_ON(!card);
> BUG_ON(fn > 7);
> @@ -144,24 +144,44 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
> cmd.arg |= fn << 28;
> cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
> cmd.arg |= addr << 9;
> - if (blocks == 1 && blksz <= 512)
> - cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */
> - else
> - cmd.arg |= 0x08000000 | blocks; /* block mode */
> + if (blocks == 1 && blksz <= 512) {
> + /* byte mode */
> + struct scatterlist sg;
> +
> + cmd.arg |= (blksz == 512) ? 0 : blksz;
> + sg_init_one(&sg, buf, blksz * blocks);
> +
> + data.sg = &sg;
> + data.sg_len = 1;
> + } else {
> + /* block mode */
> + struct scatterlist *sg_ptr;
> + int i;
> +
> + cmd.arg |= 0x08000000 | blocks;
> + if (sg_alloc_table(&sgt, blocks, GFP_KERNEL))
> + return -ENOMEM;
> + for_each_sg(sgt.sgl, sg_ptr, sgt.nents, i) {
> + sg_set_buf(sg_ptr, buf + i * blksz, blksz);
> + }
> +
> + data.sg = sgt.sgl;
> + data.sg_len = sgt.nents;
> + }
> +
> cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
>
> data.blksz = blksz;
> data.blocks = blocks;
> data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
> - data.sg = &sg;
> - data.sg_len = 1;
> -
> - sg_init_one(&sg, buf, blksz * blocks);
>
> mmc_set_data_timeout(&data, card);
>
> mmc_wait_for_req(card->host, &mrq);
>
> + if (blocks != 1 || blksz > 512)
> + sg_free_table(&sgt);
> +
> if (cmd.error)
> return cmd.error;
> if (data.error)
Best regards,
--
Nicolas Ferre
prev parent reply other threads:[~2011-10-06 14:45 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-21 9:40 [PATCH RESEND] mmc: sdio: rw extended, use a sg entry for each block Nicolas Ferre
2011-10-06 14:45 ` Nicolas Ferre [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4E8DBF14.6010903@atmel.com \
--to=nicolas.ferre@atmel.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).