diff options
Diffstat (limited to 'kernel/cgroup_freezer.c')
-rw-r--r-- | kernel/cgroup_freezer.c | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c index 224da9aa27f5..f0ff64d0ebaa 100644 --- a/kernel/cgroup_freezer.c +++ b/kernel/cgroup_freezer.c | |||
@@ -311,7 +311,6 @@ static int freezer_read(struct cgroup_subsys_state *css, struct cftype *cft, | |||
311 | /* update states bottom-up */ | 311 | /* update states bottom-up */ |
312 | css_for_each_descendant_post(pos, css) | 312 | css_for_each_descendant_post(pos, css) |
313 | update_if_frozen(pos); | 313 | update_if_frozen(pos); |
314 | update_if_frozen(css); | ||
315 | 314 | ||
316 | rcu_read_unlock(); | 315 | rcu_read_unlock(); |
317 | 316 | ||
@@ -391,11 +390,6 @@ static void freezer_change_state(struct freezer *freezer, bool freeze) | |||
391 | { | 390 | { |
392 | struct cgroup_subsys_state *pos; | 391 | struct cgroup_subsys_state *pos; |
393 | 392 | ||
394 | /* update @freezer */ | ||
395 | spin_lock_irq(&freezer->lock); | ||
396 | freezer_apply_state(freezer, freeze, CGROUP_FREEZING_SELF); | ||
397 | spin_unlock_irq(&freezer->lock); | ||
398 | |||
399 | /* | 393 | /* |
400 | * Update all its descendants in pre-order traversal. Each | 394 | * Update all its descendants in pre-order traversal. Each |
401 | * descendant will try to inherit its parent's FREEZING state as | 395 | * descendant will try to inherit its parent's FREEZING state as |
@@ -406,14 +400,23 @@ static void freezer_change_state(struct freezer *freezer, bool freeze) | |||
406 | struct freezer *pos_f = css_freezer(pos); | 400 | struct freezer *pos_f = css_freezer(pos); |
407 | struct freezer *parent = parent_freezer(pos_f); | 401 | struct freezer *parent = parent_freezer(pos_f); |
408 | 402 | ||
409 | /* | ||
410 | * Our update to @parent->state is already visible which is | ||
411 | * all we need. No need to lock @parent. For more info on | ||
412 | * synchronization, see freezer_post_create(). | ||
413 | */ | ||
414 | spin_lock_irq(&pos_f->lock); | 403 | spin_lock_irq(&pos_f->lock); |
415 | freezer_apply_state(pos_f, parent->state & CGROUP_FREEZING, | 404 | |
416 | CGROUP_FREEZING_PARENT); | 405 | if (pos_f == freezer) { |
406 | freezer_apply_state(pos_f, freeze, | ||
407 | CGROUP_FREEZING_SELF); | ||
408 | } else { | ||
409 | /* | ||
410 | * Our update to @parent->state is already visible | ||
411 | * which is all we need. No need to lock @parent. | ||
412 | * For more info on synchronization, see | ||
413 | * freezer_post_create(). | ||
414 | */ | ||
415 | freezer_apply_state(pos_f, | ||
416 | parent->state & CGROUP_FREEZING, | ||
417 | CGROUP_FREEZING_PARENT); | ||
418 | } | ||
419 | |||
417 | spin_unlock_irq(&pos_f->lock); | 420 | spin_unlock_irq(&pos_f->lock); |
418 | } | 421 | } |
419 | rcu_read_unlock(); | 422 | rcu_read_unlock(); |