Commit 67e0c687 authored by Yu Kuai's avatar Yu Kuai
Browse files

blk-io-hierarchy: support hierarchy stats for bio lifetime

hulk inclusion
category: feature
bugzilla: https://gitee.com/openeuler/release-management/issues/IB4E8P


CVE: NA

--------------------------------

Like blk-throttle, following new debugfs entries will be created for
rq-based disk:

/sys/kernel/debug/block/sda/blk_io_hierarchy/
|-- bio
|   |-- io_dump
|   |-- stats
|   `-- threshold

User can use them to analyze how bio behaves.

Signed-off-by: default avatarYu Kuai <yukuai3@huawei.com>
parent d8d1551b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "blk.h"
#include "blk-rq-qos.h"
#include "blk-cgroup.h"
#include "blk-io-hierarchy/stats.h"

#define ALLOC_CACHE_THRESHOLD	16
#define ALLOC_CACHE_MAX		256
@@ -230,6 +231,7 @@ void bio_uninit(struct bio *bio)
		bio->pid = NULL;
	}
#endif
	bio_hierarchy_end(bio);
}
EXPORT_SYMBOL(bio_uninit);

+7 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@
#include "blk-cgroup.h"
#include "blk-throttle.h"
#include "blk-ioprio.h"
#include "blk-io-hierarchy/stats.h"

struct dentry *blk_debugfs_root;

@@ -835,6 +836,12 @@ void submit_bio_noacct(struct bio *bio)
		break;
	}

	/*
	 * On the one hand REQ_PREFLUSH | REQ_FUA can be cleared above, on the
	 * other hand it doesn't make sense to count invalid bio. Split bio will
	 * be accounted separately.
	 */
	bio_hierarchy_start(bio);
	if (blk_throtl_bio(bio))
		return;
	submit_bio_noacct_nocheck(bio);
+11 −0
Original line number Diff line number Diff line
@@ -142,4 +142,15 @@ config HIERARCHY_RQ_DRIVER

	If unsure, say N.

config HIERARCHY_BIO
	bool "Support to record stats for bio lifetime"
	default n
	select BLK_BIO_ALLOC_TIME
	help
	Enabling this lets blk hierarchy stats to record additional information
	for bio. Such information can be helpful to debug performance
	and problems like io hang.

	If unsure, say N.

endif
+12 −2
Original line number Diff line number Diff line
@@ -790,9 +790,11 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
	if (unlikely(rq->rq_flags & RQF_QUIET))
		bio_set_flag(bio, BIO_QUIET);
	/* don't actually finish bio if it's part of flush sequence */
	if (bio->bi_iter.bi_size == 0 && !(rq->rq_flags & RQF_FLUSH_SEQ))
	if (bio->bi_iter.bi_size == 0 && !(rq->rq_flags & RQF_FLUSH_SEQ)) {
		req_bio_hierarchy_end(rq, bio);
		bio_endio(bio);
	}
}

static void blk_account_io_completion(struct request *req, unsigned int bytes)
{
@@ -856,8 +858,10 @@ static void blk_complete_request(struct request *req)
		if (req_op(req) == REQ_OP_ZONE_APPEND)
			bio->bi_iter.bi_sector = req->__sector;

		if (!is_flush)
		if (!is_flush) {
			req_bio_hierarchy_end(req, bio);
			bio_endio(bio);
		}
		bio = next;
	} while (bio);

@@ -1115,6 +1119,7 @@ void blk_mq_end_request_batch(struct io_comp_batch *iob)
		prefetch(rq->bio);
		prefetch(rq->rq_next);

		rq->io_end_time_ns = now;
		blk_complete_request(rq);
		if (iob->need_ts)
			__blk_mq_end_request_acct(rq, now);
@@ -3043,6 +3048,8 @@ void blk_mq_submit_bio(struct bio *bio)
			bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
			if (!bio)
				return;
			/* account for split bio. */
			bio_hierarchy_start(bio);
		}
		if (!bio_integrity_prep(bio))
			return;
@@ -3058,6 +3065,8 @@ void blk_mq_submit_bio(struct bio *bio)
			bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
			if (!bio)
				goto fail;
			/* account for split bio. */
			bio_hierarchy_start(bio);
		}
		if (!bio_integrity_prep(bio))
			goto fail;
@@ -4412,6 +4421,7 @@ static void blk_mq_unregister_default_hierarchy(struct request_queue *q)
	blk_mq_unregister_hierarchy(q, STAGE_HCTX);
	blk_mq_unregister_hierarchy(q, STAGE_REQUEUE);
	blk_mq_unregister_hierarchy(q, STAGE_RQ_DRIVER);
	blk_mq_unregister_hierarchy(q, STAGE_BIO);
}

/* tags can _not_ be used after returning from blk_mq_exit_queue */
+1 −0
Original line number Diff line number Diff line
@@ -826,6 +826,7 @@ static void blk_mq_register_default_hierarchy(struct request_queue *q)
	blk_mq_register_hierarchy(q, STAGE_HCTX);
	blk_mq_register_hierarchy(q, STAGE_REQUEUE);
	blk_mq_register_hierarchy(q, STAGE_RQ_DRIVER);
	blk_mq_register_hierarchy(q, STAGE_BIO);
}

/**