Tuesday, July 5, 2011

Block Read Performance improvement in __bread()

My Code Changes in __bread function so that we should check the block block number and size limit before looking for the buffer into the Per-CPU cache list and Radix Tree Page Cache in __find_get_block_slow function.

bash-3.2$ diff -u buffer_backup.c fs/buffer.c
--- buffer_backup.c 2011-07-05 13:01:28.950511000 +0530
+++ fs/buffer.c 2011-07-05 13:03:02.339457000 +0530
@@ -1084,18 +1084,6 @@
static struct buffer_head *
__getblk_slow(struct block_device *bdev, sector_t block, int size)
{
- /* Size must be multiple of hard sectorsize */
- if (unlikely(size & (bdev_logical_block_size(bdev)-1) ||
- (size < 512 || size > PAGE_SIZE))) {
- printk(KERN_ERR "getblk(): invalid block size %d requested\n",
- size);
- printk(KERN_ERR "logical block size: %d\n",
- bdev_logical_block_size(bdev));
-
- dump_stack();
- return NULL;
- }
-
for (;;) {
struct buffer_head * bh;
int ret;
@@ -1411,7 +1399,21 @@
struct buffer_head *
__bread(struct block_device *bdev, sector_t block, unsigned size)
{
- struct buffer_head *bh = __getblk(bdev, block, size);
+ struct buffer_head *bh;
+
+ /* Size must be multiple of hard sectorsize */
+ if (unlikely(size & (bdev_logical_block_size(bdev)-1) ||
+ (size < 512 || size > PAGE_SIZE))) {
+ printk(KERN_ERR "getblk(): invalid block size %d requested\n",
+ size);
+ printk(KERN_ERR "logical block size: %d\n",
+ bdev_logical_block_size(bdev));
+
+ dump_stack();
+ return NULL;
+ }
+
+ bh = __getblk(bdev, block, size);

if (likely(bh) && !buffer_uptodate(bh))
bh = __bread_slow(bh);