On 3 May 2011 15:16, Arnd Bergmann <arnd@xxxxxxxx> wrote: > On Thursday 28 April 2011, Per Forlin wrote: > >> For reads on the other hand it look like this >> root@(none):/ dd if=/dev/mmcblk0 of=/dev/null bs=4k count=256 >> 256+0 records in >> 256+0 records out >> root@(none):/ dmesg >> [mmc_queue_thread] req d954cec0 blocks 32 >> [mmc_queue_thread] req (null) blocks 0 >> [mmc_queue_thread] req (null) blocks 0 >> [mmc_queue_thread] req d954cec0 blocks 64 >> [mmc_queue_thread] req (null) blocks 0 >> [mmc_queue_thread] req d954cde8 blocks 128 >> [mmc_queue_thread] req (null) blocks 0 >> [mmc_queue_thread] req d954cec0 blocks 256 >> [mmc_queue_thread] req (null) blocks 0 > >> There are never more than one read request in the mmc block queue. All >> the mmc request preparations will be serialized and the cost for this >> is roughly 10% lower bandwidth (verified on ARM platforms ux500 and >> Pandaboard). > > After some offline discussions, I went back to look at your mail, and I think > the explanation is much simpler than you expected: > > You have only a single process reading blocks synchronously, so the round > trip goes all the way to user space. The block layer does some readahead, > so it will start reading 32 blocks instead of just 8 (4KB) for the first > read, but then the user process just sits waiting for data. After the > mmc driver has finished reading the entire 32 blocks, the user needs a > little time to read them from the page cache in 4 KB chunks (8 syscalls), > during which the block layer has no clue about what the user wants to do > next. > > The readahead scales up to 256 blocks, but there is still only one reader, > so you never have additional requests in the queue. > > Try running multiple readers in parallel, e.g. > > for i in 1 2 3 4 5 ; do > dd if=/dev/mmcblk0 bs=16k count=256 iflag=direct skip=$[$i * 1024] & > done Yes you are right about this. If I run with multiple read threads there are multiple request waiting in the mmc block queue. >> page_not_up_to_date: >> /* Get exclusive access to the page ... */ >> error = lock_page_killable(page); > I looked at the code in do_generic_file_read(). lock_page_killable > waits until the current read ahead is completed. > Is it possible to configure the read ahead to push multiple read > request to the block device queue?add When I first looked at this I used dd if=/dev/mmcblk0 of=/dev/null bs=1M count=4 If bs is larger than read ahead, this will make the execution loop in do_generic_file_read() reading 512 until 1M is read. The second time in this loop it will wait on lock_page_killable. If bs=16k the execution wont stuck at lock_page_killable. > > > Arnd > Thanks, Per -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html