From: Yu Watanabe Date: Fri, 28 Feb 2025 18:09:43 +0000 (+0900) Subject: basic/linux: import ioprio.h from kernel 6.14-rc4 X-Git-Tag: v258-rc1~1195^2~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e7e91769e86f27b8243ff4f8d3dea3336ea17298;p=thirdparty%2Fsystemd.git basic/linux: import ioprio.h from kernel 6.14-rc4 This also fixes the maximum allowed ioprio class: 8 -> 7 --- diff --git a/meson.build b/meson.build index f31f6372470..f69ead2ddc9 100644 --- a/meson.build +++ b/meson.build @@ -707,7 +707,6 @@ if not cc.has_header('sys/capability.h') error('POSIX caps headers not found') endif foreach header : ['crypt.h', - 'linux/ioprio.h', 'sys/sdt.h', 'threads.h', 'valgrind/memcheck.h', diff --git a/src/basic/ioprio-util.c b/src/basic/ioprio-util.c index b63650b80b2..3add1bddd08 100644 --- a/src/basic/ioprio-util.c +++ b/src/basic/ioprio-util.c @@ -23,9 +23,9 @@ int ioprio_parse_priority(const char *s, int *ret) { static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", - [IOPRIO_CLASS_RT] = "realtime", - [IOPRIO_CLASS_BE] = "best-effort", + [IOPRIO_CLASS_RT] = "realtime", + [IOPRIO_CLASS_BE] = "best-effort", [IOPRIO_CLASS_IDLE] = "idle", }; -DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, IOPRIO_N_CLASSES); +DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, IOPRIO_NR_CLASSES-1); diff --git a/src/basic/ioprio-util.h b/src/basic/ioprio-util.h index b8c9b7dd59f..376eb85dadc 100644 --- a/src/basic/ioprio-util.h +++ b/src/basic/ioprio-util.h @@ -1,8 +1,21 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include + #include "macro.h" -#include "missing_ioprio.h" + +static inline int ioprio_prio_class(int value) { + return IOPRIO_PRIO_CLASS(value); +} + +static inline int ioprio_prio_data(int value) { + return IOPRIO_PRIO_DATA(value); +} + +static inline int ioprio_prio_value(int class, int data) { + return IOPRIO_PRIO_VALUE_HINT(class, IOPRIO_PRIO_LEVEL(data), IOPRIO_PRIO_HINT(data)); +} int ioprio_class_to_string_alloc(int i, char **s); int ioprio_class_from_string(const char *s); @@ -12,7 +25,7 @@ static inline bool ioprio_class_is_valid(int i) { } static inline bool ioprio_priority_is_valid(int i) { - return i >= 0 && i < IOPRIO_BE_NR; + return i >= 0 && i < IOPRIO_NR_LEVELS; } int ioprio_parse_priority(const char *s, int *ret); diff --git a/src/basic/linux/ioprio.h b/src/basic/linux/ioprio.h new file mode 100644 index 00000000000..9a51dd0c9b5 --- /dev/null +++ b/src/basic/linux/ioprio.h @@ -0,0 +1,127 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _LINUX_IOPRIO_H +#define _LINUX_IOPRIO_H + +#include +#include + +/* + * Gives us 8 prio classes with 13-bits of data for each class + */ +#define IOPRIO_CLASS_SHIFT 13 +#define IOPRIO_NR_CLASSES 8 +#define IOPRIO_CLASS_MASK (IOPRIO_NR_CLASSES - 1) +#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1) + +#define IOPRIO_PRIO_CLASS(ioprio) \ + (((ioprio) >> IOPRIO_CLASS_SHIFT) & IOPRIO_CLASS_MASK) +#define IOPRIO_PRIO_DATA(ioprio) ((ioprio) & IOPRIO_PRIO_MASK) + +/* + * 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 + * default for any process. IDLE is the idle scheduling class, it is only + * served when no one else is using the disk. + */ +enum { + IOPRIO_CLASS_NONE = 0, + IOPRIO_CLASS_RT = 1, + IOPRIO_CLASS_BE = 2, + IOPRIO_CLASS_IDLE = 3, + + /* Special class to indicate an invalid ioprio value */ + IOPRIO_CLASS_INVALID = 7, +}; + +/* + * 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_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, + IOPRIO_WHO_USER, +}; + +/* + * Fallback BE class priority level. + */ +#define IOPRIO_NORM 4 +#define IOPRIO_BE_NORM IOPRIO_NORM + +/* + * The 10 bits between the priority class and the priority level are used to + * optionally define I/O hints for any combination of I/O priority class and + * level. Depending on the kernel configuration, I/O scheduler being used and + * the target I/O device being used, hints can influence how I/Os are processed + * without affecting the I/O scheduling ordering defined by the I/O priority + * class and level. + */ +#define IOPRIO_HINT_SHIFT IOPRIO_LEVEL_NR_BITS +#define IOPRIO_HINT_NR_BITS 10 +#define IOPRIO_NR_HINTS (1 << IOPRIO_HINT_NR_BITS) +#define IOPRIO_HINT_MASK (IOPRIO_NR_HINTS - 1) +#define IOPRIO_PRIO_HINT(ioprio) \ + (((ioprio) >> IOPRIO_HINT_SHIFT) & IOPRIO_HINT_MASK) + +/* + * I/O hints. + */ +enum { + /* No hint */ + IOPRIO_HINT_NONE = 0, + + /* + * Device command duration limits: indicate to the device a desired + * duration limit for the commands that will be used to process an I/O. + * These will currently only be effective for SCSI and ATA devices that + * support the command duration limits feature. If this feature is + * enabled, then the commands issued to the device to process an I/O with + * one of these hints set will have the duration limit index (dld field) + * set to the value of the hint. + */ + IOPRIO_HINT_DEV_DURATION_LIMIT_1 = 1, + IOPRIO_HINT_DEV_DURATION_LIMIT_2 = 2, + IOPRIO_HINT_DEV_DURATION_LIMIT_3 = 3, + IOPRIO_HINT_DEV_DURATION_LIMIT_4 = 4, + IOPRIO_HINT_DEV_DURATION_LIMIT_5 = 5, + IOPRIO_HINT_DEV_DURATION_LIMIT_6 = 6, + IOPRIO_HINT_DEV_DURATION_LIMIT_7 = 7, +}; + +#define IOPRIO_BAD_VALUE(val, max) ((val) < 0 || (val) >= (max)) + +/* + * Return an I/O priority value based on a class, a level and a hint. + */ +static __always_inline __u16 ioprio_value(int prioclass, int priolevel, + int priohint) +{ + if (IOPRIO_BAD_VALUE(prioclass, IOPRIO_NR_CLASSES) || + IOPRIO_BAD_VALUE(priolevel, IOPRIO_NR_LEVELS) || + IOPRIO_BAD_VALUE(priohint, IOPRIO_NR_HINTS)) + return IOPRIO_CLASS_INVALID << IOPRIO_CLASS_SHIFT; + + return (prioclass << IOPRIO_CLASS_SHIFT) | + (priohint << IOPRIO_HINT_SHIFT) | priolevel; +} + +#define IOPRIO_PRIO_VALUE(prioclass, priolevel) \ + ioprio_value(prioclass, priolevel, IOPRIO_HINT_NONE) +#define IOPRIO_PRIO_VALUE_HINT(prioclass, priolevel, priohint) \ + ioprio_value(prioclass, priolevel, priohint) + +#endif /* _LINUX_IOPRIO_H */ diff --git a/src/basic/missing_ioprio.h b/src/basic/missing_ioprio.h deleted file mode 100644 index 1f7323d8130..00000000000 --- a/src/basic/missing_ioprio.h +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -#if HAVE_LINUX_IOPRIO_H -# include -#endif - -#include "macro.h" - -#ifndef IOPRIO_N_CLASSES -# define IOPRIO_N_CLASSES 8 -#else -assert_cc(IOPRIO_N_CLASSES == 8); -#endif - -#ifndef IOPRIO_BE_NR -# define IOPRIO_BE_NR 8 -#else -assert_cc(IOPRIO_BE_NR == 8); -#endif - -#ifndef IOPRIO_CLASS_NONE -# define IOPRIO_CLASS_NONE 0 -#else -assert_cc(IOPRIO_CLASS_NONE == 0); -#endif -#ifndef IOPRIO_CLASS_RT -# define IOPRIO_CLASS_RT 1 -#else -assert_cc(IOPRIO_CLASS_RT == 1); -#endif -#ifndef IOPRIO_CLASS_BE -# define IOPRIO_CLASS_BE 2 -#else -assert_cc(IOPRIO_CLASS_BE == 2); -#endif -#ifndef IOPRIO_CLASS_IDLE -# define IOPRIO_CLASS_IDLE 3 -#else -assert_cc(IOPRIO_CLASS_IDLE == 3); -#endif - -#ifndef IOPRIO_WHO_PROCESS -# define IOPRIO_WHO_PROCESS 1 -#else -assert_cc(IOPRIO_WHO_PROCESS == 1); -#endif - -#ifndef IOPRIO_WHO_PGRP -# define IOPRIO_WHO_PGRP 2 -#else -assert_cc(IOPRIO_WHO_PGRP == 2); -#endif - -#ifndef IOPRIO_WHO_USER -# define IOPRIO_WHO_USER 3 -#else -assert_cc(IOPRIO_WHO_USER == 3); -#endif - -#ifndef IOPRIO_BITS -# define IOPRIO_BITS 16 -#else -assert_cc(IOPRIO_BITS == 16); -#endif - -#ifndef IOPRIO_N_CLASSES -# define IOPRIO_N_CLASSES 8 -#else -assert_cc(IOPRIO_N_CLASSES == 8); -#endif - -#ifndef IOPRIO_CLASS_SHIFT -# define IOPRIO_CLASS_SHIFT 13 -#else -assert_cc(IOPRIO_CLASS_SHIFT == 13); -#endif - -static inline int ioprio_prio_class(int value) { - return value >> IOPRIO_CLASS_SHIFT; -} - -static inline int ioprio_prio_data(int value) { - return value & ((1 << IOPRIO_CLASS_SHIFT) - 1); -} - -static inline int ioprio_prio_value(int class, int data) { - return (class << IOPRIO_CLASS_SHIFT) | data; -} diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 8039565f263..2e2e142a19d 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -22,12 +22,11 @@ #include "fileio.h" #include "hexdecoct.h" #include "hostname-util.h" -#include "iovec-util.h" #include "ioprio-util.h" +#include "iovec-util.h" #include "journal-file.h" #include "load-fragment.h" #include "memstream-util.h" -#include "missing_ioprio.h" #include "mountpoint-util.h" #include "namespace.h" #include "parse-util.h" diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 37df73adb79..8d1e072d3f2 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -37,10 +37,10 @@ #include "hexdecoct.h" #include "hostname-setup.h" #include "io-util.h" +#include "ioprio-util.h" #include "iovec-util.h" #include "journal-send.h" #include "memfd-util.h" -#include "missing_ioprio.h" #include "missing_prctl.h" #include "missing_sched.h" #include "missing_securebits.h" diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 5cb5494b0b0..dde7a55f4ff 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -41,14 +41,13 @@ #include "fstab-util.h" #include "hexdecoct.h" #include "hostname-util.h" -#include "iovec-util.h" #include "ioprio-util.h" +#include "iovec-util.h" #include "ip-protocol-list.h" #include "journal-file.h" #include "limits-util.h" #include "load-fragment.h" #include "log.h" -#include "missing_ioprio.h" #include "mountpoint-util.h" #include "nulstr-util.h" #include "open-file.h" diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c index 7bd416f8d0f..0f00089eece 100644 --- a/src/test/test-process-util.c +++ b/src/test/test-process-util.c @@ -721,7 +721,7 @@ TEST(ioprio_class_from_to_string) { test_ioprio_class_from_to_string_one("0", IOPRIO_CLASS_NONE, IOPRIO_CLASS_BE); test_ioprio_class_from_to_string_one("1", 1, 1); test_ioprio_class_from_to_string_one("7", 7, 7); - test_ioprio_class_from_to_string_one("8", 8, 8); + test_ioprio_class_from_to_string_one("8", -EINVAL, -EINVAL); test_ioprio_class_from_to_string_one("9", -EINVAL, -EINVAL); test_ioprio_class_from_to_string_one("-1", -EINVAL, -EINVAL); }