diff options
| author | Ming Lin <mlin@kernel.org> | 2015-07-16 15:14:03 -0700 |
|---|---|---|
| committer | Ming Lin <mlin@kernel.org> | 2015-07-23 11:15:32 -0700 |
| commit | eadb541104d5ee4edca0f6f6498cb6d3924de7f6 (patch) | |
| tree | 8e1d6647ea66933c67c5785023acf54a08f1d176 | |
| parent | bdb987cd65fec3af6f299d0a50dfad3876df88e2 (diff) | |
| download | linux-eadb541104d5ee4edca0f6f6498cb6d3924de7f6.tar.gz | |
BIO split statisticsblock-generic-req-test
| -rw-r--r-- | block/blk-merge.c | 12 | ||||
| -rw-r--r-- | block/blk-sysfs.c | 26 | ||||
| -rw-r--r-- | include/linux/blkdev.h | 9 |
3 files changed, 44 insertions, 3 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c index 1f5dfa0552b94..944ceedba29ea 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -128,18 +128,24 @@ void blk_queue_split(struct request_queue *q, struct bio **bio, struct bio_set *bs) { struct bio *split; + int i; - if ((*bio)->bi_rw & REQ_DISCARD) + if ((*bio)->bi_rw & REQ_DISCARD) { split = blk_bio_discard_split(q, *bio, bs); - else if ((*bio)->bi_rw & REQ_WRITE_SAME) + i = DISCARD_SPLIT; + } else if ((*bio)->bi_rw & REQ_WRITE_SAME) { split = blk_bio_write_same_split(q, *bio, bs); - else + i = WRITE_SAME_SPLIT; + } else { split = blk_bio_segment_split(q, *bio, q->bio_split); + i = SEGMENT_SPLIT; + } if (split) { bio_chain(split, *bio); generic_make_request(*bio); *bio = split; + q->split_stat[i]++; } } EXPORT_SYMBOL(blk_queue_split); diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 9a25db35e854a..174ee9318be90 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -191,6 +191,25 @@ static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page) return queue_var_show(max_hw_sectors_kb, (page)); } +static ssize_t queue_split_show(struct request_queue *q, char *page) +{ + return sprintf(page, "discard split: %lu, write same split: %lu, segment split: %lu\n", + q->split_stat[DISCARD_SPLIT], + q->split_stat[WRITE_SAME_SPLIT], + q->split_stat[SEGMENT_SPLIT]); +} + +static ssize_t +queue_split_store(struct request_queue *q, const char *page, size_t count) +{ + int i; + + for (i = 0; i < SPLIT_NUM; i++) + q->split_stat[i] = 0; + + return count; +} + #define QUEUE_SYSFS_BIT_FNS(name, flag, neg) \ static ssize_t \ queue_show_##name(struct request_queue *q, char *page) \ @@ -405,6 +424,12 @@ static struct queue_sysfs_entry queue_random_entry = { .store = queue_store_random, }; +static struct queue_sysfs_entry queue_split_entry = { + .attr = {.name = "split", .mode = S_IRUGO | S_IWUSR }, + .show = queue_split_show, + .store = queue_split_store, +}; + static struct attribute *default_attrs[] = { &queue_requests_entry.attr, &queue_ra_entry.attr, @@ -428,6 +453,7 @@ static struct attribute *default_attrs[] = { &queue_rq_affinity_entry.attr, &queue_iostats_entry.attr, &queue_random_entry.attr, + &queue_split_entry.attr, NULL, }; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 56cf082c5fd10..c46792786ba94 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -275,6 +275,13 @@ struct queue_limits { unsigned char raid_partial_stripes_expensive; }; +enum { + DISCARD_SPLIT, + WRITE_SAME_SPLIT, + SEGMENT_SPLIT, + SPLIT_NUM, +}; + struct request_queue { /* * Together with queue_head for cacheline sharing @@ -454,6 +461,8 @@ struct request_queue { struct blk_mq_tag_set *tag_set; struct list_head tag_set_list; struct bio_set *bio_split; + + unsigned long split_stat[SPLIT_NUM]; }; #define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */ |
