mirror of
https://github.com/torvalds/linux.git
synced 2025-08-15 14:11:42 +02:00

Upstream commit53889bcaf5
("block: make __get_task_ioprio() easier to read") changes the IO priority returned to the caller if no IO context is defined for the task. Prior to this commit, the returned IO priority was determined by task_nice_ioclass() and task_nice_ioprio(). Now it is always IOPRIO_DEFAULT, which translates to IOPRIO_CLASS_NONE with priority 0. However, task_nice_ioclass() returns IOPRIO_CLASS_IDLE, IOPRIO_CLASS_RT, or IOPRIO_CLASS_BE depending on the task scheduling policy, and task_nice_ioprio() returns a value determined by task_nice(). This causes regressions in test code checking the IO priority and class of IO operations on tasks with no IO context. Fix the problem by returning the IO priority calculated from task_nice_ioclass() and task_nice_ioprio() if no IO context is defined to match earlier behavior. Fixes:53889bcaf5
("block: make __get_task_ioprio() easier to read") Cc: Jens Axboe <axboe@kernel.dk> Cc: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Yu Kuai <yukuai3@huawei.com> Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Link: https://lore.kernel.org/r/20250731044953.1852690-1-linux@roeck-us.net Signed-off-by: Jens Axboe <axboe@kernel.dk>
98 lines
2.2 KiB
C
98 lines
2.2 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef IOPRIO_H
|
|
#define IOPRIO_H
|
|
|
|
#include <linux/sched.h>
|
|
#include <linux/sched/rt.h>
|
|
#include <linux/iocontext.h>
|
|
|
|
#include <uapi/linux/ioprio.h>
|
|
|
|
/*
|
|
* Default IO priority.
|
|
*/
|
|
#define IOPRIO_DEFAULT IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, 0)
|
|
|
|
/*
|
|
* Check that a priority value has a valid class.
|
|
*/
|
|
static inline bool ioprio_valid(unsigned short ioprio)
|
|
{
|
|
unsigned short class = IOPRIO_PRIO_CLASS(ioprio);
|
|
|
|
return class > IOPRIO_CLASS_NONE && class <= IOPRIO_CLASS_IDLE;
|
|
}
|
|
|
|
/*
|
|
* if process has set io priority explicitly, use that. if not, convert
|
|
* the cpu scheduler nice value to an io priority
|
|
*/
|
|
static inline int task_nice_ioprio(struct task_struct *task)
|
|
{
|
|
return (task_nice(task) + 20) / 5;
|
|
}
|
|
|
|
/*
|
|
* This is for the case where the task hasn't asked for a specific IO class.
|
|
* Check for idle and rt task process, and return appropriate IO class.
|
|
*/
|
|
static inline int task_nice_ioclass(struct task_struct *task)
|
|
{
|
|
if (task->policy == SCHED_IDLE)
|
|
return IOPRIO_CLASS_IDLE;
|
|
else if (rt_or_dl_task_policy(task))
|
|
return IOPRIO_CLASS_RT;
|
|
else
|
|
return IOPRIO_CLASS_BE;
|
|
}
|
|
|
|
#ifdef CONFIG_BLOCK
|
|
/*
|
|
* If the task has set an I/O priority, use that. Otherwise, return
|
|
* the default I/O priority.
|
|
*
|
|
* Expected to be called for current task or with task_lock() held to keep
|
|
* io_context stable.
|
|
*/
|
|
static inline int __get_task_ioprio(struct task_struct *p)
|
|
{
|
|
struct io_context *ioc = p->io_context;
|
|
int prio;
|
|
|
|
if (!ioc)
|
|
return IOPRIO_PRIO_VALUE(task_nice_ioclass(p),
|
|
task_nice_ioprio(p));
|
|
|
|
if (p != current)
|
|
lockdep_assert_held(&p->alloc_lock);
|
|
|
|
prio = ioc->ioprio;
|
|
if (IOPRIO_PRIO_CLASS(prio) == IOPRIO_CLASS_NONE)
|
|
prio = IOPRIO_PRIO_VALUE(task_nice_ioclass(p),
|
|
task_nice_ioprio(p));
|
|
return prio;
|
|
}
|
|
#else
|
|
static inline int __get_task_ioprio(struct task_struct *p)
|
|
{
|
|
return IOPRIO_DEFAULT;
|
|
}
|
|
#endif /* CONFIG_BLOCK */
|
|
|
|
static inline int get_current_ioprio(void)
|
|
{
|
|
return __get_task_ioprio(current);
|
|
}
|
|
|
|
extern int set_task_ioprio(struct task_struct *task, int ioprio);
|
|
|
|
#ifdef CONFIG_BLOCK
|
|
extern int ioprio_check_cap(int ioprio);
|
|
#else
|
|
static inline int ioprio_check_cap(int ioprio)
|
|
{
|
|
return -ENOTBLK;
|
|
}
|
|
#endif /* CONFIG_BLOCK */
|
|
|
|
#endif
|