Re: [PATHC v3 -next 3/3] cgroup/freezer: Reduce redundant propagation for cgroup_propagate_frozen

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Sep 15, 2024 at 07:13:07AM GMT, Chen Ridong <chenridong@xxxxxxxxxx> wrote:
> diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
> index dd1ecab99eeb..41e4e5a7ae55 100644
> --- a/include/linux/cgroup-defs.h
> +++ b/include/linux/cgroup-defs.h
> @@ -401,7 +401,9 @@ struct cgroup_freezer_state {
>  
>  	/* Fields below are protected by css_set_lock */
>  
> -	/* Number of frozen descendant cgroups */
> +	/* Aggregating frozen descendant cgroups, only when all
> +	 * descendants of a child are frozen will the count increase.
> +	 */
>  	int nr_frozen_descendants;
>  
>  	/*
> diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c
> index bf1690a167dd..4ee33198d6fb 100644
> --- a/kernel/cgroup/freezer.c
> +++ b/kernel/cgroup/freezer.c
> @@ -35,27 +35,34 @@ static bool cgroup_update_frozen_flag(struct cgroup *cgrp, bool frozen)
>   */
>  static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
>  {
> -	int desc = 1;
> -
> +	int deta;
            delta

> +	struct cgroup *parent;

I'd suggest here something like

	/* root cgroup never changes freeze state */
	if (WARN_ON(cgroup_parent(cgrp))
		return;

so that the parent-> dereference below is explicitly safe.

>  	/*
>  	 * If the new state is frozen, some freezing ancestor cgroups may change
>  	 * their state too, depending on if all their descendants are frozen.
>  	 *
>  	 * Otherwise, all ancestor cgroups are forced into the non-frozen state.
>  	 */
> -	while ((cgrp = cgroup_parent(cgrp))) {
> +	for (; cgrp; cgrp = cgroup_parent(cgrp)) {
>  		if (frozen) {
> -			cgrp->freezer.nr_frozen_descendants += desc;
> +			/* If freezer is not set, or cgrp has descendants
> +			 * that are not frozen, cgrp can't be frozen
> +			 */
>  			if (!test_bit(CGRP_FREEZE, &cgrp->flags) ||
>  			    (cgrp->freezer.nr_frozen_descendants !=
> -			    cgrp->nr_descendants))
> -				continue;
> +			     cgrp->nr_descendants))
> +				break;
> +			deta = cgrp->freezer.nr_frozen_descendants + 1;
>  		} else {
> -			cgrp->freezer.nr_frozen_descendants -= desc;
> +			deta = -(cgrp->freezer.nr_frozen_descendants + 1);

In this branch, if cgrp is unfrozen, delta = -1 is cgrp itself,
however is delta = -cgrp->freezer.nr_frozen_descendants warranted?
What if they are frozen empty children (of cgrp)? They likely shouldn't
be subtracted from ancestors nf_frozen_descendants.

(This refers to a situation when

	C	CGRP_FREEZE is set
	|\
	D E	both CGRP_FREEZE is set

and an unfrozen task is migrated into C which would make C (temporarily)
unfrozen but not D nor E.)


>  		}
>  
> -		if (cgroup_update_frozen_flag(cgrp, frozen))
> -			desc++;
> +		/* No change, stop propagate */
> +		if (!cgroup_update_frozen_flag(cgrp, frozen))
> +			break;
> +
> +		parent = cgroup_parent(cgrp);
> +		parent->freezer.nr_frozen_descendants += deta;


Thanks,
Michal

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [Monitors]

  Powered by Linux