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

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
...@@ -103,6 +103,20 @@ DEFINE_EVENT(cgroup, cgroup_rename, ...@@ -103,6 +103,20 @@ DEFINE_EVENT(cgroup, cgroup_rename,
TP_ARGS(cgrp, path) 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, DECLARE_EVENT_CLASS(cgroup_migrate,
TP_PROTO(struct cgroup *dst_cgrp, const char *path, TP_PROTO(struct cgroup *dst_cgrp, const char *path,
...@@ -149,6 +163,47 @@ DEFINE_EVENT(cgroup_migrate, cgroup_transfer_tasks, ...@@ -149,6 +163,47 @@ DEFINE_EVENT(cgroup_migrate, cgroup_transfer_tasks,
TP_ARGS(dst_cgrp, path, task, threadgroup) 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 */ #endif /* _TRACE_CGROUP_H */
/* This part must be outside protection */ /* This part must be outside protection */
......
...@@ -816,6 +816,8 @@ static void cgroup_update_populated(struct cgroup *cgrp, bool populated) ...@@ -816,6 +816,8 @@ static void cgroup_update_populated(struct cgroup *cgrp, bool populated)
break; break;
cgroup1_check_for_release(cgrp); cgroup1_check_for_release(cgrp);
TRACE_CGROUP_PATH(notify_populated, cgrp,
cgroup_is_populated(cgrp));
cgroup_file_notify(&cgrp->events_file); cgroup_file_notify(&cgrp->events_file);
child = cgrp; child = cgrp;
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include "cgroup-internal.h" #include "cgroup-internal.h"
#include <trace/events/cgroup.h>
/* /*
* Propagate the cgroup frozen state upwards by the cgroup tree. * Propagate the cgroup frozen state upwards by the cgroup tree.
*/ */
...@@ -28,6 +30,7 @@ static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen) ...@@ -28,6 +30,7 @@ static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
cgrp->nr_descendants) { cgrp->nr_descendants) {
set_bit(CGRP_FROZEN, &cgrp->flags); set_bit(CGRP_FROZEN, &cgrp->flags);
cgroup_file_notify(&cgrp->events_file); cgroup_file_notify(&cgrp->events_file);
TRACE_CGROUP_PATH(notify_frozen, cgrp, 1);
desc++; desc++;
} }
} else { } else {
...@@ -35,6 +38,7 @@ static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen) ...@@ -35,6 +38,7 @@ static void cgroup_propagate_frozen(struct cgroup *cgrp, bool frozen)
if (test_bit(CGRP_FROZEN, &cgrp->flags)) { if (test_bit(CGRP_FROZEN, &cgrp->flags)) {
clear_bit(CGRP_FROZEN, &cgrp->flags); clear_bit(CGRP_FROZEN, &cgrp->flags);
cgroup_file_notify(&cgrp->events_file); cgroup_file_notify(&cgrp->events_file);
TRACE_CGROUP_PATH(notify_frozen, cgrp, 0);
desc++; desc++;
} }
} }
...@@ -73,6 +77,7 @@ void cgroup_update_frozen(struct cgroup *cgrp) ...@@ -73,6 +77,7 @@ void cgroup_update_frozen(struct cgroup *cgrp)
clear_bit(CGRP_FROZEN, &cgrp->flags); clear_bit(CGRP_FROZEN, &cgrp->flags);
} }
cgroup_file_notify(&cgrp->events_file); cgroup_file_notify(&cgrp->events_file);
TRACE_CGROUP_PATH(notify_frozen, cgrp, frozen);
/* Update the state of ancestor cgroups. */ /* Update the state of ancestor cgroups. */
cgroup_propagate_frozen(cgrp, frozen); cgroup_propagate_frozen(cgrp, frozen);
...@@ -189,6 +194,11 @@ static void cgroup_do_freeze(struct cgroup *cgrp, bool freeze) ...@@ -189,6 +194,11 @@ static void cgroup_do_freeze(struct cgroup *cgrp, bool freeze)
clear_bit(CGRP_FREEZE, &cgrp->flags); clear_bit(CGRP_FREEZE, &cgrp->flags);
spin_unlock_irq(&css_set_lock); 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); css_task_iter_start(&cgrp->self, 0, &it);
while ((task = css_task_iter_next(&it))) { while ((task = css_task_iter_next(&it))) {
/* /*
...@@ -312,6 +322,9 @@ void cgroup_freeze(struct cgroup *cgrp, bool freeze) ...@@ -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 * In both cases it's better to notify a user, that there is
* nothing to wait for. * 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); cgroup_file_notify(&cgrp->events_file);
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment