@@ -54,6 +54,7 @@ enum dd_prio {
enum { DD_PRIO_COUNT = 3 };
+#define CFS_PROP_THRESHOLD 60
/*
* I/O statistics per I/O priority. It is fine if these counters overflow.
* What matters is that these counters are at least as wide as
@@ -802,6 +803,7 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
u8 ioprio_class = IOPRIO_PRIO_CLASS(ioprio);
struct dd_per_prio *per_prio;
enum dd_prio prio;
+ int fifo_expire;
lockdep_assert_held(&dd->lock);
@@ -828,6 +830,7 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
rq->fifo_time = jiffies;
} else {
struct list_head *insert_before;
+ unsigned long se_prop, rq_prop;
deadline_add_rq_rb(per_prio, rq);
@@ -839,8 +842,21 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
/*
* set expire time and add to fifo list
+ * The expire time is adjusted when current CFS task is
+ * over-preempted by RT/DL/IRQ which is calculated by the
+ * proportion of cfs_rq's activation among whole cpu time during
+ * last several dozen's ms.Whearas, this would NOT affect the
+ * rq's position in fifo_list but only take effect when this
+ * rq is checked for its expire time when at head.
*/
- rq->fifo_time = jiffies + dd->fifo_expire[data_dir];
+ fifo_expire = dd->fifo_expire[data_dir];
+ if (data_dir == DD_READ &&
+ cfs_prop_by_util(current, &se_prop, &rq_prop) &&
+ rq_prop < CFS_PROP_THRESHOLD)
+ fifo_expire = dd->fifo_expire[data_dir] * rq_prop / 100;
+
+ rq->fifo_time = jiffies + fifo_expire;
+
insert_before = &per_prio->fifo_list[data_dir];
#ifdef CONFIG_BLK_DEV_ZONED
/*