All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alessio Balsini <balsini@android.com>
To: Peter Zijlstra <peterz@infradead.org>
Cc: mingo@kernel.org, juri.lelli@redhat.com,
	linux-kernel@vger.kernel.org, dietmar.eggemann@arm.com,
	luca.abeni@santannapisa.it, bristot@redhat.com,
	dvyukov@google.com, tglx@linutronix.de, vpillai@digitalocean.com,
	rostedt@goodmis.org, kernel-team@android.com
Subject: Re: [RFC][PATCH 01/13] sched/deadline: Impose global limits on sched_attr::sched_period
Date: Sat, 31 Aug 2019 15:41:17 +0100	[thread overview]
Message-ID: <20190831144117.GA133727@google.com> (raw)
In-Reply-To: <20190822165125.GW2369@hirez.programming.kicks-ass.net>

Right!

Verified that sysctl_sched_dl_period_max and sysctl_sched_dl_period_min values
are now always consistent.

I spent some time in trying to figure out if not having any mutex in
__checkparam_dl() is safe. There can surely happen that "max < min", e.g.:

          |              |               periods
User1     | User2        | checkparam_dl()  | sysctl_sched_dl_*
----------|--------------|------------------|-------------------
          |              |                  | [x, x]
p_min = 5 |              |                  |
          |              |                  | [5, x]
p_max = 5 |              |                  |
          |              |                  | [5, 5]
          | setattr(p=8) |                  |
          |              | p = 8            |
          |              | [x, 5]           |
p_max = 9 |              |                  |
          |              |                  | [5, 9]
p_min = 6 |              |                  |
          |              |                  | [6, 9]
          |              | [6, 5]           |
----------|--------------|------------------|-------------------

Sharing my thoughts, a "BUG_ON(max < min)" in __checkparam_dl() is then a
guaranteed source of explosions, but the good news is that "if (period < min ||
period > max" in __checkparam_dl() surely fails if "max < min".  Also the fact
that, when we are writing the new sysctl_sched_dl_* values, only one is
actually changed at a time, that surely helps to preserve the consistency.

But is that enough?

Well, I couldn't find any counterexample to make __checkparam_dl() pass with
wrong parameters. And the tests I made are happy.

