Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03054de1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block

* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
  Enhanced partition statistics: documentation update
  Enhanced partition statistics: remove old partition statistics
  Enhanced partition statistics: procfs
  Enhanced partition statistics: sysfs
  Enhanced partition statistics: aoe fix
  Enhanced partition statistics: update partition statitics
  Enhanced partition statistics: core statistics
  block: fixup rq_init() a bit

Manually fixed conflict in drivers/block/aoe/aoecmd.c due to statistics
support.
parents b5eb9513 0e53c2be
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
What:		/proc/diskstats
Date:		February 2008
Contact:	Jerome Marchand <jmarchan@redhat.com>
Description:
		The /proc/diskstats file displays the I/O statistics
		of block devices. Each line contains the following 14
		fields:
		 1 - major number
		 2 - minor mumber
		 3 - device name
		 4 - reads completed succesfully
		 5 - reads merged
		 6 - sectors read
		 7 - time spent reading (ms)
		 8 - writes completed
		 9 - writes merged
		10 - sectors written
		11 - time spent writing (ms)
		12 - I/Os currently in progress
		13 - time spent doing I/Os (ms)
		14 - weighted time spent doing I/Os (ms)
		For more details refer to Documentation/iostats.txt
+28 −0
Original line number Diff line number Diff line
What:		/sys/block/<disk>/stat
Date:		February 2008
Contact:	Jerome Marchand <jmarchan@redhat.com>
Description:
		The /sys/block/<disk>/stat files displays the I/O
		statistics of disk <disk>. They contain 11 fields:
		 1 - reads completed succesfully
		 2 - reads merged
		 3 - sectors read
		 4 - time spent reading (ms)
		 5 - writes completed
		 6 - writes merged
		 7 - sectors written
		 8 - time spent writing (ms)
		 9 - I/Os currently in progress
		10 - time spent doing I/Os (ms)
		11 - weighted time spent doing I/Os (ms)
		For more details refer Documentation/iostats.txt


What:		/sys/block/<disk>/<part>/stat
Date:		February 2008
Contact:	Jerome Marchand <jmarchan@redhat.com>
Description:
		The /sys/block/<disk>/<part>/stat files display the
		I/O statistics of partition <part>. The format is the
		same as the above-written /sys/block/<disk>/stat
		format.
+14 −1
Original line number Diff line number Diff line
@@ -58,7 +58,7 @@ they should not wrap twice before you notice them.
Each set of stats only applies to the indicated device; if you want
system-wide stats you'll have to find all the devices and sum them all up.

Field  1 -- # of reads issued
Field  1 -- # of reads completed
    This is the total number of reads completed successfully.
Field  2 -- # of reads merged, field 6 -- # of writes merged
    Reads and writes which are adjacent to each other may be merged for
@@ -132,6 +132,19 @@ words, the number of reads for partitions is counted slightly before time
of queuing for partitions, and at completion for whole disks.  This is
a subtle distinction that is probably uninteresting for most cases.

More significant is the error induced by counting the numbers of
reads/writes before merges for partitions and after for disks. Since a
typical workload usually contains a lot of successive and adjacent requests,
the number of reads/writes issued can be several times higher than the
number of reads/writes completed.

In 2.6.25, the full statistic set is again available for partitions and
disk and partition statistics are consistent again. Since we still don't
keep record of the partition-relative address, an operation is attributed to
the partition which contains the first sector of the request after the
eventual merges. As requests can be merged across partition, this could lead
to some (probably insignificant) innacuracy.

Additional notes
----------------

+47 −14
Original line number Diff line number Diff line
@@ -60,10 +60,15 @@ static void drive_stat_acct(struct request *rq, int new_io)
		return;

	if (!new_io) {
		__disk_stat_inc(rq->rq_disk, merges[rw]);
		__all_stat_inc(rq->rq_disk, merges[rw], rq->sector);
	} else {
		struct hd_struct *part = get_part(rq->rq_disk, rq->sector);
		disk_round_stats(rq->rq_disk);
		rq->rq_disk->in_flight++;
		if (part) {
			part_round_stats(part);
			part->in_flight++;
		}
	}
}

@@ -102,27 +107,38 @@ struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev)
}
EXPORT_SYMBOL(blk_get_backing_dev_info);

