From: Frederic Weisbecker <fweisbec@gmail.com>
To: Steven Rostedt <rostedt@goodmis.org>
Cc: linux-kernel@vger.kernel.org, Ingo Molnar <mingo@elte.hu>,
Andrew Morton <akpm@linux-foundation.org>,
Peter Zijlstra <peterz@infradead.org>,
Wu Fengguang <fengguang.wu@intel.com>,
Pierre Ossman <drzeus@drzeus.cx>, Pekka Paalanen <pq@iki.fi>,
Steven Rostedt <srostedt@redhat.com>
Subject: Re: [PATCH 1/4] tracing: keep ring buffer to minimum size till used
Date: Thu, 12 Mar 2009 16:01:01 +0100 [thread overview]
Message-ID: <20090312150100.GB5270@nowhere> (raw)
In-Reply-To: <20090312023936.000182747@goodmis.org>
On Wed, Mar 11, 2009 at 10:37:21PM -0400, Steven Rostedt wrote:
> From: Steven Rostedt <srostedt@redhat.com>
>
> Impact: less memory impact on systems not using tracer
>
> When the kernel boots up that has tracing configured, it allocates
> the default size of the ring buffer. This currently happens to be
> 1.4Megs per possible CPU. This is quite a bit of wasted memory if
> the system is never using the tracer.
>
> The current solution is to keep the ring buffers to a minimum size
> until the user uses them. Once a tracer is piped into the current_tracer
> the ring buffer will be expanded to the default size. If the user
> changes the size of the ring buffer, it will take the size given
> by the user immediately.
>
> If the user adds a "ftrace=" to the kernel command line, then the ring
> buffers will be set to the default size on initialization.
>
> Signed-off-by: Steven Rostedt <srostedt@redhat.com>
> ---
> kernel/trace/trace.c | 79 +++++++++++++++++++++++++++++++++++++------------
> 1 files changed, 59 insertions(+), 20 deletions(-)
>
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index 4c97947..0c1dc18 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -45,6 +45,12 @@ unsigned long __read_mostly tracing_max_latency;
> unsigned long __read_mostly tracing_thresh;
>
> /*
> + * On boot up, the ring buffer is set to the minimum size, so that
> + * we do not waste memory on systems that are not using tracing.
> + */
> +static int ring_buffer_expanded;
> +
> +/*
> * We need to change this state when a selftest is running.
> * A selftest will lurk into the ring-buffer to count the
> * entries inserted during the selftest although some concurrent
> @@ -128,6 +134,8 @@ static int __init set_ftrace(char *str)
> {
> strncpy(bootup_tracer_buf, str, BOOTUP_TRACER_SIZE);
> default_bootup_tracer = bootup_tracer_buf;
> + /* We are using ftrace early, expand it */
> + ring_buffer_expanded = 1;
> return 1;
> }
> __setup("ftrace=", set_ftrace);
> @@ -2315,6 +2323,40 @@ int tracer_init(struct tracer *t, struct trace_array *tr)
> return t->init(tr);
> }
>
> +static int tracing_resize_ring_buffer(unsigned long size)
> +{
> + int ret;
> +
> + /*
> + * If kernel or user changes the size of the ring buffer
> + * it get completed.
> + */
Indeed :-)
I just wonder about one thing.
Sometimes I use trace_printk to trace some events that come on bootup.
The only solution I see that could avoid me this minimum size would be
to use ftrace=nop that I sometimes use to avoid ftrace selftests.
I guess that few developers will be aware of this trick so may be
it could be worth it to explain it on the ftrace documentation and
on kernel.h (though a simple ftrace_printk as a parameter would be
more obvious, or ftrace=printk).
Anyway this patch is a very good thing, especially on embeeded systems.
Frederic.
> + ring_buffer_expanded = 1;
> +
> + ret = ring_buffer_resize(global_trace.buffer, size);
> + if (ret < 0)
> + return ret;
> +
> + ret = ring_buffer_resize(max_tr.buffer, size);
> + if (ret < 0) {
> + int r;
> +
> + r = ring_buffer_resize(global_trace.buffer,
> + global_trace.entries);
> + if (r < 0) {
> + /* AARGH! We are left with different
> + * size max buffer!!!! */
> + WARN_ON(1);
> + tracing_disabled = 1;
> + }
> + return ret;
> + }
> +
> + global_trace.entries = size;
> +
> + return ret;
> +}
> +
> struct trace_option_dentry;
>
> static struct trace_option_dentry *
> @@ -2330,6 +2372,13 @@ static int tracing_set_tracer(const char *buf)
> struct tracer *t;
> int ret = 0;
>
> + if (!ring_buffer_expanded) {
> + ret = tracing_resize_ring_buffer(trace_buf_size);
> + if (ret < 0)
> + return ret;
> + ret = 0;
> + }
> +
> mutex_lock(&trace_types_lock);
> for (t = trace_types; t; t = t->next) {
> if (strcmp(t->name, buf) == 0)
> @@ -2903,28 +2952,11 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
> val <<= 10;
>
> if (val != global_trace.entries) {
> - ret = ring_buffer_resize(global_trace.buffer, val);
> + ret = tracing_resize_ring_buffer(val);
> if (ret < 0) {
> cnt = ret;
> goto out;
> }
> -
> - ret = ring_buffer_resize(max_tr.buffer, val);
> - if (ret < 0) {
> - int r;
> - cnt = ret;
> - r = ring_buffer_resize(global_trace.buffer,
> - global_trace.entries);
> - if (r < 0) {
> - /* AARGH! We are left with different
> - * size max buffer!!!! */
> - WARN_ON(1);
> - tracing_disabled = 1;
> - }
> - goto out;
> - }
> -
> - global_trace.entries = val;
> }
>
> filp->f_pos += cnt;
> @@ -3916,6 +3948,7 @@ void ftrace_dump(void)
> __init static int tracer_alloc_buffers(void)
> {
> struct trace_array_cpu *data;
> + int ring_buf_size;
> int i;
> int ret = -ENOMEM;
>
> @@ -3928,12 +3961,18 @@ __init static int tracer_alloc_buffers(void)
> if (!alloc_cpumask_var(&tracing_reader_cpumask, GFP_KERNEL))
> goto out_free_tracing_cpumask;
>
> + /* To save memory, keep the ring buffer size to its minimum */
> + if (ring_buffer_expanded)
> + ring_buf_size = trace_buf_size;
> + else
> + ring_buf_size = 1;
> +
> cpumask_copy(tracing_buffer_mask, cpu_possible_mask);
> cpumask_copy(tracing_cpumask, cpu_all_mask);
> cpumask_clear(tracing_reader_cpumask);
>
> /* TODO: make the number of buffers hot pluggable with CPUS */
> - global_trace.buffer = ring_buffer_alloc(trace_buf_size,
> + global_trace.buffer = ring_buffer_alloc(ring_buf_size,
> TRACE_BUFFER_FLAGS);
> if (!global_trace.buffer) {
> printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
> @@ -3944,7 +3983,7 @@ __init static int tracer_alloc_buffers(void)
>
>
> #ifdef CONFIG_TRACER_MAX_TRACE
> - max_tr.buffer = ring_buffer_alloc(trace_buf_size,
> + max_tr.buffer = ring_buffer_alloc(ring_buf_size,
> TRACE_BUFFER_FLAGS);
> if (!max_tr.buffer) {
> printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n");
> --
> 1.6.1.3
>
> --
next prev parent reply other threads:[~2009-03-12 15:01 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-12 2:37 [PATCH 0/4] [GIT PULL] memory saving ring buffer for tip/tracing/ftrace Steven Rostedt
2009-03-12 2:37 ` [PATCH 1/4] tracing: keep ring buffer to minimum size till used Steven Rostedt
2009-03-12 3:26 ` Andrew Morton
2009-03-12 13:25 ` Steven Rostedt
2009-03-12 15:01 ` Frederic Weisbecker [this message]
2009-03-12 15:14 ` Steven Rostedt
2009-03-12 2:37 ` [PATCH 2/4] tracing: expand the ring buffers when an event is activated Steven Rostedt
2009-03-12 2:37 ` [PATCH 3/4] tracing: fix trace_wait to know to wait on all cpus or just one Steven Rostedt
2009-03-12 2:37 ` [PATCH 4/4] ring-buffer: only allocate buffers for online cpus Steven Rostedt
2009-03-12 3:32 ` Andrew Morton
2009-03-12 13:29 ` Steven Rostedt
2009-03-12 7:31 ` KOSAKI Motohiro
2009-03-12 13:38 ` Steven Rostedt
2009-03-12 23:47 ` KOSAKI Motohiro
2009-03-12 7:07 ` [PATCH 0/4] [GIT PULL] memory saving ring buffer for tip/tracing/ftrace Pierre Ossman
2009-03-12 7:34 ` KOSAKI Motohiro
2009-03-12 9:20 ` Pierre Ossman
2009-03-12 13:39 ` Steven Rostedt
2009-03-12 10:47 ` Neil Horman
2009-03-12 12:12 ` Pierre Ossman
2009-03-12 13:12 ` Neil Horman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090312150100.GB5270@nowhere \
--to=fweisbec@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=drzeus@drzeus.cx \
--cc=fengguang.wu@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=peterz@infradead.org \
--cc=pq@iki.fi \
--cc=rostedt@goodmis.org \
--cc=srostedt@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.