diff mbox series

[1/5] cgroup/cpuset: Don't call validate_change() for some flag changes

Message ID 20210603212416.25934-2-longman@redhat.com
State New
Headers show
Series cgroup/cpuset: Enable cpuset partition with no load balancing | expand

Commit Message

Waiman Long June 3, 2021, 9:24 p.m. UTC
The update_flag() is called with one flag bit change and without change
in the various cpumasks in the cpuset. Moreover, not all changes in the
flag bits are validated in validate_change().  In particular, the load
balance flag and the two spread flags are not checked there. So there
is no point in calling validate_change() if those flag bits change.

Signed-off-by: Waiman Long <longman@redhat.com>
---
 kernel/cgroup/cpuset.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

Comments

Tejun Heo June 16, 2021, 8:39 p.m. UTC | #1
Hello,

On Thu, Jun 03, 2021 at 05:24:12PM -0400, Waiman Long wrote:
> The update_flag() is called with one flag bit change and without change

> in the various cpumasks in the cpuset. Moreover, not all changes in the

> flag bits are validated in validate_change().  In particular, the load

> balance flag and the two spread flags are not checked there. So there

> is no point in calling validate_change() if those flag bits change.


The fact that it's escaping validation conditionally from caller side is
bothersome given that the idea is to have self-contained verifier to ensure
correctness. I'd prefer to make the validation more complete and optimized
(ie. detect or keep track of what changed) if really necessary rather than
escaping partially because certain conditions aren't checked.

Thanks.

-- 
tejun
Waiman Long June 17, 2021, 2:53 a.m. UTC | #2
On 6/16/21 4:39 PM, Tejun Heo wrote:
> Hello,

>

> On Thu, Jun 03, 2021 at 05:24:12PM -0400, Waiman Long wrote:

>> The update_flag() is called with one flag bit change and without change

>> in the various cpumasks in the cpuset. Moreover, not all changes in the

>> flag bits are validated in validate_change().  In particular, the load

>> balance flag and the two spread flags are not checked there. So there

>> is no point in calling validate_change() if those flag bits change.

> The fact that it's escaping validation conditionally from caller side is

> bothersome given that the idea is to have self-contained verifier to ensure

> correctness. I'd prefer to make the validation more complete and optimized

> (ie. detect or keep track of what changed) if really necessary rather than

> escaping partially because certain conditions aren't checked.


Thanks for the comments.

You are right. I will leave out this patch. Anyway, the rests of the 
patchset don't have a strict dependency on it.

Cheers,
Longman
diff mbox series

Patch

diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index adb5190c4429..65ad6995ad77 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1891,7 +1891,7 @@  static void update_tasks_flags(struct cpuset *cs)
  * cs:		the cpuset to update
  * turning_on: 	whether the flag is being set or cleared
  *
- * Call with cpuset_mutex held.
+ * Call with cpuset_mutex held & cpumasks remain unchanged.
  */
 
 static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
@@ -1911,16 +1911,22 @@  static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
 	else
 		clear_bit(bit, &trialcs->flags);
 
-	err = validate_change(cs, trialcs);
-	if (err < 0)
-		goto out;
-
 	balance_flag_changed = (is_sched_load_balance(cs) !=
 				is_sched_load_balance(trialcs));
 
 	spread_flag_changed = ((is_spread_slab(cs) != is_spread_slab(trialcs))
 			|| (is_spread_page(cs) != is_spread_page(trialcs)));
 
+	/*
+	 * validate_change() doesn't validate changes in load balance
+	 * and spread flags.
+	 */
+	if (!balance_flag_changed && !spread_flag_changed) {
+		err = validate_change(cs, trialcs);
+		if (err < 0)
+			goto out;
+	}
+
 	spin_lock_irq(&callback_lock);
 	cs->flags = trialcs->flags;
 	spin_unlock_irq(&callback_lock);