@@ -5384,6 +5384,14 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE;
bfqq->new_ioprio = 7;
break;
+ case IOPRIO_CLASS_DL:
+ /*
+ * For the duration-limits class, we want the disk to do the
+ * scheduling. So map all levels to the highest RT level.
+ */
+ bfqq->new_ioprio = 0;
+ bfqq->new_ioprio_class = IOPRIO_CLASS_RT;
+ break;
}
if (bfqq->new_ioprio >= IOPRIO_NR_LEVELS) {
@@ -5510,6 +5518,8 @@ static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd,
return &bfqg->async_bfqq[1][ioprio];
case IOPRIO_CLASS_IDLE:
return &bfqg->async_idle_bfqq;
+ case IOPRIO_CLASS_DL:
+ return &bfqg->async_bfqq[0][0];
default:
return NULL;
}
@@ -27,6 +27,7 @@
* @POLICY_RESTRICT_TO_BE: modify IOPRIO_CLASS_NONE and IOPRIO_CLASS_RT into
* IOPRIO_CLASS_BE.
* @POLICY_ALL_TO_IDLE: change the I/O priority class into IOPRIO_CLASS_IDLE.
+ * @POLICY_ALL_TO_DL: change the I/O priority class into IOPRIO_CLASS_DL.
*
* See also <linux/ioprio.h>.
*/
@@ -35,6 +36,7 @@ enum prio_policy {
POLICY_NONE_TO_RT = 1,
POLICY_RESTRICT_TO_BE = 2,
POLICY_ALL_TO_IDLE = 3,
+ POLICY_ALL_TO_DL = 4,
};
static const char *policy_name[] = {
@@ -42,6 +44,7 @@ static const char *policy_name[] = {
[POLICY_NONE_TO_RT] = "none-to-rt",
[POLICY_RESTRICT_TO_BE] = "restrict-to-be",
[POLICY_ALL_TO_IDLE] = "idle",
+ [POLICY_ALL_TO_DL] = "duration-limits",
};
static struct blkcg_policy ioprio_policy;
@@ -37,6 +37,7 @@ int ioprio_check_cap(int ioprio)
switch (class) {
case IOPRIO_CLASS_RT:
+ case IOPRIO_CLASS_DL:
/*
* Originally this only checked for CAP_SYS_ADMIN,
* which was implicitly allowed for pid 0 by security
@@ -47,7 +48,7 @@ int ioprio_check_cap(int ioprio)
if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_NICE))
return -EPERM;
fallthrough;
- /* rt has prio field too */
+ /* RT and DL have prio field too */
case IOPRIO_CLASS_BE:
if (data >= IOPRIO_NR_LEVELS || data < 0)
return -EINVAL;
@@ -113,6 +113,7 @@ static const enum dd_prio ioprio_class_to_prio[] = {
[IOPRIO_CLASS_RT] = DD_RT_PRIO,
[IOPRIO_CLASS_BE] = DD_BE_PRIO,
[IOPRIO_CLASS_IDLE] = DD_IDLE_PRIO,
+ [IOPRIO_CLASS_DL] = DD_RT_PRIO,
};
static inline struct rb_root *
@@ -20,7 +20,7 @@ static inline bool ioprio_valid(unsigned short ioprio)
{
unsigned short class = IOPRIO_PRIO_CLASS(ioprio);
- return class > IOPRIO_CLASS_NONE && class <= IOPRIO_CLASS_IDLE;
+ return class > IOPRIO_CLASS_NONE && class <= IOPRIO_CLASS_DL;
}
/*
@@ -29,6 +29,7 @@ enum {
IOPRIO_CLASS_RT,
IOPRIO_CLASS_BE,
IOPRIO_CLASS_IDLE,
+ IOPRIO_CLASS_DL,
};
/*
@@ -37,6 +38,12 @@ enum {
#define IOPRIO_NR_LEVELS 8
#define IOPRIO_BE_NR IOPRIO_NR_LEVELS
+/*
+ * The Duration limits class allows 8 levels: level 0 for "no limit" and levels
+ * 1 to 7, each corresponding to a read or write limit descriptor.
+ */
+#define IOPRIO_DL_NR_LEVELS 8
+
enum {
IOPRIO_WHO_PROCESS = 1,
IOPRIO_WHO_PGRP,