tracing: Fix complicated dependency of CONFIG_TRACER_MAX_TRACE
authorMasami Hiramatsu (Google) <mhiramat@kernel.org>
Tue, 6 Dec 2022 14:18:01 +0000 (23:18 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 7 Jan 2023 10:11:48 +0000 (11:11 +0100)
commit e25e43a4e5d8cb2323553d8b6a7ba08d2ebab21f upstream.

Both CONFIG_OSNOISE_TRACER and CONFIG_HWLAT_TRACER partially enables the
CONFIG_TRACER_MAX_TRACE code, but that is complicated and has
introduced a bug; It declares tracing_max_lat_fops data structure outside
of #ifdefs, but since it is defined only when CONFIG_TRACER_MAX_TRACE=y
or CONFIG_HWLAT_TRACER=y, if only CONFIG_OSNOISE_TRACER=y, that
declaration comes to a definition(!).

To fix this issue, and do not repeat the similar problem, makes
CONFIG_OSNOISE_TRACER and CONFIG_HWLAT_TRACER enables the
CONFIG_TRACER_MAX_TRACE always. It has there benefits;
- Fix the tracing_max_lat_fops bug
- Simplify the #ifdefs
- CONFIG_TRACER_MAX_TRACE code is fully enabled, or not.

Link: https://lore.kernel.org/linux-trace-kernel/167033628155.4111793.12185405690820208159.stgit@devnote3
Fixes: 424b650f35c7 ("tracing: Fix missing osnoise tracer on max_latency")
Cc: Daniel Bristot de Oliveira <bristot@kernel.org>
Cc: stable@vger.kernel.org
Reported-by: David Howells <dhowells@redhat.com>
Reported-by: kernel test robot <lkp@intel.com>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Link: https://lore.kernel.org/all/166992525941.1716618.13740663757583361463.stgit@warthog.procyon.org.uk/
Link: https://lore.kernel.org/all/202212052253.VuhZ2ulJ-lkp@intel.com/T/#u
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
kernel/trace/Kconfig
kernel/trace/trace.c
kernel/trace/trace.h

index e9e95c7..93d7249 100644 (file)
@@ -375,6 +375,7 @@ config SCHED_TRACER
 config HWLAT_TRACER
        bool "Tracer to detect hardware latencies (like SMIs)"
        select GENERIC_TRACER
 config HWLAT_TRACER
        bool "Tracer to detect hardware latencies (like SMIs)"
        select GENERIC_TRACER
+       select TRACER_MAX_TRACE
        help
         This tracer, when enabled will create one or more kernel threads,
         depending on what the cpumask file is set to, which each thread
        help
         This tracer, when enabled will create one or more kernel threads,
         depending on what the cpumask file is set to, which each thread
@@ -410,6 +411,7 @@ config HWLAT_TRACER
 config OSNOISE_TRACER
        bool "OS Noise tracer"
        select GENERIC_TRACER
 config OSNOISE_TRACER
        bool "OS Noise tracer"
        select GENERIC_TRACER
+       select TRACER_MAX_TRACE
        help
          In the context of high-performance computing (HPC), the Operating
          System Noise (osnoise) refers to the interference experienced by an
        help
          In the context of high-performance computing (HPC), the Operating
          System Noise (osnoise) refers to the interference experienced by an
index 5cfc95a..459ff8c 100644 (file)
@@ -1421,6 +1421,7 @@ int tracing_snapshot_cond_disable(struct trace_array *tr)
        return false;
 }
 EXPORT_SYMBOL_GPL(tracing_snapshot_cond_disable);
        return false;
 }
 EXPORT_SYMBOL_GPL(tracing_snapshot_cond_disable);
+#define free_snapshot(tr)      do { } while (0)
 #endif /* CONFIG_TRACER_SNAPSHOT */
 
 void tracer_tracing_off(struct trace_array *tr)
 #endif /* CONFIG_TRACER_SNAPSHOT */
 
 void tracer_tracing_off(struct trace_array *tr)
@@ -1692,6 +1693,8 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
 }
 
 unsigned long __read_mostly    tracing_thresh;
 }
 
 unsigned long __read_mostly    tracing_thresh;
+
+#ifdef CONFIG_TRACER_MAX_TRACE
 static const struct file_operations tracing_max_lat_fops;
 
 #ifdef LATENCY_FS_NOTIFY
 static const struct file_operations tracing_max_lat_fops;
 
 #ifdef LATENCY_FS_NOTIFY
@@ -1748,18 +1751,14 @@ void latency_fsnotify(struct trace_array *tr)
        irq_work_queue(&tr->fsnotify_irqwork);
 }
 
        irq_work_queue(&tr->fsnotify_irqwork);
 }
 
-#elif defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
-       || defined(CONFIG_OSNOISE_TRACER)
+#else /* !LATENCY_FS_NOTIFY */
 
 #define trace_create_maxlat_file(tr, d_tracer)                         \
        trace_create_file("tracing_max_latency", TRACE_MODE_WRITE,      \
                          d_tracer, &tr->max_latency, &tracing_max_lat_fops)
 
 
 #define trace_create_maxlat_file(tr, d_tracer)                         \
        trace_create_file("tracing_max_latency", TRACE_MODE_WRITE,      \
                          d_tracer, &tr->max_latency, &tracing_max_lat_fops)
 
