scsi: block: ioprio: Clean up interface definition
authorDamien Le Moal <dlemoal@kernel.org>
Thu, 11 May 2023 01:13:34 +0000 (03:13 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 22 May 2023 21:05:18 +0000 (17:05 -0400)
The I/O priority user interface defines the 16-bits ioprio values as the
combination of the upper 3-bits for an I/O priority class and the lower
13-bits as priority data. However, the kernel only uses the lower 3-bits of
the priority data to define priority levels for the RT and BE priority
classes. The data part of an ioprio value is completely ignored for the
IDLE and NONE classes. This is enforced by checks done in
ioprio_check_cap(), which is called for all paths that allow defining an
I/O priority for I/Os: the per-context ioprio_set() system call, aio
interface and io_uring interface.

Clarify this fact in the uapi ioprio.h header file and introduce the
IOPRIO_PRIO_LEVEL_MASK and IOPRIO_PRIO_LEVEL() macros for users to define
and get priority levels in an ioprio value. The coarser macro
IOPRIO_PRIO_DATA() is retained for backward compatibility with old
applications already using it. There is no functional change introduced
with this.

In-kernel users of the IOPRIO_PRIO_DATA() macro which are explicitly
handling I/O priority data as a priority level are modified to use the new
IOPRIO_PRIO_LEVEL() macro without any functional change. Since f2fs is the
only user of this macro not explicitly using that value as a priority
level, it is left unchanged.

Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
Link: https://lore.kernel.org/r/20230511011356.227789-2-nks@flawful.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
block/bfq-iosched.c
block/ioprio.c
include/uapi/linux/ioprio.h

index 3164e31..3067b75 100644 (file)
@@ -5524,16 +5524,16 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
                bfqq->new_ioprio_class = task_nice_ioclass(tsk);
                break;
        case IOPRIO_CLASS_RT:
-               bfqq->new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
+               bfqq->new_ioprio = IOPRIO_PRIO_LEVEL(bic->ioprio);
                bfqq->new_ioprio_class = IOPRIO_CLASS_RT;
                break;
        case IOPRIO_CLASS_BE:
-               bfqq->new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
+               bfqq->new_ioprio = IOPRIO_PRIO_LEVEL(bic->ioprio);
                bfqq->new_ioprio_class = IOPRIO_CLASS_BE;
                break;
        case IOPRIO_CLASS_IDLE:
                bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE;
-               bfqq->new_ioprio = 7;
+               bfqq->new_ioprio = IOPRIO_NR_LEVELS - 1;
                break;
        }
 
@@ -5830,7 +5830,7 @@ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
                                       struct bfq_io_cq *bic,
                                       bool respawn)
 {
-       const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
+       const int ioprio = IOPRIO_PRIO_LEVEL(bic->ioprio);
        const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
        struct bfq_queue **async_bfqq = NULL;
        struct bfq_queue *bfqq;
index 32a456b..f0d9e81 100644 (file)
@@ -33,7 +33,7 @@
 int ioprio_check_cap(int ioprio)
 {
        int class = IOPRIO_PRIO_CLASS(ioprio);
-       int data = IOPRIO_PRIO_DATA(ioprio);
+       int level = IOPRIO_PRIO_LEVEL(ioprio);
 
        switch (class) {
                case IOPRIO_CLASS_RT:
@@ -49,13 +49,13 @@ int ioprio_check_cap(int ioprio)
                        fallthrough;
                        /* rt has prio field too */
                case IOPRIO_CLASS_BE:
-                       if (data >= IOPRIO_NR_LEVELS || data < 0)
+                       if (level >= IOPRIO_NR_LEVELS)
                                return -EINVAL;
                        break;
                case IOPRIO_CLASS_IDLE:
                        break;
                case IOPRIO_CLASS_NONE:
-                       if (data)
+                       if (level)
                                return -EINVAL;
                        break;
                default:
index f70f259..4444b4e 100644 (file)
@@ -17,7 +17,7 @@
         ((data) & IOPRIO_PRIO_MASK))
 
 /*
- * These are the io priority groups as implemented by the BFQ and mq-deadline
+ * These are the io priority classes as implemented by the BFQ and mq-deadline
  * schedulers. RT is the realtime class, it always gets premium service. For
  * ATA disks supporting NCQ IO priority, RT class IOs will be processed using
  * high priority NCQ commands. BE is the best-effort scheduling class, the
@@ -32,11 +32,20 @@ enum {
 };
 
 /*
- * The RT and BE priority classes both support up to 8 priority levels.
+ * The RT and BE priority classes both support up to 8 priority levels that
+ * can be specified using the lower 3-bits of the priority data.
  */
-#define IOPRIO_NR_LEVELS       8
-#define IOPRIO_BE_NR           IOPRIO_NR_LEVELS
+#define IOPRIO_LEVEL_NR_BITS           3
+#define IOPRIO_NR_LEVELS               (1 << IOPRIO_LEVEL_NR_BITS)
+#define IOPRIO_LEVEL_MASK              (IOPRIO_NR_LEVELS - 1)
+#define IOPRIO_PRIO_LEVEL(ioprio)      ((ioprio) & IOPRIO_LEVEL_MASK)
 
+#define IOPRIO_BE_NR                   IOPRIO_NR_LEVELS
+
+/*
+ * Possible values for the "which" argument of the ioprio_get() and
+ * ioprio_set() system calls (see "man ioprio_set").
+ */
 enum {
        IOPRIO_WHO_PROCESS = 1,
        IOPRIO_WHO_PGRP,
@@ -44,7 +53,7 @@ enum {
 };
 
 /*
- * Fallback BE priority level.
+ * Fallback BE class priority level.
  */
 #define IOPRIO_NORM    4
 #define IOPRIO_BE_NORM IOPRIO_NORM