aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMing Lin <mlin@kernel.org>2015-07-16 15:14:03 -0700
committerMing Lin <mlin@kernel.org>2015-07-23 11:15:32 -0700
commiteadb541104d5ee4edca0f6f6498cb6d3924de7f6 (patch)
tree8e1d6647ea66933c67c5785023acf54a08f1d176
parentbdb987cd65fec3af6f299d0a50dfad3876df88e2 (diff)
downloadlinux-eadb541104d5ee4edca0f6f6498cb6d3924de7f6.tar.gz
BIO split statisticsblock-generic-req-test
-rw-r--r--block/blk-merge.c12
-rw-r--r--block/blk-sysfs.c26
-rw-r--r--include/linux/blkdev.h9
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 */