[PATCH] tracing: report buffer memory in /proc/meminfo

Xiang Gao <[email protected]>
Newsgroups gmane.linux.file-systems,gmane.linux.kernel.mm,gmane.linux.kernel
Message-ID <[email protected]>
Report the data capacity of all ftrace ring buffers through a new Ftrace
field in /proc/meminfo. Include the main and snapshot buffers of the
global trace array and all tracing instances, while leaving ring-buffer
metadata accounted for by Slab.

Keep the interface as a no-op when tracing is disabled so /proc/meminfo
does not gain a configuration dependency on tracing.

Tested on arm64 QEMU:

  CONFIG_TRACING=n:                   0 kB
  Global resize/restore:          7 -> 4099 -> 7 kB
  Instance and snapshot lifecycle: 15 -> 1434 -> 2836 -> 1434 -> 15 kB

Signed-off-by: Xiang Gao <[email protected]>
---
 fs/proc/meminfo.c     |  3 +++
 include/linux/trace.h |  5 +++++
 kernel/trace/trace.c  | 30 ++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+)

diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index b2813ff13cb2..96a38ffc4e35 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -18,6 +18,7 @@
 #include <linux/cma.h>
 #endif
 #include <linux/zswap.h>
+#include <linux/trace.h>
 #include <asm/page.h>
 #include "internal.h"
 
@@ -108,6 +109,8 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
 	show_val_kb(m, "Slab:           ", sreclaimable + sunreclaim);
 	show_val_kb(m, "SReclaimable:   ", sreclaimable);
 	show_val_kb(m, "SUnreclaim:     ", sunreclaim);
+	seq_printf(m, "Ftrace:         %8lu kB\n",
+		   ftrace_buffer_total_size() >> 10);
 	seq_printf(m, "KernelStack:    %8lu kB\n",
 		   global_node_page_state(NR_KERNEL_STACK_KB));
 #ifdef CONFIG_SHADOW_CALL_STACK
diff --git a/include/linux/trace.h b/include/linux/trace.h
index 7eaad857dee0..f9935231560c 100644
--- a/include/linux/trace.h
+++ b/include/linux/trace.h
@@ -53,6 +53,7 @@ int trace_array_init_printk(struct trace_array *tr);
 void trace_array_put(struct trace_array *tr);
 struct trace_array *trace_array_get_by_name(const char *name, const char *systems);
 int trace_array_destroy(struct trace_array *tr);
+unsigned long ftrace_buffer_total_size(void);
 
 /* For osnoise tracer */
 int osnoise_arch_register(void);
@@ -92,6 +93,10 @@ static inline int trace_array_destroy(struct trace_array *tr)
 {
 	return 0;
 }
+static inline unsigned long ftrace_buffer_total_size(void)
+{
+	return 0;
+}
 #endif	/* CONFIG_TRACING */
 
 #endif	/* _LINUX_TRACE_H */
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 01a5e87af299..f0bb553e3688 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -5769,6 +5769,36 @@ tracing_total_entries_read(struct file *filp, char __user *ubuf,
 	return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
 }
 
+static unsigned long trace_array_buffer_size(struct array_buffer *buf)
+{
+	unsigned long size = 0;
+	int cpu;
+
+	if (!buf->buffer)
+		return 0;
+
+	for_each_tracing_cpu(cpu)
+		size += ring_buffer_size(buf->buffer, cpu);
+
+	return size;
+}
+
+unsigned long ftrace_buffer_total_size(void)
+{
+	struct trace_array *tr;
+	unsigned long size = 0;
+
+	guard(mutex)(&trace_types_lock);
+	list_for_each_entry(tr, &ftrace_trace_arrays, list) {
+		size += trace_array_buffer_size(&tr->array_buffer);
+#ifdef CONFIG_TRACER_SNAPSHOT
+		size += trace_array_buffer_size(&tr->snapshot_buffer);
+#endif
+	}
+
+	return size;
+}
+
 #define LAST_BOOT_HEADER ((void *)1)
 
 static void *l_next(struct seq_file *m, void *v, loff_t *pos)
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.