aboutsummaryrefslogtreecommitdiffstats
path: root/include/trace
diff options
context:
space:
mode:
authorSteven Rostedt (VMware) <rostedt@goodmis.org>2018-07-09 17:48:54 -0400
committerTejun Heo <tj@kernel.org>2018-07-11 13:48:47 -0400
commite4f8d81c738db6d3ffdabfb8329aa2feaa310699 (patch)
tree97153959e7c625bc49850709149a1faa5146a70e /include/trace
parent1e09177acae32a61586af26d83ca5ef591cdcaf5 (diff)
cgroup/tracing: Move taking of spin lock out of trace event handlers
It is unwise to take spin locks from the handlers of trace events. Mainly, because they can introduce lockups, because it introduces locks in places that are normally not tested. Worse yet, because trace events are tucked away in the include/trace/events/ directory, locks that are taken there are forgotten about. As a general rule, I tell people never to take any locks in a trace event handler. Several cgroup trace event handlers call cgroup_path() which eventually takes the kernfs_rename_lock spinlock. This injects the spinlock in the code without people realizing it. It also can cause issues for the PREEMPT_RT patch, as the spinlock becomes a mutex, and the trace event handlers are called with preemption disabled. By moving the calculation of the cgroup_path() out of the trace event handlers and into a macro (surrounded by a trace_cgroup_##type##_enabled()), then we could place the cgroup_path into a string, and pass that to the trace event. Not only does this remove the taking of the spinlock out of the trace event handler, but it also means that the cgroup_path() only needs to be called once (it is currently called twice, once to get the length to reserver the buffer for, and once again to get the path itself. Now it only needs to be done once. Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'include/trace')
-rw-r--r--include/trace/events/cgroup.h47
1 files changed, 23 insertions, 24 deletions
diff --git a/include/trace/events/cgroup.h b/include/trace/events/cgroup.h
index d74722c2ac8b..a401ff5e7847 100644
--- a/include/trace/events/cgroup.h
+++ b/include/trace/events/cgroup.h
@@ -53,24 +53,22 @@ DEFINE_EVENT(cgroup_root, cgroup_remount,
53 53
54DECLARE_EVENT_CLASS(cgroup, 54DECLARE_EVENT_CLASS(cgroup,
55 55
56 TP_PROTO(struct cgroup *cgrp), 56 TP_PROTO(struct cgroup *cgrp, const char *path),
57 57
58 TP_ARGS(cgrp), 58 TP_ARGS(cgrp, path),
59 59
60 TP_STRUCT__entry( 60 TP_STRUCT__entry(
61 __field( int, root ) 61 __field( int, root )
62 __field( int, id ) 62 __field( int, id )
63 __field( int, level ) 63 __field( int, level )
64 __dynamic_array(char, path, 64 __string( path, path )
65 cgroup_path(cgrp, NULL, 0) + 1)
66 ), 65 ),
67 66
68 TP_fast_assign( 67 TP_fast_assign(
69 __entry->root = cgrp->root->hierarchy_id; 68 __entry->root = cgrp->root->hierarchy_id;
70 __entry->id = cgrp->id; 69 __entry->id = cgrp->id;
71 __entry->level = cgrp->level; 70 __entry->level = cgrp->level;
72 cgroup_path(cgrp, __get_dynamic_array(path), 71 __assign_str(path, path);
73 __get_dynamic_array_len(path));
74 ), 72 ),
75 73
76 TP_printk("root=%d id=%d level=%d path=%s", 74 TP_printk("root=%d id=%d level=%d path=%s",
@@ -79,45 +77,45 @@ DECLARE_EVENT_CLASS(cgroup,
79 77
80DEFINE_EVENT(cgroup, cgroup_mkdir, 78DEFINE_EVENT(cgroup, cgroup_mkdir,
81 79
82 TP_PROTO(struct cgroup *cgroup), 80 TP_PROTO(struct cgroup *cgrp, const char *path),
83 81
84 TP_ARGS(cgroup) 82 TP_ARGS(cgrp, path)
85); 83);
86 84
87DEFINE_EVENT(cgroup, cgroup_rmdir, 85DEFINE_EVENT(cgroup, cgroup_rmdir,
88 86
89 TP_PROTO(struct cgroup *cgroup), 87 TP_PROTO(struct cgroup *cgrp, const char *path),
90 88
91 TP_ARGS(cgroup) 89 TP_ARGS(cgrp, path)
92); 90);
93 91
94DEFINE_EVENT(cgroup, cgroup_release, 92DEFINE_EVENT(cgroup, cgroup_release,
95 93
96 TP_PROTO(struct cgroup *cgroup), 94 TP_PROTO(struct cgroup *cgrp, const char *path),
97 95
98 TP_ARGS(cgroup) 96 TP_ARGS(cgrp, path)
99); 97);
100 98
101DEFINE_EVENT(cgroup, cgroup_rename, 99DEFINE_EVENT(cgroup, cgroup_rename,
102 100
103 TP_PROTO(struct cgroup *cgroup), 101 TP_PROTO(struct cgroup *cgrp, const char *path),
104 102
105 TP_ARGS(cgroup) 103 TP_ARGS(cgrp, path)
106); 104);
107 105
108DECLARE_EVENT_CLASS(cgroup_migrate, 106DECLARE_EVENT_CLASS(cgroup_migrate,
109 107
110 TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup), 108 TP_PROTO(struct cgroup *dst_cgrp, const char *path,
109 struct task_struct *task, bool threadgroup),
111 110
112 TP_ARGS(dst_cgrp, task, threadgroup), 111 TP_ARGS(dst_cgrp, path, task, threadgroup),
113 112
114 TP_STRUCT__entry( 113 TP_STRUCT__entry(
115 __field( int, dst_root ) 114 __field( int, dst_root )
116 __field( int, dst_id ) 115 __field( int, dst_id )
117 __field( int, dst_level ) 116 __field( int, dst_level )
118 __dynamic_array(char, dst_path,
119 cgroup_path(dst_cgrp, NULL, 0) + 1)
120 __field( int, pid ) 117 __field( int, pid )
118 __string( dst_path, path )
121 __string( comm, task->comm ) 119 __string( comm, task->comm )
122 ), 120 ),
123 121
@@ -125,8 +123,7 @@ DECLARE_EVENT_CLASS(cgroup_migrate,
125 __entry->dst_root = dst_cgrp->root->hierarchy_id; 123 __entry->dst_root = dst_cgrp->root->hierarchy_id;
126 __entry->dst_id = dst_cgrp->id; 124 __entry->dst_id = dst_cgrp->id;
127 __entry->dst_level = dst_cgrp->level; 125 __entry->dst_level = dst_cgrp->level;
128 cgroup_path(dst_cgrp, __get_dynamic_array(dst_path), 126 __assign_str(dst_path, path);
129 __get_dynamic_array_len(dst_path));
130 __entry->pid = task->pid; 127 __entry->pid = task->pid;
131 __assign_str(comm, task->comm); 128 __assign_str(comm, task->comm);
132 ), 129 ),
@@ -138,16 +135,18 @@ DECLARE_EVENT_CLASS(cgroup_migrate,
138 135
139DEFINE_EVENT(cgroup_migrate, cgroup_attach_task, 136DEFINE_EVENT(cgroup_migrate, cgroup_attach_task,
140 137
141 TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup), 138 TP_PROTO(struct cgroup *dst_cgrp, const char *path,
139 struct task_struct *task, bool threadgroup),
142 140
143 TP_ARGS(dst_cgrp, task, threadgroup) 141 TP_ARGS(dst_cgrp, path, task, threadgroup)
144); 142);
145 143
146DEFINE_EVENT(cgroup_migrate, cgroup_transfer_tasks, 144DEFINE_EVENT(cgroup_migrate, cgroup_transfer_tasks,
147 145
148 TP_PROTO(struct cgroup *dst_cgrp, struct task_struct *task, bool threadgroup), 146 TP_PROTO(struct cgroup *dst_cgrp, const char *path,
147 struct task_struct *task, bool threadgroup),
149 148
150 TP_ARGS(dst_cgrp, task, threadgroup) 149 TP_ARGS(dst_cgrp, path, task, threadgroup)
151); 150);
152 151
153#endif /* _TRACE_CGROUP_H */ 152#endif /* _TRACE_CGROUP_H */