-#else
-#define trace_create_maxlat_file(tr, d_tracer)  do { } while (0)
 #endif
 
 #endif
 
-#ifdef CONFIG_TRACER_MAX_TRACE
 /*
  * Copy the new maximum trace into the separate maximum-trace
  * structure. (this way the maximum trace is permanently saved,
 /*
  * Copy the new maximum trace into the separate maximum-trace
  * structure. (this way the maximum trace is permanently saved,
@@ -1834,14 +1833,15 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
                ring_buffer_record_off(tr->max_buffer.buffer);
 
 #ifdef CONFIG_TRACER_SNAPSHOT
                ring_buffer_record_off(tr->max_buffer.buffer);
 
 #ifdef CONFIG_TRACER_SNAPSHOT
-       if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data))
-               goto out_unlock;
+       if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data)) {
+               arch_spin_unlock(&tr->max_lock);
+               return;
+       }
 #endif
        swap(tr->array_buffer.buffer, tr->max_buffer.buffer);
 
        __update_max_tr(tr, tsk, cpu);
 
 #endif
        swap(tr->array_buffer.buffer, tr->max_buffer.buffer);
 
        __update_max_tr(tr, tsk, cpu);
 
- out_unlock:
        arch_spin_unlock(&tr->max_lock);
 }
 
        arch_spin_unlock(&tr->max_lock);
 }
 
@@ -1888,6 +1888,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
        __update_max_tr(tr, tsk, cpu);
        arch_spin_unlock(&tr->max_lock);
 }
        __update_max_tr(tr, tsk, cpu);
        arch_spin_unlock(&tr->max_lock);
 }
+
 #endif /* CONFIG_TRACER_MAX_TRACE */
 
 static int wait_on_pipe(struct trace_iterator *iter, int full)
 #endif /* CONFIG_TRACER_MAX_TRACE */
 
 static int wait_on_pipe(struct trace_iterator *iter, int full)
@@ -6572,7 +6573,7 @@ out:
        return ret;
 }
 
        return ret;
 }
 
-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
+#ifdef CONFIG_TRACER_MAX_TRACE
 
 static ssize_t
 tracing_max_lat_read(struct file *filp, char __user *ubuf,
 
 static ssize_t
 tracing_max_lat_read(struct file *filp, char __user *ubuf,
@@ -7587,7 +7588,7 @@ static const struct file_operations tracing_thresh_fops = {
        .llseek         = generic_file_llseek,
 };
 
        .llseek         = generic_file_llseek,
 };
 
-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
+#ifdef CONFIG_TRACER_MAX_TRACE
 static const struct file_operations tracing_max_lat_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_max_lat_read,
 static const struct file_operations tracing_max_lat_fops = {
        .open           = tracing_open_generic,
        .read           = tracing_max_lat_read,
@@ -9601,7 +9602,9 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
 
        create_trace_options_dir(tr);
 
 
        create_trace_options_dir(tr);
 
+#ifdef CONFIG_TRACER_MAX_TRACE
        trace_create_maxlat_file(tr, d_tracer);
        trace_create_maxlat_file(tr, d_tracer);
+#endif
 
        if (ftrace_create_function_files(tr, d_tracer))
                MEM_FAIL(1, "Could not allocate function filter files");
 
        if (ftrace_create_function_files(tr, d_tracer))
                MEM_FAIL(1, "Could not allocate function filter files");
index d42e245..8b69698 100644 (file)
@@ -308,8 +308,7 @@ struct trace_array {
        struct array_buffer     max_buffer;
        bool                    allocated_snapshot;
 #endif
        struct array_buffer     max_buffer;
        bool                    allocated_snapshot;
 #endif
-#if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
-       || defined(CONFIG_OSNOISE_TRACER)
+#ifdef CONFIG_TRACER_MAX_TRACE
        unsigned long           max_latency;
 #ifdef CONFIG_FSNOTIFY
        struct dentry           *d_max_latency;
        unsigned long           max_latency;
 #ifdef CONFIG_FSNOTIFY
        struct dentry           *d_max_latency;
@@ -688,12 +687,11 @@ void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
                   void *cond_data);
 void update_max_tr_single(struct trace_array *tr,
                          struct task_struct *tsk, int cpu);
                   void *cond_data);
 void update_max_tr_single(struct trace_array *tr,
                          struct task_struct *tsk, int cpu);
-#endif /* CONFIG_TRACER_MAX_TRACE */
 
 
-#if (defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER) \
-       || defined(CONFIG_OSNOISE_TRACER)) && defined(CONFIG_FSNOTIFY)
+#ifdef CONFIG_FSNOTIFY
 #define LATENCY_FS_NOTIFY
 #endif
 #define LATENCY_FS_NOTIFY
 #endif
+#endif /* CONFIG_TRACER_MAX_TRACE */
 
 #ifdef LATENCY_FS_NOTIFY
 void latency_fsnotify(struct trace_array *tr);
 
 #ifdef LATENCY_FS_NOTIFY
 void latency_fsnotify(struct trace_array *tr);