* MMC performance @ 2004-10-11 11:05 Pierre Ossman 2004-10-11 12:19 ` Russell King 0 siblings, 1 reply; 7+ messages in thread From: Pierre Ossman @ 2004-10-11 11:05 UTC (permalink / raw) To: LKML, Russell King I've added SGIO support to my driver now hoping that it would resolve the piss-poor performance I've been getting. Didn't do much difference though. Read operations are fairly fast. It queues 8kB at a time. A bit small perhaps, but still decent. Writing, however, only sends a single sector at a time. The queue process eats up half of the CPU time on my machine during a write. And since MMC cards have to clear a whole bunch of sectors before a write shouldn't you send as many sectors as possible to them? Since I don't have another controller to compare with I don't really know if the problem is in my code, the MMC layer, the block layer or the filesystem. I'm going to dig around a bit more but some pointers are welcome. At least which layer I should be looking at. Rgds Pierre ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: MMC performance 2004-10-11 11:05 MMC performance Pierre Ossman @ 2004-10-11 12:19 ` Russell King 2004-10-11 13:18 ` Alan Cox 2004-10-11 13:49 ` Pierre Ossman 0 siblings, 2 replies; 7+ messages in thread From: Russell King @ 2004-10-11 12:19 UTC (permalink / raw) To: Pierre Ossman; +Cc: LKML On Mon, Oct 11, 2004 at 01:05:09PM +0200, Pierre Ossman wrote: > Writing, however, only sends a single sector at a time. The queue > process eats up half of the CPU time on my machine during a write. And > since MMC cards have to clear a whole bunch of sectors before a write > shouldn't you send as many sectors as possible to them? Only if you can reliably know how many bytes you've tranferred when an error occurs. Without that, the only safe way to do a write is sector by sector. And there are MMC controllers which just don't give you that information, namely those found in Intel chips... Since I'm having to be compatible with existing drivers, we need to do this for the time being. It's a shame we can't tell the BIO layer about this type of quirk though. Not that BIO itself understands "sector by sector" IO at the moment. -- Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/ 2.6 Serial core ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: MMC performance 2004-10-11 12:19 ` Russell King @ 2004-10-11 13:18 ` Alan Cox 2004-10-11 15:27 ` Pierre Ossman 2004-10-11 13:49 ` Pierre Ossman 1 sibling, 1 reply; 7+ messages in thread From: Alan Cox @ 2004-10-11 13:18 UTC (permalink / raw) To: Russell King; +Cc: Pierre Ossman, LKML On Llu, 2004-10-11 at 13:19, Russell King wrote: > Only if you can reliably know how many bytes you've tranferred when > an error occurs. Without that, the only safe way to do a write is > sector by sector. Only on retries. You can try and blast the lot out the first time then on retries you write sector by sector. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: MMC performance 2004-10-11 13:18 ` Alan Cox @ 2004-10-11 15:27 ` Pierre Ossman 2004-10-11 18:01 ` Pierre Ossman 0 siblings, 1 reply; 7+ messages in thread From: Pierre Ossman @ 2004-10-11 15:27 UTC (permalink / raw) To: Alan Cox; +Cc: Russell King, LKML [-- Attachment #1: Type: text/plain, Size: 199 bytes --] Alan Cox wrote: >Only on retries. You can try and blast the lot out the first time then >on retries you write sector by sector. > > > Something like this? Gives more than double throughput here. [-- Attachment #2: mmc-bulk.patch --] [-- Type: text/x-patch, Size: 2761 bytes --] Index: linux-wbsd/drivers/mmc/mmc_block.c =================================================================== --- linux-wbsd/drivers/mmc/mmc_block.c (revision 71) +++ linux-wbsd/drivers/mmc/mmc_block.c (working copy) @@ -166,9 +166,20 @@ struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; int ret; + int failsafe; if (mmc_card_claim_host(card)) goto cmd_err; + + /* + * We first try transfering multiple blocks. If this fails + * we fall back to single block transfers. + * + * This gives us good performance when all is well and the + * possibility to determine which sector fails when all + * is not well. + */ + failsafe = 0; do { struct mmc_blk_request brq; @@ -188,15 +199,24 @@ brq.stop.opcode = MMC_STOP_TRANSMISSION; brq.stop.arg = 0; brq.stop.flags = MMC_RSP_R1B; + + /* + * A multi-block transfer failed. Falling back to single + * blocks. + */ + if (failsafe) + brq.data.blocks = 1; + + ret = 1; if (rq_data_dir(req) == READ) { brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; brq.data.flags |= MMC_DATA_READ; } else { - brq.cmd.opcode = MMC_WRITE_BLOCK; + brq.cmd.opcode = brq.data.blocks > 1 ? MMC_WRITE_MULTIPLE_BLOCK : + MMC_WRITE_BLOCK; brq.cmd.flags = MMC_RSP_R1B; brq.data.flags |= MMC_DATA_WRITE; - brq.data.blocks = 1; } brq.mrq.stop = brq.data.blocks > 1 ? &brq.stop : NULL; @@ -204,19 +224,34 @@ if (brq.cmd.error) { printk(KERN_ERR "%s: error %d sending read/write command\n", req->rq_disk->disk_name, brq.cmd.error); - goto cmd_err; + if (failsafe) + goto cmd_err; + else { + failsafe = 1; + continue; + } } if (brq.data.error) { printk(KERN_ERR "%s: error %d transferring data\n", req->rq_disk->disk_name, brq.data.error); - goto cmd_err; + if (failsafe) + goto cmd_err; + else { + failsafe = 1; + continue; + } } if (brq.stop.error) { printk(KERN_ERR "%s: error %d sending stop command\n", req->rq_disk->disk_name, brq.stop.error); - goto cmd_err; + if (failsafe) + goto cmd_err; + else { + failsafe = 1; + continue; + } } do { @@ -229,7 +264,12 @@ if (err) { printk(KERN_ERR "%s: error %d requesting status\n", req->rq_disk->disk_name, err); - goto cmd_err; + if (failsafe) + goto cmd_err; + else { + failsafe = 1; + continue; + } } } while (!(cmd.resp[0] & R1_READY_FOR_DATA)); @@ -255,6 +295,11 @@ end_that_request_last(req); } spin_unlock_irq(&md->lock); + + /* + * Go back to bulk mode if in failsafe mode. + */ + failsafe = 0; } while (ret); mmc_card_release_host(card); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: MMC performance 2004-10-11 15:27 ` Pierre Ossman @ 2004-10-11 18:01 ` Pierre Ossman 2004-10-18 19:26 ` Pierre Ossman 0 siblings, 1 reply; 7+ messages in thread From: Pierre Ossman @ 2004-10-11 18:01 UTC (permalink / raw) Cc: Alan Cox, Russell King, LKML Pierre Ossman wrote: > Alan Cox wrote: > >> Only on retries. You can try and blast the lot out the first time then >> on retries you write sector by sector. >> >> >> > Something like this? Gives more than double throughput here. > > *sigh* I'm starting to think there is a special place in hell reserved for the folks at SimpleTech. This card has been giving me all kinds of trouble and this patch adds another one. It seems the card completely screws up multiple block writes. As little as two blocks at a time causes corrupt data on the card. I've been digging through the specs I have to find some way of detecting cards like these but I haven't had any success. Hopefully there aren't too many of these out there. If the choice comes down to high speed or supporting non-compliant cards, then my vote is for speed. -- Pierre ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: MMC performance 2004-10-11 18:01 ` Pierre Ossman @ 2004-10-18 19:26 ` Pierre Ossman 0 siblings, 0 replies; 7+ messages in thread From: Pierre Ossman @ 2004-10-18 19:26 UTC (permalink / raw) To: LKML; +Cc: Russell King I've solved (sort of) the problem with corrupt data when doing multiple block writes. It seems the spec I have for the host controller isn't quite correct when it comes to clock frequencies. Copying the value that Windows uses (it doesn't adapt to the card) got the card working perfectly. This value is (according to my spec) invalid though. I need to hook up an oscilloscope to the device to figure this one out. Russell, the users of my driver have tested the write multiple block patch and haven't run into any problems. If you haven't found any issues I suggest making it standard. Rgds Pierre ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: MMC performance 2004-10-11 12:19 ` Russell King 2004-10-11 13:18 ` Alan Cox @ 2004-10-11 13:49 ` Pierre Ossman 1 sibling, 0 replies; 7+ messages in thread From: Pierre Ossman @ 2004-10-11 13:49 UTC (permalink / raw) To: Russell King; +Cc: LKML Russell King wrote: >Only if you can reliably know how many bytes you've tranferred when >an error occurs. Without that, the only safe way to do a write is >sector by sector. > > > What would happen if we failed the entire request? Rewriting a few sectors is harmless. Or will it break in more exotic ways? Rgds Pierre ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2004-10-18 19:31 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-10-11 11:05 MMC performance Pierre Ossman 2004-10-11 12:19 ` Russell King 2004-10-11 13:18 ` Alan Cox 2004-10-11 15:27 ` Pierre Ossman 2004-10-11 18:01 ` Pierre Ossman 2004-10-18 19:26 ` Pierre Ossman 2004-10-11 13:49 ` Pierre Ossman
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.