/*
 * We can't just memset() the structure, since the allocation path
 * already stored some information in the request.
 */
void rq_init(struct request_queue *q, struct request *rq)
{
	INIT_LIST_HEAD(&rq->queuelist);
	INIT_LIST_HEAD(&rq->donelist);

	rq->errors = 0;
	rq->q = q;
	rq->sector = rq->hard_sector = (sector_t) -1;
	rq->nr_sectors = rq->hard_nr_sectors = 0;
	rq->current_nr_sectors = rq->hard_cur_sectors = 0;
	rq->bio = rq->biotail = NULL;
	INIT_HLIST_NODE(&rq->hash);
	RB_CLEAR_NODE(&rq->rb_node);
	rq->rq_disk = NULL;
	rq->nr_phys_segments = 0;
	rq->nr_hw_segments = 0;
	rq->ioprio = 0;
	rq->special = NULL;
	rq->buffer = NULL;
	rq->tag = -1;
	rq->errors = 0;
	rq->ref_count = 1;
	rq->q = q;
	rq->special = NULL;
	rq->cmd_len = 0;
	memset(rq->cmd, 0, sizeof(rq->cmd));
	rq->data_len = 0;
	rq->sense_len = 0;
	rq->data = NULL;
	rq->nr_phys_segments = 0;
	rq->sense = NULL;
	rq->end_io = NULL;
	rq->end_io_data = NULL;
	rq->completion_data = NULL;
	rq->next_rq = NULL;
}

@@ -986,6 +1002,21 @@ void disk_round_stats(struct gendisk *disk)
}
EXPORT_SYMBOL_GPL(disk_round_stats);

void part_round_stats(struct hd_struct *part)
{
	unsigned long now = jiffies;

	if (now == part->stamp)
		return;

	if (part->in_flight) {
		__part_stat_add(part, time_in_queue,
				part->in_flight * (now - part->stamp));
		__part_stat_add(part, io_ticks, (now - part->stamp));
	}
	part->stamp = now;
}

/*
 * queue lock must be held
 */
@@ -1188,10 +1219,6 @@ static inline void blk_partition_remap(struct bio *bio)

	if (bio_sectors(bio) && bdev != bdev->bd_contains) {
		struct hd_struct *p = bdev->bd_part;
		const int rw = bio_data_dir(bio);

		p->sectors[rw] += bio_sectors(bio);
		p->ios[rw]++;

		bio->bi_sector += p->start_sect;
		bio->bi_bdev = bdev->bd_contains;
@@ -1519,7 +1546,8 @@ static int __end_that_request_first(struct request *req, int error,
	if (blk_fs_request(req) && req->rq_disk) {
		const int rw = rq_data_dir(req);

		disk_stat_add(req->rq_disk, sectors[rw], nr_bytes >> 9);
		all_stat_add(req->rq_disk, sectors[rw],
			     nr_bytes >> 9, req->sector);
	}

	total_bytes = bio_nbytes = 0;
@@ -1704,11 +1732,16 @@ static void end_that_request_last(struct request *req, int error)
	if (disk && blk_fs_request(req) && req != &req->q->bar_rq) {
		unsigned long duration = jiffies - req->start_time;
		const int rw = rq_data_dir(req);
		struct hd_struct *part = get_part(disk, req->sector);

		__disk_stat_inc(disk, ios[rw]);
		__disk_stat_add(disk, ticks[rw], duration);
		__all_stat_inc(disk, ios[rw], req->sector);
		__all_stat_add(disk, ticks[rw], duration, req->sector);
		disk_round_stats(disk);
		disk->in_flight--;
		if (part) {
			part_round_stats(part);
			part->in_flight--;
		}
	}

	if (req->end_io)
+6 −0
Original line number Diff line number Diff line
@@ -454,8 +454,14 @@ static int attempt_merge(struct request_queue *q, struct request *req,
	elv_merge_requests(q, req, next);

	if (req->rq_disk) {
		struct hd_struct *part
			= get_part(req->rq_disk, req->sector);
		disk_round_stats(req->rq_disk);
		req->rq_disk->in_flight--;
		if (part) {
			part_round_stats(part);
			part->in_flight--;
		}
	}

	req->ioprio = ioprio_best(req->ioprio, next->ioprio);
Loading