Index: linux-2.6/include/linux/blkdev.h =================================================================== --- linux-2.6.orig/include/linux/blkdev.h 2005-06-10 21:11:21.000000000 +1000 +++ linux-2.6/include/linux/blkdev.h 2005-06-10 21:20:53.000000000 +1000 @@ -137,7 +137,6 @@ struct request { int rq_status; /* should split this into a few status bits */ struct gendisk *rq_disk; int errors; - unsigned long start_time; /* Number of scatter-gather DMA addr+len pairs after * physical address coalescing is performed. @@ -368,6 +367,11 @@ struct request_queue struct kobject kobj; /* + * Jiffies. Time the current request was started + */ + unsigned long start_time; + + /* * queue settings */ unsigned long nr_requests; /* Max # of requests */ Index: linux-2.6/drivers/block/ll_rw_blk.c =================================================================== --- linux-2.6.orig/drivers/block/ll_rw_blk.c 2005-06-10 21:10:26.000000000 +1000 +++ linux-2.6/drivers/block/ll_rw_blk.c 2005-06-11 16:23:38.000000000 +1000 @@ -1914,10 +1914,13 @@ static struct request *get_request(reque } get_rq: + if (rl->count[READ] + rl->count[WRITE] == 0) + q->start_time = jiffies; rl->count[rw]++; rl->starved[rw] = 0; if (rl->count[rw] >= queue_congestion_on_threshold(q)) set_queue_congested(q, rw); + spin_unlock_irq(q->queue_lock); rq = blk_alloc_request(q, rw, gfp_mask); @@ -2487,15 +2490,6 @@ static int attempt_merge(request_queue_t if (!q->merge_requests_fn(q, req, next)) return 0; - /* - * At this point we have either done a back merge - * or front merge. We need the smaller start_time of - * the merged requests to be the current request - * for accounting purposes. - */ - if (time_after(req->start_time, next->start_time)) - req->start_time = next->start_time; - req->biotail->bi_next = next->bio; req->biotail = next->biotail; @@ -2703,7 +2697,6 @@ get_rq: req->waiting = NULL; req->bio = req->biotail = bio; req->rq_disk = bio->bi_bdev->bd_disk; - req->start_time = jiffies; add_request(q, req); out: @@ -3195,13 +3188,16 @@ EXPORT_SYMBOL(end_that_request_chunk); */ void end_that_request_last(struct request *req) { + request_queue_t *q = req->q; + unsigned long now = jiffies; struct gendisk *disk = req->rq_disk; if (unlikely(laptop_mode) && blk_fs_request(req)) laptop_io_completion(); if (disk && blk_fs_request(req)) { - unsigned long duration = jiffies - req->start_time; + unsigned long duration = now - q->start_time; + switch (rq_data_dir(req)) { case WRITE: __disk_stat_inc(disk, writes); @@ -3215,6 +3211,8 @@ void end_that_request_last(struct reques disk_round_stats(disk); disk->in_flight--; } + q->start_time = now; + if (req->end_io) req->end_io(req); else