History

sched: Provide sched_set_fifo()

SCHED_FIFO (or any static priority scheduler) is a broken scheduler model; it is fundamentally incapable of resource management, the one thing an OS is actually supposed to do. It is impossible to compose static priority workloads. One cannot take two well designed and functional static priority workloads and mash them together and still expect them to work. Therefore it doesn't make sense to expose the priority field; the kernel is fundamentally incapable of setting a sensible value, it needs systems knowledge that it doesn't have. Take away sched_setschedule() / sched_setattr() from modules and replace them with: - sched_set_fifo(p); create a FIFO task (at prio 50) - sched_set_fifo_low(p); create a task higher than NORMAL, which ends up being a FIFO task at prio 1. - sched_set_normal(p, nice); (re)set the task to normal This stops the proliferation of randomly chosen, and irrelevant, FIFO priorities that dont't really mean anything anyway. The system administrator/integrator, whoever has insight into the actual system design and requirements (userspace) can set-up appropriate priorities if and when needed.

Peter Zijlstra committed 6 years ago

Commit 7318d4c1 parent 87e867b2 files · +50 −0Browse files

Unified · Split

2 files
  1. include/linux/sched.h +3 −0
  2. kernel/sched/core.c +47 −0
include/linux/sched.h+3−0
@@ -1653,6 +1653,9 @@ extern int idle_cpu(int cpu); · 1652 unmodified lines
1653extern int available_idle_cpu(int cpu);1653extern int available_idle_cpu(int cpu);
1654extern int sched_setscheduler(struct task_struct *, int, const struct sched_param *);1654extern int sched_setscheduler(struct task_struct *, int, const struct sched_param *);
1655extern int sched_setscheduler_nocheck(struct task_struct *, int, const struct sched_param *);1655extern int sched_setscheduler_nocheck(struct task_struct *, int, const struct sched_param *);
1656extern int sched_set_fifo(struct task_struct *p);
1657extern int sched_set_fifo_low(struct task_struct *p);
1658extern int sched_set_normal(struct task_struct *p, int nice);
1656extern int sched_setattr(struct task_struct *, const struct sched_attr *);1659extern int sched_setattr(struct task_struct *, const struct sched_attr *);
1657extern int sched_setattr_nocheck(struct task_struct *, const struct sched_attr *);1660extern int sched_setattr_nocheck(struct task_struct *, const struct sched_attr *);
1658extern struct task_struct *idle_task(int cpu);1661extern struct task_struct *idle_task(int cpu);
kernel/sched/core.c+47−0
@@ -5124,6 +5124,8 @@ static int _sched_setscheduler(struct task_struct *p, int policy, · 5123 unmodified lines
5124 * @policy: new policy.5124 * @policy: new policy.
5125 * @param: structure containing the new RT priority.5125 * @param: structure containing the new RT priority.
5126 *5126 *
5127 * Use sched_set_fifo(), read its comment.
5128 *
5127 * Return: 0 on success. An error code otherwise.5129 * Return: 0 on success. An error code otherwise.
5128 *5130 *
5129 * NOTE that the task may be already dead.5131 * NOTE that the task may be already dead.
@@ -5166,6 +5168,51 @@ int sched_setscheduler_nocheck(struct task_struct *p, int policy, · 36 unmodified lines
5166}5168}
5167EXPORT_SYMBOL_GPL(sched_setscheduler_nocheck);5169EXPORT_SYMBOL_GPL(sched_setscheduler_nocheck);
5168 5170
5171/*
5172 * SCHED_FIFO is a broken scheduler model; that is, it is fundamentally
5173 * incapable of resource management, which is the one thing an OS really should
5174 * be doing.
5175 *
5176 * This is of course the reason it is limited to privileged users only.
5177 *
5178 * Worse still; it is fundamentally impossible to compose static priority
5179 * workloads. You cannot take two correctly working static prio workloads
5180 * and smash them together and still expect them to work.
5181 *
5182 * For this reason 'all' FIFO tasks the kernel creates are basically at:
5183 *
5184 * MAX_RT_PRIO / 2
5185 *
5186 * The administrator _MUST_ configure the system, the kernel simply doesn't
5187 * know enough information to make a sensible choice.
5188 */
5189int sched_set_fifo(struct task_struct *p)
5190{
5191 struct sched_param sp = { .sched_priority = MAX_RT_PRIO / 2 };
5192 return sched_setscheduler_nocheck(p, SCHED_FIFO, &sp);
5193}
5194EXPORT_SYMBOL_GPL(sched_set_fifo);
5195
5196/*
5197 * For when you don't much care about FIFO, but want to be above SCHED_NORMAL.
5198 */
5199int sched_set_fifo_low(struct task_struct *p)
5200{
5201 struct sched_param sp = { .sched_priority = 1 };
5202 return sched_setscheduler_nocheck(p, SCHED_FIFO, &sp);
5203}
5204EXPORT_SYMBOL_GPL(sched_set_fifo_low);
5205
5206int sched_set_normal(struct task_struct *p, int nice)
5207{
5208 struct sched_attr attr = {
5209 .sched_policy = SCHED_NORMAL,
5210 .sched_nice = nice,
5211 };
5212 return sched_setattr_nocheck(p, &attr);
5213}
5214EXPORT_SYMBOL_GPL(sched_set_normal);
5215
5169static int5216static int
5170do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)5217do_sched_setscheduler(pid_t pid, int policy, struct sched_param __user *param)
5171{5218{