Commit 4c476d8c authored by Roman Gushchin's avatar Roman Gushchin Committed by Tejun Heo
Browse files

cgroup: add tracing points for cgroup v2 freezer



Add cgroup:cgroup_freeze and cgroup:cgroup_unfreeze events,
which are using the existing cgroup tracing infrastructure.

Add the cgroup_event event class, which is similar to the cgroup
class, but contains an additional integer field to store a new
value (the level field is dropped).

Also add two tracing events: cgroup_notify_populated and
cgroup_notify_frozen, which are raised in a generic way using
the TRACE_CGROUP_PATH() macro.

This allows to trace cgroup state transitions and is generally
helpful for debugging the cgroup freezer code.

Signed-off-by: default avatarRoman Gushchin <guro@fb.com>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent 712e3517
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -103,6 +103,20 @@ DEFINE_EVENT(cgroup, cgroup_rename,
	TP_ARGS(cgrp, path)
);

DEFINE_EVENT(cgroup, cgroup_freeze,

	TP_PROTO(struct cgroup *cgrp, const char *path),

	TP_ARGS(cgrp, path)
);

DEFINE_EVENT(cgroup, cgroup_unfreeze,

	TP_PROTO(struct cgroup *cgrp, const char *path),

	TP_ARGS(cgrp, path)
);

DECLARE_EVENT_CLASS(cgroup_migrate,

	TP_PROTO(struct cgroup *dst_cgrp, const char *path,
@@ -149,6 +163,47 @@ DEFINE_EVENT(cgroup_migrate, cgroup_transfer_tasks,
	TP_ARGS(dst_cgrp, path, task, threadgroup)
);

DECLARE_EVENT_CLASS(cgroup_event,

	TP_PROTO(struct cgroup *cgrp, const char *path, int val),

	TP_ARGS(cgrp, path, val),

	TP_STRUCT__entry(
		__field(	int,		root			)
		__field(	int,		id			)
		__field(	int,		level			)
		__string(	path,		path			)
		__field(	int,		val			)
	),

	TP_fast_assign(
		__entry->root = cgrp->root->hierarchy_id;
		__entry->id = cgrp->id;
		__entry->level = cgrp->level;
		__assign_str(path, path);
		__entry->val = val;
	),

	TP_printk("root=%d id=%d level=%d path=%s val=%d",
		  __entry->root, __entry->id, __entry->level, __get_str(path),
		  __entry->val)
);

DEFINE_EVENT(cgroup_event, cgroup_notify_populated,

	TP_PROTO(struct cgroup *cgrp, const char *path, int val),

	TP_ARGS(cgrp, path, val)
);

DEFINE_EVENT(cgroup_event, cgroup_notify_frozen,

	TP_PROTO(struct cgroup *cgrp, const char *path, int val),

	TP_ARGS(cgrp, path, val)
);

#endif /* _TRACE_CGROUP_H */

/* This part must be outside protection */
+2 −0
Original line number Diff line number Diff line
@@ -816,6 +816,8 @@ static void cgroup_update_populated(struct cgroup *cgrp, bool populated)
			break;

		cgroup1_check_for_release(cgrp);
		TRACE_CGROUP_PATH(notify_populated, cgrp,
				  cgroup_is_populated(cgrp));
		cgroup_file_notify(&cgrp->events_file);

		child = cgrp;
+14 −1
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@

#include "cgroup-internal.h"

#include <trace/events/cgroup.h>

/*
 * Propagate the cgroup frozen state upwards by the cgroup tree.
 */
@@ -28,6 +30,7 @@ static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
			    cgrp->nr_descendants) {
				set_bit(CGRP_FROZEN, &cgrp->flags);
				cgroup_file_notify(&cgrp->events_file);
				TRACE_CGROUP_PATH(notify_frozen, cgrp, 1);
				desc++;
			}
		} else {
@@ -35,6 +38,7 @@ static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
			if (test_bit(CGRP_FROZEN, &cgrp->flags)) {
				clear_bit(CGRP_FROZEN, &cgrp->flags);
				cgroup_file_notify(&cgrp->events_file);
				TRACE_CGROUP_PATH(notify_frozen, cgrp, 0);
				desc++;
			}
		}
@@ -73,6 +77,7 @@ void cgroup_update_frozen(struct cgroup *cgrp)
		clear_bit(CGRP_FROZEN, &cgrp->flags);
	}
	cgroup_file_notify(&cgrp->events_file);
	TRACE_CGROUP_PATH(notify_frozen, cgrp, frozen);

	/* Update the state of ancestor cgroups. */
	cgroup_propagate_frozen(cgrp, frozen);
@@ -189,6 +194,11 @@ static void cgroup_do_freeze(struct cgroup *cgrp, bool freeze)
		clear_bit(CGRP_FREEZE, &cgrp->flags);
	spin_unlock_irq(&css_set_lock);

	if (freeze)
		TRACE_CGROUP_PATH(freeze, cgrp);
	else
		TRACE_CGROUP_PATH(unfreeze, cgrp);

	css_task_iter_start(&cgrp->self, 0, &it);
	while ((task = css_task_iter_next(&it))) {
		/*
@@ -312,6 +322,9 @@ void cgroup_freeze(struct cgroup *cgrp, bool freeze)
	 * In both cases it's better to notify a user, that there is
	 * nothing to wait for.
	 */
	if (!applied)
	if (!applied) {
		TRACE_CGROUP_PATH(notify_frozen, cgrp,
				  test_bit(CGRP_FROZEN, &cgrp->flags));
		cgroup_file_notify(&cgrp->events_file);
	}
}