From: David Vrabel <david.vrabel@csr.com>
To: Pierre Ossman <drzeus-list@drzeus.cx>
Cc: linux-kernel@vger.kernel.org, david.vrabel@csr.com
Subject: Re: sdio: enhance IO_RW_EXTENDED support
Date: Tue, 07 Aug 2007 13:51:39 +0100 [thread overview]
Message-ID: <46B86ADB.90000@csr.com> (raw)
In-Reply-To: <20070806220145.66b97559@poseidon.drzeus.cx>
Pierre Ossman wrote:
> This is essentially what I mean.
It does not behave very well, see the specific comments at the end.
When considering optimizing SDIO it is important to always keep in mind
that a command is very expensive. They're some 100-150 clocks long and
there's also overheads in interrupt handling/scheduling, this can add to
up to 10s of us. Therefore, when selecting an optimum block size one
should aim to reduce the number of commands before attempting to
maximize the block size.
There are two cases to consider.
1. Card's max block_size <= 512.
In this case the optimum block size is /always/ the card's maximum.
This means we can do all transfers in two commands (and if the driver is
aware of the block size it may choose to pad transfers so only one
command is done).
2. Card's max block size > 512.
We can't handle arbitrary sized transfers with a block size > 512 (since
512 is maximum length of a byte mode transfer), so if we wish to use a
block size of 1024 (say) some transfers will require three commands (a
block mode, and two byte mode transfers). For a block size of 2048 (the
maximum possible) some transfer may require 5 commands!
We could attempt to set the block size as follows:
transfer size % 1024 == 0 => block size = 1024
transfer size % 2048 == 0 => block size = 2048
otherwise => block size = 512
However, without knowing what sizes of transfers the driver is going to
use we cannot intelligently know when it's best to switch the block
size. A block size change is expensive (two commands).
The change in block size from 512 to 2048 improves performance (for an
individual command) by 2.0% [1]. I don't believe this performance
benefit is worth the possible overhead of frequent block size changes
nor the cost of potentially more than 2 commands per transfer.
[1] The real performance benefit will be much less due to per command
overhead and other non IO_RW_EXTENDED traffic on the bus.
In conclusion, the optimum block size is based solely on the card and
host capabilities and should be limited to at most 512. Hence the block
size can (and should) only be set once during card initialization.
This has the added benefit of making the code simpler and hence easier
to understand and maintain.
> +/*
> + * Internal function. Splits an arbitrarily sized data transfer
> + * into several IO_RW_EXTENDED commands.
> + */
> +static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
> + unsigned addr, int incr_addr, u8 *buf, unsigned size)
> +{
> + unsigned remainder = size;
> + int ret;
> + unsigned short blksz;
> + struct mmc_host *host = func->card->host;
> +
> + if (func->forced_blksz)
> + blksz = func->forced_blksz;
> + else {
> + if (size <= 512)
> + goto byte_remainder;
The maximum size for a byte mode transfer is the block size set in the card.
> +
> + blksz = size;
> + if (size > 0xffff)
> + blksz = 0xffff;
The largest possible block size is 2048. I'd also not be keen on using
a block size which isn't a power of 2 -- hardware is unlikely to have
been exercised with unusual block sizes.
> + if (blksz > func->blksize)
> + blksz = func->blksize;
> + if (blksz > host->max_blk_size)
> + blksz = host->max_blk_size;
> +
> + /* avoid changing blksize needlessly */
> + if (func->cur_blksz && ((blksz % func->cur_blksz) == 0))
> + blksz = func->cur_blksz;
If func->blksize == 1024 and we perform transfers in the 512 to 1024
range, this would set the block size on every transfer.
> + }
David
--
David Vrabel, Software Engineer, Drivers group Tel: +44 (0)1223 692562
CSR plc, Churchill House, Cambridge Business Park, Cowley Road, CB4 0WZ
.
next prev parent reply other threads:[~2007-08-07 12:52 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-31 15:36 sdio: enhance IO_RW_EXTENDED support David Vrabel
2007-07-31 15:36 ` sdio: parameterize SDIO FBR register defines David Vrabel
2007-08-04 13:26 ` Pierre Ossman
2007-08-06 10:14 ` David Vrabel
2007-08-06 14:58 ` Pierre Ossman
2007-07-31 15:36 ` sdio: set the functions' block size David Vrabel
2007-08-04 13:30 ` Pierre Ossman
2007-08-06 10:04 ` David Vrabel
2007-07-31 15:36 ` sdio: extend sdio_readsb() and friends to handle any length of buffer David Vrabel
2007-08-04 13:35 ` Pierre Ossman
2007-08-04 13:23 ` sdio: enhance IO_RW_EXTENDED support Pierre Ossman
2007-08-06 10:31 ` David Vrabel
2007-08-06 15:12 ` Pierre Ossman
2007-08-06 15:32 ` David Vrabel
2007-08-06 18:06 ` Pierre Ossman
2007-08-06 20:01 ` Pierre Ossman
2007-08-07 12:51 ` David Vrabel [this message]
2007-08-07 12:53 ` [patch 1/4] sdio: parameterize SDIO FBR register defines David Vrabel
2007-08-07 12:54 ` [patch 2/4] sdio: set the functions' block size David Vrabel
2007-08-07 13:38 ` Pierre Ossman
2007-08-07 17:20 ` David Vrabel
2007-08-07 17:54 ` Pierre Ossman
2007-08-08 9:46 ` David Vrabel
2007-08-08 10:06 ` Pierre Ossman
2007-08-08 10:19 ` David Vrabel
2007-08-07 12:55 ` [patch 3/4] sdio: extend sdio_readsb() and friends to handle any length of buffer David Vrabel
2007-08-07 13:42 ` Pierre Ossman
2007-08-07 20:17 ` Pierre Ossman
2007-08-08 10:19 ` David Vrabel
2007-08-08 10:37 ` Pierre Ossman
2007-08-08 13:22 ` David Vrabel
2007-08-08 13:23 ` [patch 1/3] sdio: add SDIO_FBR_BASE(f) macro David Vrabel
2007-08-08 13:23 ` [patch 2/3] sdio: set the functions' block size David Vrabel
2007-08-08 13:24 ` [patch 3/3] sdio: extend sdio_readsb() and friends to handle any length of buffer David Vrabel
2007-08-08 16:55 ` [patch 3/4] " Pierre Ossman
2007-08-07 12:55 ` [patch 4/4] sdio: disable CD resistor David Vrabel
2007-08-07 13:43 ` Pierre Ossman
2007-08-07 14:46 ` David Vrabel
2007-08-07 15:08 ` Pierre Ossman
2007-08-07 13:33 ` sdio: enhance IO_RW_EXTENDED support Pierre Ossman
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=46B86ADB.90000@csr.com \
--to=david.vrabel@csr.com \
--cc=drzeus-list@drzeus.cx \
--cc=linux-kernel@vger.kernel.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).