[PATCH v2 06/10] sched/debug: Add support to change sched_ext server params

Joel Fernandes posted 10 patches 6 months, 2 weeks ago
There is a newer version of this series
[PATCH v2 06/10] sched/debug: Add support to change sched_ext server params
Posted by Joel Fernandes 6 months, 2 weeks ago
When a sched_ext server is loaded, tasks in CFS are converted to run in
sched_ext class. Modify the ext server parameters as well along with the
fair ones.

Re-use the existing interface to modify both ext and fair servers to
keep number of interfaces less (as it is, we have a per-cpu interface).

Reviewed-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com>
---
 kernel/sched/debug.c | 91 ++++++++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 37 deletions(-)

diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 6866f0a9e88c..f1af2999a8e5 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -341,17 +341,18 @@ enum dl_param {
 	DL_PERIOD,
 };
 
-static unsigned long fair_server_period_max = (1UL << 22) * NSEC_PER_USEC; /* ~4 seconds */
-static unsigned long fair_server_period_min = (100) * NSEC_PER_USEC;     /* 100 us */
+static unsigned long dl_server_period_max = (1UL << 22) * NSEC_PER_USEC; /* ~4 seconds */
+static unsigned long dl_server_period_min = (100) * NSEC_PER_USEC;     /* 100 us */
 
