Skip to content

Commit

Permalink
ring-buffer: add tracing_off_permanent
Browse files Browse the repository at this point in the history
Impact: feature to permanently disable ring buffer

This patch adds a API to the ring buffer code that will permanently
disable the ring buffer from ever recording. This should only be
called when some serious anomaly is detected, and the system
may be in an unstable state. When that happens, shutting down the
recording to the ring buffers may be appropriate.

Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Steven Rostedt authored and Ingo Molnar committed Nov 23, 2008
1 parent a0a70c7 commit 033601a
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 13 deletions.
1 change: 1 addition & 0 deletions include/linux/ring_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ void ring_buffer_normalize_time_stamp(int cpu, u64 *ts);

void tracing_on(void);
void tracing_off(void);
void tracing_off_permanent(void);

enum ring_buffer_flags {
RB_FL_OVERWRITE = 1 << 0,
Expand Down
79 changes: 66 additions & 13 deletions kernel/trace/ring_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,46 @@

#include "trace.h"

/* Global flag to disable all recording to ring buffers */
static int ring_buffers_off __read_mostly;
/*
* A fast way to enable or disable all ring buffers is to
* call tracing_on or tracing_off. Turning off the ring buffers
* prevents all ring buffers from being recorded to.
* Turning this switch on, makes it OK to write to the
* ring buffer, if the ring buffer is enabled itself.
*
* There's three layers that must be on in order to write
* to the ring buffer.
*
* 1) This global flag must be set.
* 2) The ring buffer must be enabled for recording.
* 3) The per cpu buffer must be enabled for recording.
*
* In case of an anomaly, this global flag has a bit set that
* will permantly disable all ring buffers.
*/

/*
* Global flag to disable all recording to ring buffers
* This has two bits: ON, DISABLED
*
* ON DISABLED
* ---- ----------
* 0 0 : ring buffers are off
* 1 0 : ring buffers are on
* X 1 : ring buffers are permanently disabled
*/

enum {
RB_BUFFERS_ON_BIT = 0,
RB_BUFFERS_DISABLED_BIT = 1,
};

enum {
RB_BUFFERS_ON = 1 << RB_BUFFERS_ON_BIT,
RB_BUFFERS_DISABLED = 1 << RB_BUFFERS_DISABLED_BIT,
};

static long ring_buffer_flags __read_mostly = RB_BUFFERS_ON;

/**
* tracing_on - enable all tracing buffers
Expand All @@ -29,7 +67,7 @@ static int ring_buffers_off __read_mostly;
*/
void tracing_on(void)
{
ring_buffers_off = 0;
set_bit(RB_BUFFERS_ON_BIT, &ring_buffer_flags);
}

/**
Expand All @@ -42,7 +80,18 @@ void tracing_on(void)
*/
void tracing_off(void)
{
ring_buffers_off = 1;
clear_bit(RB_BUFFERS_ON_BIT, &ring_buffer_flags);
}

/**
* tracing_off_permanent - permanently disable ring buffers
*
* This function, once called, will disable all ring buffers
* permanenty.
*/
void tracing_off_permanent(void)
{
set_bit(RB_BUFFERS_DISABLED_BIT, &ring_buffer_flags);
}

#include "trace.h"
Expand Down Expand Up @@ -1185,7 +1234,7 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer,
struct ring_buffer_event *event;
int cpu, resched;

if (ring_buffers_off)
if (ring_buffer_flags != RB_BUFFERS_ON)
return NULL;

if (atomic_read(&buffer->record_disabled))
Expand Down Expand Up @@ -1297,7 +1346,7 @@ int ring_buffer_write(struct ring_buffer *buffer,
int ret = -EBUSY;
int cpu, resched;

if (ring_buffers_off)
if (ring_buffer_flags != RB_BUFFERS_ON)
return -EBUSY;

if (atomic_read(&buffer->record_disabled))
Expand Down Expand Up @@ -2178,12 +2227,14 @@ static ssize_t
rb_simple_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
int *p = filp->private_data;
long *p = filp->private_data;
char buf[64];
int r;

/* !ring_buffers_off == tracing_on */
r = sprintf(buf, "%d\n", !*p);
if (test_bit(RB_BUFFERS_DISABLED_BIT, p))
r = sprintf(buf, "permanently disabled\n");
else
r = sprintf(buf, "%d\n", test_bit(RB_BUFFERS_ON_BIT, p));

return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
}
Expand All @@ -2192,7 +2243,7 @@ static ssize_t
rb_simple_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
int *p = filp->private_data;
long *p = filp->private_data;
char buf[64];
long val;
int ret;
Expand All @@ -2209,8 +2260,10 @@ rb_simple_write(struct file *filp, const char __user *ubuf,
if (ret < 0)
return ret;

/* !ring_buffers_off == tracing_on */
*p = !val;
if (val)
set_bit(RB_BUFFERS_ON_BIT, p);
else
clear_bit(RB_BUFFERS_ON_BIT, p);

(*ppos)++;

Expand All @@ -2232,7 +2285,7 @@ static __init int rb_init_debugfs(void)
d_tracer = tracing_init_dentry();

entry = debugfs_create_file("tracing_on", 0644, d_tracer,
&ring_buffers_off, &rb_simple_fops);
&ring_buffer_flags, &rb_simple_fops);
if (!entry)
pr_warning("Could not create debugfs 'tracing_on' entry\n");

Expand Down

0 comments on commit 033601a

Please sign in to comment.