From 1d42bea919090c89b016e30482260475ea53a724 Mon Sep 17 00:00:00 2001 From: Corrado Zoccolo Date: Fri, 23 Apr 2010 22:21:30 +0200 Subject: [PATCH 1/2] cfq-iosched: introduce bandwidth measurement --- block/cfq-iosched.c | 30 ++++++++++++++++++++++++++++-- 1 files changed, 28 insertions(+), 2 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 838834b..6551726 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -54,7 +54,7 @@ static const int cfq_hist_divisor = 4; #define RQ_CIC(rq) \ ((struct cfq_io_context *) (rq)->elevator_private) -#define RQ_CFQQ(rq) (struct cfq_queue *) ((rq)->elevator_private2) +#define RQ_CFQQ(rq) ((struct cfq_queue *) ((rq)->elevator_private2)) static struct kmem_cache *cfq_pool; static struct kmem_cache *cfq_ioc_pool; @@ -145,6 +145,7 @@ struct cfq_queue { struct cfq_group *orig_cfqg; /* Sectors dispatched in current dispatch round */ unsigned long nr_sectors; + unsigned transferred; }; /* @@ -241,6 +242,12 @@ struct cfq_data { */ int hw_tag_est_depth; unsigned int hw_tag_samples; + /* + * performance measurements + * max_bw is indexed by coop flag. + */ + unsigned max_bw[2]; + unsigned cur_bw; /* * idle window management @@ -1422,6 +1429,7 @@ static void cfq_activate_request(struct request_queue *q, struct request *rq) cfqd->rq_in_driver); cfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq); + RQ_CFQQ(rq)->transferred += blk_rq_sectors(rq); } static void cfq_deactivate_request(struct request_queue *q, struct request *rq) @@ -1430,6 +1438,7 @@ static void cfq_deactivate_request(struct request_queue *q, struct request *rq) WARN_ON(!cfqd->rq_in_driver); cfqd->rq_in_driver--; + RQ_CFQQ(rq)->transferred -= blk_rq_sectors(rq); cfq_log_cfqq(cfqd, RQ_CFQQ(rq), "deactivate rq, drv=%d", cfqd->rq_in_driver); } @@ -1552,6 +1561,8 @@ static void __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, bool timed_out) { + unsigned used_slice = jiffies - cfqq->slice_start; + unsigned bw = cfqd->max_bw[1]; cfq_log_cfqq(cfqd, cfqq, "slice expired t=%d", timed_out); if (cfq_cfqq_wait_request(cfqq)) @@ -1560,13 +1571,20 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, cfq_clear_cfqq_wait_request(cfqq); cfq_clear_cfqq_wait_busy(cfqq); + if (used_slice > HZ / 100 && used_slice > 2) { + bw = cfqq->transferred / used_slice; + cfqd->cur_bw = bw; + cfqd->max_bw[cfq_cfqq_coop(cfqq)] = + max(cfqd->max_bw[cfq_cfqq_coop(cfqq)], bw); + } + cfqq->transferred = 0; /* * If this cfqq is shared between multiple processes, check to * make sure that those processes are still issuing I/Os within * the mean seek distance. If not, it may be time to break the * queues apart again. */ - if (cfq_cfqq_coop(cfqq) && CFQQ_SEEKY(cfqq)) + if (cfq_cfqq_coop(cfqq) && bw <= cfqd->max_bw[1] * 9/10) cfq_mark_cfqq_split_coop(cfqq); /* @@ -3776,6 +3794,13 @@ fail: /* * sysfs parts below --> */ +static ssize_t bandwidth_show(struct elevator_queue *e, char *page) +{ + struct cfq_data *cfqd = e->elevator_data; + return sprintf(page, "%d\t%d\t%d\n", cfqd->cur_bw, + cfqd->max_bw[0], cfqd->max_bw[1]); +} + static ssize_t cfq_var_show(unsigned int var, char *page) { @@ -3861,6 +3886,7 @@ static struct elv_fs_entry cfq_attrs[] = { CFQ_ATTR(slice_idle), CFQ_ATTR(low_latency), CFQ_ATTR(group_isolation), + __ATTR_RO(bandwidth), __ATTR_NULL }; -- 1.6.2.5