[Devel] [PATCH RH7] cgroup_freezer: print information about unfreezable process

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Fri Nov 25 14:55:51 MSK 2022


I found one improvement which can be done while porting to vz9, see inline:

On 24.11.2022 21:46, Pavel Tikhomirov wrote:
> Add a sysctl kernel.freeze_cgroup_timeout (default value 30 * HZ).
> 
> If one writes FROZEN to freezer.state file and after a timeout of
> kernel.freeze_cgroup_timeout one still reads FREEZING from freezer.state
> file (meaning that kernel does not succeed to freeze cgroup processes
> still) - let's print a warning with information about the problem, e.g.:
> 
> [ 7196.621368] Freeze of /test took 0 sec, due to unfreezable process 13732:bash, stack:
> [ 7196.621396] [<ffffffffa2df9556>] retint_careful+0x14/0x32
> [ 7196.621431] [<ffffffffffffffff>] 0xffffffffffffffff
> 
> The output includes:
> - path to problematic freezer cgroup
> - timeout in seconds
> - unfeezable process pid, comm and stack
> 
> https://jira.sw.ru/browse/PSBM-142970
> 
> Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> ---
> Will send for vz9 separately, it does not apply cleanly.
> ---
>   include/linux/sysctl.h  |  2 ++
>   kernel/cgroup_freezer.c | 55 ++++++++++++++++++++++++++++++++++++++---
>   kernel/sysctl.c         | 10 ++++++++
>   3 files changed, 64 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
> index f28d9fb58c03..798b0465cb93 100644
> --- a/include/linux/sysctl.h
> +++ b/include/linux/sysctl.h
> @@ -189,6 +189,8 @@ struct ctl_path {
>   extern int ve_allow_module_load;
>   extern int __read_mostly lazytime_default;
>   extern int trusted_exec;
> +#define DEFAULT_FREEZE_TIMEOUT (30 * HZ)
> +extern int sysctl_freeze_timeout;
>   
>   #ifdef CONFIG_SYSCTL
>   
> diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c
> index f31d68f55db0..343ebfed05fc 100644
> --- a/kernel/cgroup_freezer.c
> +++ b/kernel/cgroup_freezer.c
> @@ -21,6 +21,10 @@
>   #include <linux/uaccess.h>
>   #include <linux/freezer.h>
>   #include <linux/seq_file.h>
> +#include <linux/jiffies.h>
> +#include <linux/ratelimit.h>
> +#include <linux/stacktrace.h>
> +#include <linux/sysctl.h>
>   
>   /*
>    * A cgroup is freezing if any FREEZING flags are set.  FREEZING_SELF is
> @@ -43,6 +47,7 @@ struct freezer {
>   	struct cgroup_subsys_state	css;
>   	unsigned int			state;
>   	spinlock_t			lock;
> +	unsigned long			freeze_jiffies;
>   };
>   
>   static inline struct freezer *cgroup_freezer(struct cgroup *cgroup)
> @@ -242,6 +247,44 @@ static void freezer_fork(struct task_struct *task, void *private)
>   	rcu_read_unlock();
>   }
>   
> +#define MAX_STACK_TRACE_DEPTH   64
> +
> +static void check_freezer_timeout(struct cgroup *cgroup, struct task_struct *task)
> +{
> +	static DEFINE_RATELIMIT_STATE(freeze_timeout_rs, DEFAULT_FREEZE_TIMEOUT, 1);
> +	int __freeze_timeout = READ_ONCE(sysctl_freeze_timeout);
> +	struct freezer *freezer = cgroup_freezer(cgroup);
> +	unsigned long entries[MAX_STACK_TRACE_DEPTH];
> +	static char freezer_cg_name[PATH_MAX];
> +	struct stack_trace trace;
> +	pid_t tgid;
> +	int i;
> +
> +	if (!freezer->freeze_jiffies ||
> +	    freezer->freeze_jiffies + __freeze_timeout > get_jiffies_64())
> +		return;
> +
> +	if (!__ratelimit(&freeze_timeout_rs))
> +		return;
> +
> +	if (cgroup_path(cgroup, freezer_cg_name, PATH_MAX) < 0)
> +		return;
> +
> +	tgid = task_pid_nr_ns(task, &init_pid_ns);
> +
> +	printk(KERN_WARNING "Freeze of %s took %d sec, due to unfreezable process %d:%s, stack:\n",
> +	       freezer_cg_name, __freeze_timeout/HZ, tgid, task->comm);
> +
> +	memset(&trace, 0, sizeof(trace));
> +	trace.max_entries = MAX_STACK_TRACE_DEPTH;
> +	trace.entries = entries;
> +	save_stack_trace_tsk(task, &trace);
> +
> +	for (i = 0; i < trace.nr_entries; i++) {
> +		printk(KERN_WARNING "[<%pK>] %pS\n", (void *)entries[i], (void *)entries[i]);

%pB is better than %pS, seee 8b927d734122 ("proc: Fix return address 
printk conversion specifer in /proc/<pid>/stack")

> +	}
> +}
> +
>   /**
>    * update_if_frozen - update whether a cgroup finished freezing
>    * @cgroup: cgroup of interest
> @@ -293,8 +336,10 @@ static void update_if_frozen(struct cgroup *cgroup)
>   			 * completion.  Consider it frozen in addition to
>   			 * the usual frozen condition.
>   			 */
> -			if (!frozen(task) && !freezer_should_skip(task))
> +			if (!frozen(task) && !freezer_should_skip(task)) {
> +				check_freezer_timeout(cgroup, task);
>   				goto out_iter_end;
> +			}
>   		}
>   	}
>   
> @@ -367,8 +412,10 @@ static void freezer_apply_state(struct freezer *freezer, bool freeze,
>   		return;
>   
>   	if (freeze) {
> -		if (!(freezer->state & CGROUP_FREEZING))
> +		if (!(freezer->state & CGROUP_FREEZING)) {
>   			atomic_inc(&system_freezing_cnt);
> +			freezer->freeze_jiffies = get_jiffies_64();
> +		}
>   		freezer->state |= state;
>   		freeze_cgroup(freezer);
>   	} else {
> @@ -377,8 +424,10 @@ static void freezer_apply_state(struct freezer *freezer, bool freeze,
>   		freezer->state &= ~state;
>   
>   		if (!(freezer->state & CGROUP_FREEZING)) {
> -			if (was_freezing)
> +			if (was_freezing) {
> +				freezer->freeze_jiffies = 0;
>   				atomic_dec(&system_freezing_cnt);
> +			}
>   			freezer->state &= ~CGROUP_FROZEN;
>   			unfreeze_cgroup(freezer);
>   		}
> diff --git a/kernel/sysctl.c b/kernel/sysctl.c
> index 6ccebbfaf9c8..b8dd96172edf 100644
> --- a/kernel/sysctl.c
> +++ b/kernel/sysctl.c
> @@ -130,6 +130,8 @@ static int __init set_trusted_exec(char *str)
>   }
>   __setup("trusted_exec", set_trusted_exec);
>   
> +int sysctl_freeze_timeout = DEFAULT_FREEZE_TIMEOUT;
> +
>   /* Constants used for minimum and  maximum */
>   #ifdef CONFIG_LOCKUP_DETECTOR
>   static int sixty = 60;
> @@ -1281,6 +1283,14 @@ static struct ctl_table kern_table[] = {
>   		.extra2         = &one,
>   	},
>   #endif
> +	{
> +		.procname	= "freeze_cgroup_timeout",
> +		.data		= &sysctl_freeze_timeout,
> +		.maxlen		= sizeof(int),
> +		.mode		= 0644,
> +		.proc_handler	= proc_dointvec_minmax,
> +		.extra1		= &zero,
> +	},
>   	{ }
>   };
>   

-- 
Best regards, Tikhomirov Pavel
Software Developer, Virtuozzo.


More information about the Devel mailing list