Commit 6f2576af authored by Jerome Marchand's avatar Jerome Marchand Committed by Jens Axboe

Enhanced partition statistics: update partition statitics

Updates the enhanced partition statistics in generic block layer
besides the disk statistics.
Signed-off-by: default avatarJerome Marchand <jmarchan@redhat.com>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent ea5c48ab
......@@ -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++;
}
}
}
......@@ -997,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
*/
......@@ -1530,7 +1550,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;
......@@ -1715,11 +1736,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)
......
......@@ -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);
......
......@@ -18,6 +18,7 @@
#include <linux/fs.h>
#include <linux/kmod.h>
#include <linux/ctype.h>
#include <linux/genhd.h>
#include "check.h"
......@@ -273,6 +274,7 @@ static struct attribute_group *part_attr_groups[] = {
static void part_release(struct device *dev)
{
struct hd_struct *p = dev_to_part(dev);
free_part_stats(p);
kfree(p);
}
......@@ -314,6 +316,7 @@ void delete_partition(struct gendisk *disk, int part)
p->nr_sects = 0;
p->ios[0] = p->ios[1] = 0;
p->sectors[0] = p->sectors[1] = 0;
part_stat_set_all(p, 0);
kobject_put(p->holder_dir);
device_del(&p->dev);
put_device(&p->dev);
......@@ -336,6 +339,10 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len,
if (!p)
return;
if (!init_part_stats(p)) {
kfree(p);
return;
}
p->start_sect = start;
p->nr_sects = len;
p->partno = part;
......
......@@ -365,6 +365,7 @@ static inline void free_part_stats(struct hd_struct *part)
/* drivers/block/ll_rw_blk.c */
extern void disk_round_stats(struct gendisk *disk);
extern void part_round_stats(struct hd_struct *part);
/* drivers/block/genhd.c */
extern int get_blkdev_list(char *, int);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment