#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
  */
 void tracing_on(void)
 {
-       ring_buffers_off = 0;
+       set_bit(RB_BUFFERS_ON_BIT, &ring_buffer_flags);
 }
 
 /**
  */
 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"
        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))
        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))
 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);
 }
 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;
        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)++;
 
        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");