diff -pru linux-2.6.18-53.orig/drivers/md/raid5.c linux-2.6.18-53/drivers/md/raid5.c --- linux-2.6.18-53.orig/drivers/md/raid5.c 2007-12-06 17:15:22.000000000 +0800 +++ linux-2.6.18-53/drivers/md/raid5.c 2007-12-06 17:17:30.000000000 +0800 @@ -115,10 +115,12 @@ static void __release_stripe(raid5_conf_ if (test_bit(STRIPE_DELAYED, &sh->state)) { list_add_tail(&sh->lru, &conf->delayed_list); blk_plug_device(conf->mddev->queue); + atomic_inc(&conf->delayed); } else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && sh->bm_seq - conf->seq_write > 0) { list_add_tail(&sh->lru, &conf->bitmap_list); blk_plug_device(conf->mddev->queue); + atomic_inc(&conf->bit_delayed); } else { clear_bit(STRIPE_BIT_DELAY, &sh->state); list_add_tail(&sh->lru, &conf->handle_list); @@ -289,6 +291,7 @@ static struct stripe_head *get_active_st if (noblock && sh == NULL) break; if (!sh) { + atomic_inc(&conf->out_of_stripes); conf->inactive_blocked = 1; wait_event_lock_irq(conf->wait_for_stripe, !list_empty(&conf->inactive_list) && @@ -311,6 +314,10 @@ static struct stripe_head *get_active_st !test_bit(STRIPE_EXPANDING, &sh->state)) BUG(); list_del_init(&sh->lru); + if (test_bit(STRIPE_DELAYED, &sh->state)) + atomic_dec(&conf->delayed); + if (test_bit(STRIPE_BIT_DELAY, &sh->state)) + atomic_dec(&conf->bit_delayed); } } } while (sh == NULL); @@ -529,6 +536,8 @@ static int raid5_end_read_request(struct if (bi->bi_size) return 1; + atomic_dec(&conf->out_reqs_in_queue); + for (i=0 ; idev[i].req) break; @@ -642,6 +651,8 @@ static int raid5_end_write_request (stru if (bi->bi_size) return 1; + atomic_dec(&conf->out_reqs_in_queue); + for (i=0 ; idev[i].req) break; @@ -1402,6 +1413,8 @@ static void handle_stripe5(struct stripe clear_bit(STRIPE_HANDLE, &sh->state); clear_bit(STRIPE_DELAYED, &sh->state); + atomic_inc(&conf->handle_called); + syncing = test_bit(STRIPE_SYNCING, &sh->state); expanding = test_bit(STRIPE_EXPAND_SOURCE, &sh->state); expanded = test_bit(STRIPE_EXPAND_READY, &sh->state); @@ -1684,6 +1697,7 @@ static void handle_stripe5(struct stripe set_bit(R5_LOCKED, &dev->flags); set_bit(R5_Wantread, &dev->flags); locked++; + atomic_inc(&conf->reads_for_rmw); } else { set_bit(STRIPE_DELAYED, &sh->state); set_bit(STRIPE_HANDLE, &sh->state); @@ -1703,6 +1717,7 @@ static void handle_stripe5(struct stripe set_bit(R5_LOCKED, &dev->flags); set_bit(R5_Wantread, &dev->flags); locked++; + atomic_inc(&conf->reads_for_rcw); } else { set_bit(STRIPE_DELAYED, &sh->state); set_bit(STRIPE_HANDLE, &sh->state); @@ -1870,6 +1885,7 @@ static void handle_stripe5(struct stripe bi->bi_next = NULL; bi->bi_size = 0; bi->bi_end_io(bi, bytes, 0); + atomic_dec(&conf->in_reqs_in_queue); } for (i=disks; i-- ;) { int rw; @@ -1885,10 +1901,13 @@ static void handle_stripe5(struct stripe bi = &sh->dev[i].req; bi->bi_rw = rw; - if (rw) + if (rw) { + atomic_inc(&conf->writes_out); bi->bi_end_io = raid5_end_write_request; - else + } else { + atomic_inc(&conf->reads_out); bi->bi_end_io = raid5_end_read_request; + } rcu_read_lock(); rdev = rcu_dereference(conf->disks[i].rdev); @@ -1919,6 +1938,7 @@ static void handle_stripe5(struct stripe if (rw == WRITE && test_bit(R5_ReWrite, &sh->dev[i].flags)) atomic_add(STRIPE_SECTORS, &rdev->corrected_errors); + atomic_inc(&conf->out_reqs_in_queue); generic_make_request(bi); } else { if (rw == 1) @@ -1955,6 +1975,8 @@ static void handle_stripe6(struct stripe clear_bit(STRIPE_HANDLE, &sh->state); clear_bit(STRIPE_DELAYED, &sh->state); + atomic_inc(&conf->handle_called); + syncing = test_bit(STRIPE_SYNCING, &sh->state); /* Now to look around and see what can be done */ @@ -2255,6 +2277,7 @@ static void handle_stripe6(struct stripe set_bit(R5_LOCKED, &dev->flags); set_bit(R5_Wantread, &dev->flags); locked++; + atomic_inc(&conf->reads_for_rcw); } else { PRINTK("Request delayed stripe %llu block %d for Reconstruct\n", (unsigned long long)sh->sector, i); @@ -2423,6 +2446,7 @@ static void handle_stripe6(struct stripe bi->bi_next = NULL; bi->bi_size = 0; bi->bi_end_io(bi, bytes, 0); + atomic_dec(&conf->in_reqs_in_queue); } for (i=disks; i-- ;) { int rw; @@ -2438,10 +2462,13 @@ static void handle_stripe6(struct stripe bi = &sh->dev[i].req; bi->bi_rw = rw; - if (rw) + if (rw) { + atomic_inc(&conf->writes_out); bi->bi_end_io = raid5_end_write_request; - else + } else { + atomic_inc(&conf->reads_out); bi->bi_end_io = raid5_end_read_request; + } rcu_read_lock(); rdev = rcu_dereference(conf->disks[i].rdev); @@ -2473,6 +2500,7 @@ static void handle_stripe6(struct stripe test_bit(R5_ReWrite, &sh->dev[i].flags)) atomic_add(STRIPE_SECTORS, &rdev->corrected_errors); generic_make_request(bi); + atomic_inc(&conf->out_reqs_in_queue); } else { if (rw == 1) set_bit(STRIPE_DEGRADED, &sh->state); @@ -2506,6 +2534,7 @@ static void raid5_activate_delayed(raid5 if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) atomic_inc(&conf->preread_active_stripes); list_add_tail(&sh->lru, &conf->handle_list); + atomic_dec(&conf->delayed); } } } @@ -2608,6 +2637,8 @@ static int make_request(request_queue_t const int rw = bio_data_dir(bi); int remaining; + atomic_inc(&conf->in_reqs_in_queue); + if (unlikely(bio_barrier(bi))) { bio_endio(bi, bi->bi_size, -EOPNOTSUPP); return 0; @@ -2617,6 +2648,11 @@ static int make_request(request_queue_t disk_stat_inc(mddev->gendisk, ios[rw]); disk_stat_add(mddev->gendisk, sectors[rw], bio_sectors(bi)); + if (rw == WRITE) + atomic_inc(&conf->writes_in); + else + atomic_inc(&conf->reads_in); + logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1); last_sector = bi->bi_sector + (bi->bi_size>>9); @@ -2724,6 +2760,7 @@ static int make_request(request_queue_t if ( rw == WRITE ) md_write_end(mddev); + atomic_dec(&conf->in_reqs_in_queue); bi->bi_size = 0; bi->bi_end_io(bi, bytes, 0); } @@ -2985,6 +3022,7 @@ static void raid5d (mddev_t *mddev) spin_unlock_irq(&conf->device_lock); handled++; + atomic_inc(&conf->handled_in_raid5d); handle_stripe(sh, conf->spare_page); release_stripe(sh); @@ -3381,6 +3419,21 @@ static void status (struct seq_file *seq conf->disks[i].rdev && test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_"); seq_printf (seq, "]"); + seq_printf (seq, "\n\t\tin: %u reads, %u writes; out: %u reads, %u writes", + atomic_read(&conf->reads_in), atomic_read(&conf->writes_in), + atomic_read(&conf->reads_out), atomic_read(&conf->writes_out)); + seq_printf (seq, "\n\t\t%u in raid5d, %u out of stripes, %u handle called", + atomic_read(&conf->handled_in_raid5d), + atomic_read(&conf->out_of_stripes), + atomic_read(&conf->handle_called)); + seq_printf (seq, "\n\t\treads: %u for rmw, %u for rcw", + atomic_read(&conf->reads_for_rmw), + atomic_read(&conf->reads_for_rcw)); + seq_printf (seq, "\n\t\t%u delayed, %u bit delayed, %u active, queues: %u in, %u out\n", + atomic_read(&conf->delayed), atomic_read(&conf->bit_delayed), + atomic_read(&conf->active_stripes), + atomic_read(&conf->in_reqs_in_queue), + atomic_read(&conf->out_reqs_in_queue)); #if RAID5_DEBUG seq_printf (seq, "\n"); printall(seq, conf); diff -pru linux-2.6.18-53.orig/include/linux/raid/raid5.h linux-2.6.18-53/include/linux/raid/raid5.h --- linux-2.6.18-53.orig/include/linux/raid/raid5.h 2007-12-06 17:15:22.000000000 +0800 +++ linux-2.6.18-53/include/linux/raid/raid5.h 2007-12-06 17:15:32.000000000 +0800 @@ -259,6 +259,25 @@ struct raid5_private_data { int pool_size; /* number of disks in stripeheads in pool */ spinlock_t device_lock; struct disk_info *disks; + + /* + * Stats + */ + atomic_t reads_in; + atomic_t writes_in; + atomic_t reads_out; + atomic_t writes_out; + atomic_t handled_in_raid5d; + atomic_t out_of_stripes; + atomic_t reads_for_rmw; + atomic_t reads_for_rcw; + atomic_t writes_zcopy; + atomic_t writes_copied; + atomic_t handle_called; + atomic_t delayed; + atomic_t bit_delayed; + atomic_t in_reqs_in_queue; + atomic_t out_reqs_in_queue; }; typedef struct raid5_private_data raid5_conf_t; Only in linux-2.6.18-53.orig/include/linux/raid: .raid5.h.swp