aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace.c')
-rw-r--r--kernel/trace/trace.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index d22f8d34b18d..66c1683fa1dd 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -10087,6 +10087,32 @@ static void trace_module_remove_evals(struct module *mod)
static inline void trace_module_remove_evals(struct module *mod) { }
#endif /* CONFIG_TRACE_EVAL_MAP_FILE */
+static bool trace_array_active(struct trace_array *tr)
+{
+ if (tr->current_trace != &nop_trace)
+ return true;
+
+ /* 0 is no events, 1 is all disabled */
+ return trace_events_enabled(tr, NULL) > 1;
+}
+
+static void trace_module_record(struct module *mod)
+{
+ struct trace_array *tr;
+
+ list_for_each_entry(tr, &ftrace_trace_arrays, list) {
+ /* Update any persistent trace array that has already been started */
+ if ((tr->flags & (TRACE_ARRAY_FL_BOOT | TRACE_ARRAY_FL_LAST_BOOT)) ==
+ TRACE_ARRAY_FL_BOOT) {
+ /* Only update if the trace array is active */
+ if (trace_array_active(tr)) {
+ guard(mutex)(&scratch_mutex);
+ save_mod(mod, tr);
+ }
+ }
+ }
+}
+
static int trace_module_notify(struct notifier_block *self,
unsigned long val, void *data)
{
@@ -10095,6 +10121,7 @@ static int trace_module_notify(struct notifier_block *self,
switch (val) {
case MODULE_STATE_COMING:
trace_module_add_evals(mod);
+ trace_module_record(mod);
break;
case MODULE_STATE_GOING:
trace_module_remove_evals(mod);