On Thu, Aug 22, 2019 at 06:51:25PM +0200, Peter Zijlstra wrote:
>  include/linux/sched/sysctl.h |    7 +++++
>  kernel/sched/deadline.c      |   58 +++++++++++++++++++++++++++++++++++++++++--
>  kernel/sysctl.c              |   14 ++++++++++
>  3 files changed, 77 insertions(+), 2 deletions(-)
> 
> --- a/kernel/sched/deadline.c
> +++ b/kernel/sched/deadline.c
> +int sched_dl_period_handler(struct ctl_table *table, int write,
> +			    void __user *buffer, size_t *lenp,
> +			    loff_t *ppos)
> +{
> +		if (min > 1ULL << DL_SCALE && max > min) {

s/>/>=/

> +			WRITE_ONCE(sysctl_sched_dl_period_max, new_max);
> +			WRITE_ONCE(sysctl_sched_dl_period_min, new_min);

Besides the inline comment above, this is my ack to your patch.

Otherwise, here follows a slightly more convoluted version of your patch with a
couple of changes to sched_dl_period_handler(), summarized as:
 - handle new_table only if writing;
 - directly compare the us min and max (saves one multiplication);
 - atomic-writes only the sysctl_sched_dl_period_XXX which changed.

M2c.

Thanks!
-Alessio

---
From cb4481233b57e42ff9dd315811f7919168a28162 Mon Sep 17 00:00:00 2001
From: Peter Zijlstra <peterz@infradead.org>
Date: Thu, 22 Aug 2019 18:51:25 +0200
Subject: [PATCH] sched/deadline: Impose global limits on
 sched_attr::sched_period

There are two DoS scenarios with SCHED_DEADLINE related to
sched_attr::sched_period:

 - since access-control only looks at utilization and density, a very
   large period can allow a very large runtime, which in turn can
   incur a very large latency to lower priority tasks.

 - for very short periods we can end up spending more time programming
   the hardware timer than actually running the task.

Mitigate these by imposing limits on the period.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Alessio Balsini <balsini@android.com>
Cc: rostedt@goodmis.org
Cc: mingo@kernel.org
Cc: luca.abeni@santannapisa.it
Cc: bristot@redhat.com
Cc: vpillai@digitalocean.com
Cc: kernel-team@android.com
Cc: juri.lelli@redhat.com
Cc: dietmar.eggemann@arm.com
Cc: dvyukov@google.com
Cc: tglx@linutronix.de
---
 include/linux/sched/sysctl.h |  7 ++++
 kernel/sched/deadline.c      | 68 ++++++++++++++++++++++++++++++++++--
 kernel/sysctl.c              | 14 ++++++++
 3 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h
index d4f6215ee03f7..7c8ef07e52133 100644
--- a/include/linux/sched/sysctl.h
+++ b/include/linux/sched/sysctl.h
@@ -56,6 +56,13 @@ int sched_proc_update_handler(struct ctl_table *table, int write,
 extern unsigned int sysctl_sched_rt_period;
 extern int sysctl_sched_rt_runtime;
 
+extern unsigned int sysctl_sched_dl_period_max;
+extern unsigned int sysctl_sched_dl_period_min;
+
+extern int sched_dl_period_handler(struct ctl_table *table, int write,
+		void __user *buffer, size_t *lenp,
+		loff_t *ppos);
+
 #ifdef CONFIG_UCLAMP_TASK
 extern unsigned int sysctl_sched_uclamp_util_min;
 extern unsigned int sysctl_sched_uclamp_util_max;
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 0b9cbfb2b1d4f..c4a6107e055c7 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -2640,6 +2640,59 @@ void __getparam_dl(struct task_struct *p, struct sched_attr *attr)
 	attr->sched_flags = dl_se->flags;
 }
 
+/*
+ * Default limits for DL period: on the top end we guard against small util
+ * tasks still getting ridiculous long effective runtimes, on the bottom end we
+ * guard against timer DoS.
+ */
+unsigned int sysctl_sched_dl_period_max = 1 << 22; /* ~4.2 seconds */
+unsigned int sysctl_sched_dl_period_min = 100;     /* 100 us */
+
+int sched_dl_period_handler(struct ctl_table *table, int write,
+			    void __user *buffer, size_t *lenp,
+			    loff_t *ppos)
+{
+	static DEFINE_MUTEX(mutex);
+	int ret;
+
+	mutex_lock(&mutex);
+	if (write) {
+		/*
+		 * Use a temporary data structure to store the value read from
+		 * userspace. The sysctl_sched_dl_period_{max,min} value will
+		 * be updated only if the data is consistent.
+		 */
+		struct ctl_table new_table = *table;
+		unsigned int max, min;
+
+		if (new_table.data == &sysctl_sched_dl_period_max) {
+			new_table.data = &max;
+			min = sysctl_sched_dl_period_min;
+		} else {
+			new_table.data = &min;
+			max = sysctl_sched_dl_period_max;
+		}
+
+		ret = proc_douintvec(&new_table, write, buffer, lenp, ppos);
+		if (!ret) {
+			if (min > max ||
+			    (u64)min * NSEC_PER_USEC < 1ULL << DL_SCALE) {
+				ret = -EINVAL;
+			} else {
+				unsigned int *src = new_table.data;
+				unsigned int *dst = table->data;
+
+				WRITE_ONCE(*dst, *src);
+			}
+		}
+	} else {
+		ret = proc_douintvec(table, write, buffer, lenp, ppos);
+	}
+	mutex_unlock(&mutex);
+
+	return ret;
+}
+
 /*
  * This function validates the new parameters of a -deadline task.
  * We ask for the deadline not being zero, and greater or equal
@@ -2652,6 +2705,8 @@ void __getparam_dl(struct task_struct *p, struct sched_attr *attr)
  */
 bool __checkparam_dl(const struct sched_attr *attr)
 {
+	u64 period, max, min;
+
 	/* special dl tasks don't actually use any parameter */
 	if (attr->sched_flags & SCHED_FLAG_SUGOV)
 		return true;
@@ -2675,12 +2730,21 @@ bool __checkparam_dl(const struct sched_attr *attr)
 	    attr->sched_period & (1ULL << 63))
 		return false;
 
+	period = attr->sched_period;
+	if (!period)
+		period = attr->sched_deadline;
+
 	/* runtime <= deadline <= period (if period != 0) */
-	if ((attr->sched_period != 0 &&
-	     attr->sched_period < attr->sched_deadline) ||
+	if (period < attr->sched_deadline ||
 	    attr->sched_deadline < attr->sched_runtime)
 		return false;
 
+	max = (u64)READ_ONCE(sysctl_sched_dl_period_max) * NSEC_PER_USEC;
+	min = (u64)READ_ONCE(sysctl_sched_dl_period_min) * NSEC_PER_USEC;
+
+	if (period < min || period > max)
+		return false;
+
 	return true;
 }
 
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 078950d9605ba..0d07e4707e9d2 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -442,6 +442,20 @@ static struct ctl_table kern_table[] = {
 		.mode		= 0644,
 		.proc_handler	= sched_rt_handler,
 	},
+	{
+		.procname	= "sched_deadline_period_max_us",
+		.data		= &sysctl_sched_dl_period_max,
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= sched_dl_period_handler,
+	},
+	{
+		.procname	= "sched_deadline_period_min_us",
+		.data		= &sysctl_sched_dl_period_min,
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= sched_dl_period_handler,
+	},
 	{
 		.procname	= "sched_rr_timeslice_ms",
 		.data		= &sysctl_sched_rr_timeslice,
-- 
2.23.0.187.g17f5b7556c-goog



  reply	other threads:[~2019-08-31 14:41 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-26 14:54 [RFC][PATCH 00/13] SCHED_DEADLINE server infrastructure Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 01/13] sched/deadline: Impose global limits on sched_attr::sched_period Peter Zijlstra
2019-07-29  8:57   ` Juri Lelli
2019-07-29 11:45     ` Daniel Bristot de Oliveira
2019-08-02 17:21   ` Alessio Balsini
2019-08-05 11:53     ` Peter Zijlstra
2019-08-22 12:29       ` Alessio Balsini
2019-08-22 16:51         ` Peter Zijlstra
2019-08-31 14:41           ` Alessio Balsini [this message]
2019-09-02  9:16             ` Peter Zijlstra
2019-09-02 12:31               ` Peter Zijlstra
2019-09-04 10:16               ` Steven Rostedt
2019-09-04 11:30                 ` Peter Zijlstra
2019-09-04 13:24                   ` Joel Fernandes
2019-09-04 14:11                     ` Will Deacon
2019-09-04 14:35                       ` Joel Fernandes
2019-09-04 15:52                     ` Peter Zijlstra
2019-10-23 17:17       ` [PATCH 4.4 4.9 4.14] loop: Add LOOP_SET_DIRECT_IO to compat ioctl Alessio Balsini
2019-10-23 17:22         ` Alessio Balsini
2019-10-25  0:17         ` Sasha Levin
2020-05-20 18:38   ` [RFC][PATCH 01/13] sched/deadline: Impose global limits on sched_attr::sched_period Juri Lelli
2020-05-21 13:45     ` Daniel Bristot de Oliveira
2020-06-16 12:21   ` [tip: sched/core] " tip-bot2 for Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 02/13] stop_machine: Fix stop_cpus_in_progress ordering Peter Zijlstra
2019-07-30 13:16   ` Phil Auld
2019-07-30 13:22   ` Steven Rostedt
2019-07-26 14:54 ` [RFC][PATCH 03/13] sched: Fix kerneldoc comment for ia64_set_curr_task Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 04/13] sched/{rt,deadline}: Fix set_next_task vs pick_next_task Peter Zijlstra
2019-07-29  9:25   ` Juri Lelli
2019-07-29 11:15     ` Peter Zijlstra
2019-07-29 11:27       ` Juri Lelli
2019-07-29 13:04         ` Peter Zijlstra
2019-07-29 13:17           ` Juri Lelli
2019-07-29 14:40             ` Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 05/13] sched: Add task_struct pointer to sched_class::set_curr_task Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 06/13] sched/fair: Export newidle_balance() Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 07/13] sched: Allow put_prev_task() to drop rq->lock Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 08/13] sched: Rework pick_next_task() slow-path Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 09/13] sched: Unify runtime accounting across classes Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 10/13] sched/deadline: Collect sched_dl_entity initialization Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 11/13] sched/deadline: Move bandwidth accounting into {en,de}queue_dl_entity Peter Zijlstra
2019-07-26 14:54 ` [RFC][PATCH 12/13] sched/deadline: Introduce deadline servers Peter Zijlstra
2019-08-07 16:31   ` Dietmar Eggemann
2019-08-08  6:52     ` Juri Lelli
2019-08-08  7:52       ` Dietmar Eggemann
2019-08-08  7:56     ` Peter Zijlstra
2019-08-08  8:11       ` Dietmar Eggemann
2019-08-08  8:46         ` Juri Lelli
2019-08-08  8:57           ` Dietmar Eggemann
2019-08-08  9:27             ` Juri Lelli
2019-08-08  9:45               ` Juri Lelli
2019-08-30 11:24                 ` Peter Zijlstra
2019-09-06  9:36                   ` Juri Lelli
2019-08-08 10:31           ` Peter Zijlstra
2019-08-09  7:13             ` Juri Lelli
2019-08-08  6:59   ` Juri Lelli
2019-08-09  9:17   ` Dietmar Eggemann
2019-08-09 12:16     ` Juri Lelli
2019-07-26 14:54 ` [RFC][PATCH 13/13] sched/fair: Add trivial fair server Peter Zijlstra
2019-07-26 20:01 ` [RFC][PATCH 00/13] SCHED_DEADLINE server infrastructure luca abeni
2019-09-03 14:27 ` Alessio Balsini
2019-09-04 10:50   ` Juri Lelli
2019-09-04 11:32     ` Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190831144117.GA133727@google.com \
    --to=balsini@android.com \
    --cc=bristot@redhat.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=dvyukov@google.com \
    --cc=juri.lelli@redhat.com \
    --cc=kernel-team@android.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luca.abeni@santannapisa.it \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=vpillai@digitalocean.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.