-static ssize_t sched_fair_server_write(struct file *filp, const char __user *ubuf,
+static ssize_t sched_dl_server_write(struct file *filp, const char __user *ubuf,
 				       size_t cnt, loff_t *ppos, enum dl_param param)
 {
 	long cpu = (long) ((struct seq_file *) filp->private_data)->private;
 	struct rq *rq = cpu_rq(cpu);
-	bool was_active = false;
+	bool was_active_fair = false;
+	bool was_active_ext = false;
+	int retval = 0, retval2 = 0;
 	u64 runtime, period;
-	int retval = 0;
 	size_t err;
 	u64 value;
 
@@ -377,41 +378,57 @@ static ssize_t sched_fair_server_write(struct file *filp, const char __user *ubu
 		}
 
 		if (runtime > period ||
-		    period > fair_server_period_max ||
-		    period < fair_server_period_min) {
+		    period > dl_server_period_max ||
+		    period < dl_server_period_min) {
 			return  -EINVAL;
 		}
 
 		if (dl_server_active(&rq->fair_server)) {
-			was_active = true;
+			was_active_fair = true;
 			update_rq_clock(rq);
 			dl_server_stop(&rq->fair_server);
 		}
 
+		if (dl_server_active(&rq->ext_server)) {
+			was_active_ext = true;
+			update_rq_clock(rq);
+			dl_server_stop(&rq->ext_server);
+		}
+
 		retval = dl_server_apply_params(&rq->fair_server, runtime, period, 0);
+		retval2 = dl_server_apply_params(&rq->ext_server, runtime, period, 0);
 
 		if (!runtime)
-			printk_deferred("Fair server disabled in CPU %d, system may crash due to starvation.\n",
+			printk_deferred("Deadline servers are disabled on CPU %d, system may crash due to starvation.\n",
 					cpu_of(rq));
 
-		if (was_active)
+		if (was_active_fair)
 			dl_server_start(&rq->fair_server);
 
+		if (was_active_ext)
+			dl_server_start(&rq->ext_server);
+
 		if (retval < 0)
 			return retval;
+		if (retval2 < 0)
+			return retval2;
 	}
 
 	*ppos += cnt;
 	return cnt;
 }
 
-static size_t sched_fair_server_show(struct seq_file *m, void *v, enum dl_param param)
+static size_t sched_dl_server_show(struct seq_file *m, void *v, enum dl_param param)
 {
 	unsigned long cpu = (unsigned long) m->private;
 	struct rq *rq = cpu_rq(cpu);
 	u64 value;
 
 	switch (param) {
+	/*
+	 * The params for fair server and ext server as set via debugfs
+	 * are the same, so we can just use one of them
+	 */
 	case DL_RUNTIME:
 		value = rq->fair_server.dl_runtime;
 		break;
@@ -426,50 +443,50 @@ static size_t sched_fair_server_show(struct seq_file *m, void *v, enum dl_param
 }
 
 static ssize_t
-sched_fair_server_runtime_write(struct file *filp, const char __user *ubuf,
+sched_dl_server_runtime_write(struct file *filp, const char __user *ubuf,
 				size_t cnt, loff_t *ppos)
 {
-	return sched_fair_server_write(filp, ubuf, cnt, ppos, DL_RUNTIME);
+	return sched_dl_server_write(filp, ubuf, cnt, ppos, DL_RUNTIME);
 }
 
-static int sched_fair_server_runtime_show(struct seq_file *m, void *v)
+static int sched_dl_server_runtime_show(struct seq_file *m, void *v)
 {
-	return sched_fair_server_show(m, v, DL_RUNTIME);
+	return sched_dl_server_show(m, v, DL_RUNTIME);
 }
 
-static int sched_fair_server_runtime_open(struct inode *inode, struct file *filp)
+static int sched_dl_server_runtime_open(struct inode *inode, struct file *filp)
 {
-	return single_open(filp, sched_fair_server_runtime_show, inode->i_private);
+	return single_open(filp, sched_dl_server_runtime_show, inode->i_private);
 }
 
-static const struct file_operations fair_server_runtime_fops = {
-	.open		= sched_fair_server_runtime_open,
-	.write		= sched_fair_server_runtime_write,
+static const struct file_operations dl_server_runtime_fops = {
+	.open		= sched_dl_server_runtime_open,
+	.write		= sched_dl_server_runtime_write,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
 
 static ssize_t
-sched_fair_server_period_write(struct file *filp, const char __user *ubuf,
+sched_dl_server_period_write(struct file *filp, const char __user *ubuf,
 			       size_t cnt, loff_t *ppos)
 {
-	return sched_fair_server_write(filp, ubuf, cnt, ppos, DL_PERIOD);
+	return sched_dl_server_write(filp, ubuf, cnt, ppos, DL_PERIOD);
 }
 
-static int sched_fair_server_period_show(struct seq_file *m, void *v)
+static int sched_dl_server_period_show(struct seq_file *m, void *v)
 {
-	return sched_fair_server_show(m, v, DL_PERIOD);
+	return sched_dl_server_show(m, v, DL_PERIOD);
 }
 
-static int sched_fair_server_period_open(struct inode *inode, struct file *filp)
+static int sched_dl_server_period_open(struct inode *inode, struct file *filp)
 {
-	return single_open(filp, sched_fair_server_period_show, inode->i_private);
+	return single_open(filp, sched_dl_server_period_show, inode->i_private);
 }
 
-static const struct file_operations fair_server_period_fops = {
-	.open		= sched_fair_server_period_open,
-	.write		= sched_fair_server_period_write,
+static const struct file_operations dl_server_period_fops = {
+	.open		= sched_dl_server_period_open,
+	.write		= sched_dl_server_period_write,
 	.read		= seq_read,
 	.llseek		= seq_lseek,
 	.release	= single_release,
@@ -477,13 +494,13 @@ static const struct file_operations fair_server_period_fops = {
 
 static struct dentry *debugfs_sched;
 
-static void debugfs_fair_server_init(void)
+static void debugfs_dl_server_init(void)
 {
-	struct dentry *d_fair;
+	struct dentry *d_server;
 	unsigned long cpu;
 
-	d_fair = debugfs_create_dir("fair_server", debugfs_sched);
-	if (!d_fair)
+	d_server = debugfs_create_dir("dl_server", debugfs_sched);
+	if (!d_server)
 		return;
 
 	for_each_possible_cpu(cpu) {
@@ -491,10 +508,10 @@ static void debugfs_fair_server_init(void)
 		char buf[32];
 
 		snprintf(buf, sizeof(buf), "cpu%lu", cpu);
-		d_cpu = debugfs_create_dir(buf, d_fair);
+		d_cpu = debugfs_create_dir(buf, d_server);
 
-		debugfs_create_file("runtime", 0644, d_cpu, (void *) cpu, &fair_server_runtime_fops);
-		debugfs_create_file("period", 0644, d_cpu, (void *) cpu, &fair_server_period_fops);
+		debugfs_create_file("runtime", 0644, d_cpu, (void *) cpu, &dl_server_runtime_fops);
+		debugfs_create_file("period", 0644, d_cpu, (void *) cpu, &dl_server_period_fops);
 	}
 }
 
@@ -537,7 +554,7 @@ static __init int sched_init_debug(void)
 
 	debugfs_create_file("debug", 0444, debugfs_sched, NULL, &sched_debug_fops);
 
-	debugfs_fair_server_init();
+	debugfs_dl_server_init();
 
 	return 0;
 }
-- 
2.43.0
Re: [PATCH v2 06/10] sched/debug: Add support to change sched_ext server params
Posted by Juri Lelli 6 months, 2 weeks ago
Hi Joel,

On 02/06/25 14:01, Joel Fernandes wrote:
> When a sched_ext server is loaded, tasks in CFS are converted to run in
> sched_ext class. Modify the ext server parameters as well along with the
> fair ones.
> 
> Re-use the existing interface to modify both ext and fair servers to
> keep number of interfaces less (as it is, we have a per-cpu interface).

We have a bit of code duplication, don't we? I wonder if we can do
anything early on to prevent mis-alignment between servers in the
future.

Also, is a single shared interface enough? Is the assumption that either
all tasks are FAIR or SCX always guaranteed?

Thanks,
Juri
Re: [PATCH v2 06/10] sched/debug: Add support to change sched_ext server params
Posted by Tejun Heo 6 months, 2 weeks ago
On Wed, Jun 04, 2025 at 12:02:11PM +0200, Juri Lelli wrote:
> Hi Joel,
> 
> On 02/06/25 14:01, Joel Fernandes wrote:
> > When a sched_ext server is loaded, tasks in CFS are converted to run in
> > sched_ext class. Modify the ext server parameters as well along with the
> > fair ones.
> > 
> > Re-use the existing interface to modify both ext and fair servers to
> > keep number of interfaces less (as it is, we have a per-cpu interface).
> 
> We have a bit of code duplication, don't we? I wonder if we can do
> anything early on to prevent mis-alignment between servers in the
> future.
> 
> Also, is a single shared interface enough? Is the assumption that either
> all tasks are FAIR or SCX always guaranteed?

It's not a guarantee but at least all the current use cases are like that.
No objection to splitting the interface tho. In fact, for SCX, it may make
more sense to just make it part of sched_ext_ops, so that each scheduler can
specify what they want.

Thanks.

-- 
tejun
Re: [PATCH v2 06/10] sched/debug: Add support to change sched_ext server params
Posted by Joel Fernandes 6 months, 2 weeks ago
Hi,

On 6/4/2025 2:40 PM, Tejun Heo wrote:
> On Wed, Jun 04, 2025 at 12:02:11PM +0200, Juri Lelli wrote:
>> Hi Joel,
>>
>> On 02/06/25 14:01, Joel Fernandes wrote:
>>> When a sched_ext server is loaded, tasks in CFS are converted to run in
>>> sched_ext class. Modify the ext server parameters as well along with the
>>> fair ones.
>>>
>>> Re-use the existing interface to modify both ext and fair servers to
>>> keep number of interfaces less (as it is, we have a per-cpu interface).
>>
>> We have a bit of code duplication, don't we

Hmm, I did try to keep the duplication less but I'll give it another try.

>> I wonder if we can do
>> anything early on to prevent mis-alignment between servers in the
>> future.

Sure, let me look into that too.

>>
>> Also, is a single shared interface enough? Is the assumption that either
>> all tasks are FAIR or SCX always guaranteed?
> 
> It's not a guarantee but at least all the current use cases are like that.
> No objection to splitting the interface tho. In fact, for SCX, it may make
> more sense to just make it part of sched_ext_ops, so that each scheduler can
> specify what they want.

I am Ok with having different debugfs entries for different servers, and perhaps
we can reuse the code for both to reduce code duplication. Will work on that next.

thanks,

 - Joel