[RFC PATCH 2/8] sched/core: sched_setscheduler_pi_nocheck for interrupt context usage

Vineeth Pillai (Google)
2023-12-14T02:47:36Z

__sched_setscheduler takes an argument 'pi' so as to allow its usage in
interrupt context when PI is not used. But this is not exported and
cannot be used outside of scheduler code. sched_setscheduler_nocheck is
exported but it doesn't allow that flexibility.

Introduce sched_setscheduler_pi_nocheck to allow for the flexibility to
call from interrupt context

Co-developed-by: Joel Fernandes (Google) <joel@joelfernandes.org>
Signed-off-by: Joel Fernandes (Google) <joel@joelfernandes.org>
Signed-off-by: Vineeth Pillai (Google) <vineeth@bitbyteword.org>
---
include/linux/sched.h | 2 ++
kernel/sched/core.c | 34 +++++++++++++++++++++++++++++++---
2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 609bde814cb0..de7382f149cf 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1908,6 +1908,8 @@ extern int idle_cpu(int cpu);
extern int available_idle_cpu(int cpu);
extern int sched_setscheduler(struct task_struct *, int, const struct sched_param *);
extern int sched_setscheduler_nocheck(struct task_struct *, int, const struct sched_param *);
+extern int sched_setscheduler_pi_nocheck(struct task_struct *p, int policy,
+ const struct sched_param *sp, bool pi);
extern void sched_set_fifo(struct task_struct *p);
extern void sched_set_fifo_low(struct task_struct *p);
extern void sched_set_normal(struct task_struct *p, int nice);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e8f73ff12126..b47f72b6595f 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7850,8 +7850,8 @@ static int __sched_setscheduler(struct task_struct *p,
return retval;
}

-static int _sched_setscheduler(struct task_struct *p, int policy,
- const struct sched_param *param, bool check)
+static int _sched_setscheduler_pi(struct task_struct *p, int policy,
+ const struct sched_param *param, bool check, bool pi)
{
struct sched_attr attr = {
.sched_policy = policy,
@@ -7866,8 +7866,15 @@ static int _sched_setscheduler(struct task_struct *p, int policy,
attr.sched_policy = policy;
}

- return __sched_setscheduler(p, &attr, check, true);
+ return __sched_setscheduler(p, &attr, check, pi);
+}
+
+static inline int _sched_setscheduler(struct task_struct *p, int policy,
+ const struct sched_param *param, bool check)
+{
+ return _sched_setscheduler_pi(p, policy, param, check, true);
}
+
/**
* sched_setscheduler - change the scheduling policy and/or RT priority of a thread.
* @p: the task in question.
@@ -7916,6 +7923,27 @@ int sched_setscheduler_nocheck(struct task_struct *p, int policy,
return _sched_setscheduler(p, policy, param, false);
}

+/**
+ * sched_setscheduler_pi_nocheck - change the scheduling policy and/or RT priority of a thread from kernelspace.
+ * @p: the task in question.
+ * @policy: new policy.
+ * @param: structure containing the new RT priority.
+ * @pi: boolean flag stating if pi validation needs to be performed.
+ *
+ * A flexible version of sched_setcheduler_nocheck which allows for specifying
+ * whether PI context validation needs to be done or not. set_scheduler_nocheck
+ * is not allowed in interrupt context as it assumes that PI is used.
+ * This function allows interrupt context call by specifying pi = false.
+ *
+ * Return: 0 on success. An error code otherwise.
+ */
+int sched_setscheduler_pi_nocheck(struct task_struct *p, int policy,
+ const struct sched_param *param, bool pi)
+{
+ return _sched_setscheduler_pi(p, policy, param, false, pi);
+}
+EXPORT_SYMBOL_GPL(sched_setscheduler_pi_nocheck);
+
/*
* SCHED_FIFO is a broken scheduler model; that is, it is fundamentally
* incapable of resource management, which is the one thing an OS really should
--
2.43.0