Message ID | 20210603212416.25934-2-longman@redhat.com |
---|---|
State | New |
Headers | show |
Series | cgroup/cpuset: Enable cpuset partition with no load balancing | expand |
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
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 --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);
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(-)