@@ -228,6 +228,21 @@ config BLOCK_HOLDER_DEPRECATED
config BLK_MQ_STACKING
bool
+config BLK_CONT_ACT_BASED_IOPRIO
+ bool "Enable content activity based ioprio"
+ depends on LRU_GEN
+ default n
+ help
+ This item enable the feature of adjust bio's priority by
+ calculating its content's activity.
+ This feature works as a hint of original bio_set_ioprio
+ which means rt task get no change of its bio->bi_ioprio
+ while other tasks have the opportunity to raise the ioprio
+ if the bio take certain numbers of active pages.
+ The file system should use the API after bio_add_folio for
+ their buffered read/write/sync function to adjust the
+ bio->bi_ioprio.
+
source "block/Kconfig.iosched"
endif # BLOCK
@@ -1476,6 +1476,40 @@ void bio_set_pages_dirty(struct bio *bio)
}
EXPORT_SYMBOL_GPL(bio_set_pages_dirty);
+/*
+ * bio_set_active_ioprio_folio is helper function to count the bio's
+ * content's activities which measured by MGLRU.
+ * The file system should call this function after bio_add_page/folio for
+ * the buffered read/write/sync.
+ */
+#ifdef CONFIG_BLK_CONT_ACT_BASED_IOPRIO
+void bio_set_active_ioprio_folio(struct bio *bio, struct folio *folio)
+{
+ int class, level, hint;
+ int activities;
+
+ /*
+ * use bi_ioprio to record the activities, assume no one will set it
+ * before submit_bio
+ */
+ bio->bi_ioprio += folio_test_workingset(folio) ? 1 : 0;
+ activities = IOPRIO_PRIO_DATA(bio->bi_ioprio);
+ class = IOPRIO_PRIO_CLASS(bio->bi_ioprio);
+ level = IOPRIO_PRIO_LEVEL(bio->bi_ioprio);
+ hint = IOPRIO_PRIO_HINT(bio->bi_ioprio);
+
+ if (activities > bio->bi_vcnt / 2)
+ class = IOPRIO_CLASS_RT;
+ else if (activities > bio->bi_vcnt / 4)
+ class = max(IOPRIO_PRIO_CLASS(get_current_ioprio()), IOPRIO_CLASS_BE);
+
+ bio->bi_ioprio = IOPRIO_PRIO_VALUE_HINT(class, level, hint);
+}
+#else
+void bio_set_active_ioprio_folio(struct bio *bio, struct folio *folio) {}
+#endif
+EXPORT_SYMBOL_GPL(bio_set_active_ioprio_folio);
+
/*
* bio_check_pages_dirty() will check that all the BIO's pages are still dirty.
* If they are, then fine. If, however, some pages are clean then they must
@@ -487,6 +487,7 @@ void bio_iov_bvec_set(struct bio *bio, struct iov_iter *iter);
void __bio_release_pages(struct bio *bio, bool mark_dirty);
extern void bio_set_pages_dirty(struct bio *bio);
extern void bio_check_pages_dirty(struct bio *bio);
+void bio_set_active_ioprio_folio(struct bio *bio, struct folio *folio);
extern void bio_copy_data_iter(struct bio *dst, struct bvec_iter *dst_iter,
struct bio *src, struct bvec_iter *src_iter);