From 128b4a831059b0152fe295ddef4ed29f71fb5cde Mon Sep 17 00:00:00 2001 From: Vijay Kumar Date: Wed, 18 Jan 2017 08:10:12 -0800 Subject: [PATCH] sparc64:block/sunvdc: Added io stats accounting for bio based vdisk As vdisk now bypass block layer and directly submits IO, iostats does not get accounted (which happens at block). Added IO accounting at bio layer for vdisk block device. Signed-off-by: Vijay Kumar Reviewed-by: Martin K. Petersen Orabug: 25128265 Signed-off-by: Allen Pais --- drivers/block/sunvdc.c | 44 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 5898a19030e00..55452ef7e095e 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -49,6 +49,7 @@ struct vdc_req_entry { struct bio *req; u64 size; int sent; + unsigned long start_time; }; struct vdc_port { @@ -277,6 +278,41 @@ static int vdc_handle_attr(struct vio_driver_state *vio, void *arg) } } +void vdc_start_io_acct (struct vdc_port *port, int rw, sector_t sec, + unsigned long nrsec) +{ + struct hd_struct *part; + int cpu; + + part = disk_map_sector_rcu(port->disk, sec); + cpu = part_stat_lock(); + + part_round_stats(cpu, part); + part_stat_inc(cpu, part, ios[rw]); + part_stat_add(cpu, part, sectors[rw], nrsec); + part_inc_in_flight(part, rw); + + part_stat_unlock(); +} + +void vdc_end_io_acct(struct vdc_port *port, int rw, unsigned long start_time, + sector_t sec) +{ + unsigned long duration = jiffies - start_time; + int cpu; + struct hd_struct *part; + + part = disk_map_sector_rcu(port->disk, sec); + cpu = part_stat_lock(); + + part_stat_add(cpu, part, ticks[rw], duration); + part_round_stats(cpu, part); + part_dec_in_flight(part, rw); + + part_stat_unlock(); +} + + static void vdc_end_special(struct vdc_port *port, int err) { vdc_finish(port->cmp, -err, WAITING_FOR_GEN_CMD); @@ -315,6 +351,9 @@ static void vdc_end_one(struct vdc_port *port, struct vio_dring_state *dr, BUG(); } + vdc_end_io_acct(port, bio_data_dir(req), rqe->start_time, + req->bi_iter.bi_sector); + bio_endio(req, err ? -EIO : 0); rqe->size = 0; } @@ -632,6 +671,7 @@ static int __create_rw_desc(struct vdc_port *port, struct request *req, rqe = &port->rq_arr[idx]; rqe->size = len; + rqe->start_time = jiffies; return 0; } @@ -711,6 +751,10 @@ static void vdc_make_request(struct request_queue *q, struct bio *bio) err = __create_rw_desc(port, &req, desc, idx); if (err) pr_err(PFX "__create_rw_desc() failed, err=%d\n", err); + + vdc_start_io_acct(port, bio_data_dir(bio), + bio->bi_iter.bi_sector, + bio_sectors(bio)); } if (!err) -- 2.50.1