[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250603233654.1838967-4-prakash.sangappa@oracle.com>
Date: Tue, 3 Jun 2025 23:36:51 +0000
From: Prakash Sangappa <prakash.sangappa@...cle.com>
To: linux-kernel@...r.kernel.org
Cc: peterz@...radead.org, rostedt@...dmis.org, mathieu.desnoyers@...icios.com,
tglx@...utronix.de, bigeasy@...utronix.de, kprateek.nayak@....com,
vineethr@...ux.ibm.com
Subject: [PATCH V5 3/6] Sched: Tunable to specify duration of time slice extension
Add a tunable to specify duration of scheduler time slice extension.
The default will be set to 30us and the max value that can be specified
is 100us. Setting it to 0, disables scheduler time slice extension.
Signed-off-by: Prakash Sangappa <prakash.sangappa@...cle.com>
---
v5:
- Added #ifdef CONFIG_RSEQ & CONFIG_PROC_SYSCTL
---
include/linux/sched.h | 5 +++++
include/uapi/linux/rseq.h | 5 +++--
kernel/rseq.c | 7 +++++--
kernel/sched/core.c | 40 +++++++++++++++++++++++++++++++++++++++
4 files changed, 53 insertions(+), 4 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 71e6c8221c1e..14069ebe26e2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -407,6 +407,11 @@ static inline void sched_domains_mutex_lock(void) { }
static inline void sched_domains_mutex_unlock(void) { }
#endif
+#ifdef CONFIG_RSEQ
+/* Scheduler time slice extension */
+extern unsigned int sysctl_sched_preempt_delay_us;
+#endif
+
struct sched_param {
int sched_priority;
};
diff --git a/include/uapi/linux/rseq.h b/include/uapi/linux/rseq.h
index f4813d931387..015534f064af 100644
--- a/include/uapi/linux/rseq.h
+++ b/include/uapi/linux/rseq.h
@@ -137,8 +137,9 @@ struct rseq {
* this thread.
* - RSEQ_CS_FLAG_DELAY_RESCHED
* Request by user thread to delay preemption. With use
- * of a timer, kernel grants extra cpu time upto 30us for this
- * thread before being rescheduled.
+ * of a timer, kernel grants extra cpu time upto the tunable
+ * 'sched_preempt_delay_us' value for this thread before it gets
+ * rescheduled.
* - RSEQ_CS_FLAG_RESCHEDULED
* Set by kernel if the thread was rescheduled in the extra time
* granted due to request RSEQ_CS_DELAY_RESCHED. This bit is
diff --git a/kernel/rseq.c b/kernel/rseq.c
index 9355654e9b38..44d0f3ae0cd3 100644
--- a/kernel/rseq.c
+++ b/kernel/rseq.c
@@ -456,6 +456,8 @@ bool rseq_delay_resched(void)
if (!IS_ENABLED(CONFIG_SCHED_HRTICK))
return false;
+ if (!sysctl_sched_preempt_delay_us)
+ return false;
if (!t->rseq)
return false;
@@ -489,8 +491,9 @@ void rseq_delay_resched_fini(void)
* If your critical section is longer than 30 us you get to keep the
* pieces.
*/
- if (t->sched_time_delay)
- hrtick_local_start(30 * NSEC_PER_USEC);
+ if (sysctl_sched_preempt_delay_us && t->sched_time_delay)
+ hrtick_local_start(sysctl_sched_preempt_delay_us *
+ NSEC_PER_USEC);
#endif
}
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 86583fb72914..e5307389b30a 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -148,6 +148,17 @@ __read_mostly int sysctl_resched_latency_warn_once = 1;
*/
__read_mostly unsigned int sysctl_sched_nr_migrate = SCHED_NR_MIGRATE_BREAK;
+#ifdef CONFIG_RSEQ
+/*
+ * Scheduler time slice extension, duration in microsecs.
+ * Max value allowed 100us, default is 30us.
+ * If set to 0, scheduler time slice extension is disabled.
+ */
+#define SCHED_PREEMPT_DELAY_DEFAULT_US 30
+__read_mostly unsigned int sysctl_sched_preempt_delay_us =
+ SCHED_PREEMPT_DELAY_DEFAULT_US;
+#endif
+
__read_mostly int scheduler_running;
#ifdef CONFIG_SCHED_CORE
@@ -4664,6 +4675,24 @@ static int sysctl_schedstats(const struct ctl_table *table, int write, void *buf
#endif /* CONFIG_PROC_SYSCTL */
#endif /* CONFIG_SCHEDSTATS */
+#ifdef CONFIG_PROC_SYSCTL
+#ifdef CONFIG_RSEQ
+static int sysctl_sched_preempt_delay(const struct ctl_table *table, int write,
+ void *buffer, size_t *lenp, loff_t *ppos)
+{
+ int err;
+
+ err = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+ if (err < 0)
+ return err;
+ if (sysctl_sched_preempt_delay_us > SCHED_PREEMPT_DELAY_DEFAULT_US)
+ pr_warn("Sched preemption delay time set higher then default value %d us\n",
+ SCHED_PREEMPT_DELAY_DEFAULT_US);
+ return err;
+}
+#endif /* CONFIG_RSEQ */
+#endif /* CONFIG_PROC_SYSCTL */
+
#ifdef CONFIG_SYSCTL
static const struct ctl_table sched_core_sysctls[] = {
#ifdef CONFIG_SCHEDSTATS
@@ -4711,6 +4740,17 @@ static const struct ctl_table sched_core_sysctls[] = {
.extra2 = SYSCTL_FOUR,
},
#endif /* CONFIG_NUMA_BALANCING */
+#ifdef CONFIG_RSEQ
+ {
+ .procname = "sched_preempt_delay_us",
+ .data = &sysctl_sched_preempt_delay_us,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = sysctl_sched_preempt_delay,
+ .extra1 = SYSCTL_ZERO,
+ .extra2 = SYSCTL_ONE_HUNDRED,
+ },
+#endif /* CONFIG_RSEQ */
};
static int __init sched_core_sysctl_init(void)
{
--
2.43.5
Powered by blists - more mailing lists