Re: [PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-08-21 Thread Steven Rostedt
On Tue, 2012-08-21 at 19:10 -0700, Anton Vorontsov wrote:

> Running without any recursion protection is prone to weird
> lockups/reboots, and probably a good idea to have it on a production
> system. But recursion during tracing is still an evidence of some other
> bugs, right? At least the fact that I didn't have it helped me to find a
> bug. So, does it make sense to make the recursion protection optionally
> disabled? Maybe as some CONFIG_DEBUG_* option (briefly looking into
> kernel/trace/Kconfig I didn't find any)?

The problem is that recursion bugs are usually due to calling something
that might be traced. Really, I've hit so many recursion bugs, that
having the protection is probably the best thing. I wouldn't turn it
off.

The worse that recursion can do (with proper protection) is that it
causes a little wasted effort during the trace (it wastes cycles tracing
something again and then recognizing that it is doing it due to
recursion).

Therefore, the 'notrace' annotations are mostly for speed up (don't
trace this while tracing, because the tracer uses it too).

-- Steve


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-08-21 Thread Anton Vorontsov
On Tue, Aug 21, 2012 at 09:07:19PM -0400, Steven Rostedt wrote: [...]
> I'm fine with it. I know there was some issues about recursion
> protection and I said that the function tracer now has its own
> protection where you don't need to worry about it. I was hoping that
> code would make it into 3.6, but Linus opened the merge window the day
> after I posted the final version. Which I figured was too close to the
> merge window to push for 3.6 (lots of changes occurred, and I wanted
> it vetted in linux-next for a bit).
> 
> Now those changes are queued for 3.7 and are currently in the tip
> tree.  You can supply your own temporary recursion protection to the
> function tracer callback, or wait till my changes make it into Linus's
> tree.

Great! Btw, the particular recursion issue that I faced back then was
triggered by a missing 'notrace' specifier for the ->write() callback in
pstore code, i.e. a bug in pstore.

Running without any recursion protection is prone to weird
lockups/reboots, and probably a good idea to have it on a production
system. But recursion during tracing is still an evidence of some other
bugs, right? At least the fact that I didn't have it helped me to find a
bug. So, does it make sense to make the recursion protection optionally
disabled? Maybe as some CONFIG_DEBUG_* option (briefly looking into
kernel/trace/Kconfig I didn't find any)?

Thanks,

Anton.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-08-21 Thread Steven Rostedt
On Mon, 2012-08-20 at 18:46 -0700, Anton Vorontsov wrote:
> On Wed, Jul 18, 2012 at 12:30:52PM -0700, Anton Vorontsov wrote:
> > With this patch we no longer reuse function tracer infrastructure, now
> > we register our own tracer back-end via a debugfs knob.
> > 
> > It's a bit more code, but that is the only downside. On the bright side we
> > have:
> > 
> > - Ability to make persistent_ram module removable (when needed, we can
> >   move ftrace_ops struct into a module). Note that persistent_ram is still
> >   not removable for other reasons, but with this patch it's just one
> >   thing less to worry about;
> > 
> > - Pstore part is more isolated from the generic function tracer. We tried
> >   it already by registering our own tracer in available_tracers, but that
> >   way we're loosing ability to see the traces while we record them to
> >   pstore. This solution is somewhere in the middle: we only register
> >   "internal ftracer" back-end, but not the "front-end";
> > 
> > - When there is only pstore tracing enabled, the kernel will only write
> >   to the pstore buffer, omitting function tracer buffer (which, of course,
> >   still can be enabled via 'echo function > current_tracer').
> > 
> > Suggested-by: Steven Rostedt 
> > Signed-off-by: Anton Vorontsov 
> > ---
> 
> Hi Steven,
> 
> Unless there are any issues, may I take the patch via linux-pstore.git
> tree?

I'm fine with it. I know there was some issues about recursion
protection and I said that the function tracer now has its own
protection where you don't need to worry about it. I was hoping that
code would make it into 3.6, but Linus opened the merge window the day
after I posted the final version. Which I figured was too close to the
merge window to push for 3.6 (lots of changes occurred, and I wanted it
vetted in linux-next for a bit).

Now those changes are queued for 3.7 and are currently in the tip tree.
You can supply your own temporary recursion protection to the function
tracer callback, or wait till my changes make it into Linus's tree.

Specifically, see commit 4740974a6844156c14d741b0080b59d275679a23 (in
tip.git).

-- Steve


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-08-21 Thread Steven Rostedt
On Mon, 2012-08-20 at 18:46 -0700, Anton Vorontsov wrote:
 On Wed, Jul 18, 2012 at 12:30:52PM -0700, Anton Vorontsov wrote:
  With this patch we no longer reuse function tracer infrastructure, now
  we register our own tracer back-end via a debugfs knob.
  
  It's a bit more code, but that is the only downside. On the bright side we
  have:
  
  - Ability to make persistent_ram module removable (when needed, we can
move ftrace_ops struct into a module). Note that persistent_ram is still
not removable for other reasons, but with this patch it's just one
thing less to worry about;
  
  - Pstore part is more isolated from the generic function tracer. We tried
it already by registering our own tracer in available_tracers, but that
way we're loosing ability to see the traces while we record them to
pstore. This solution is somewhere in the middle: we only register
internal ftracer back-end, but not the front-end;
  
  - When there is only pstore tracing enabled, the kernel will only write
to the pstore buffer, omitting function tracer buffer (which, of course,
still can be enabled via 'echo function  current_tracer').
  
  Suggested-by: Steven Rostedt rost...@goodmis.org
  Signed-off-by: Anton Vorontsov anton.voront...@linaro.org
  ---
 
 Hi Steven,
 
 Unless there are any issues, may I take the patch via linux-pstore.git
 tree?

I'm fine with it. I know there was some issues about recursion
protection and I said that the function tracer now has its own
protection where you don't need to worry about it. I was hoping that
code would make it into 3.6, but Linus opened the merge window the day
after I posted the final version. Which I figured was too close to the
merge window to push for 3.6 (lots of changes occurred, and I wanted it
vetted in linux-next for a bit).

Now those changes are queued for 3.7 and are currently in the tip tree.
You can supply your own temporary recursion protection to the function
tracer callback, or wait till my changes make it into Linus's tree.

Specifically, see commit 4740974a6844156c14d741b0080b59d275679a23 (in
tip.git).

-- Steve


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-08-21 Thread Anton Vorontsov
On Tue, Aug 21, 2012 at 09:07:19PM -0400, Steven Rostedt wrote: [...]
 I'm fine with it. I know there was some issues about recursion
 protection and I said that the function tracer now has its own
 protection where you don't need to worry about it. I was hoping that
 code would make it into 3.6, but Linus opened the merge window the day
 after I posted the final version. Which I figured was too close to the
 merge window to push for 3.6 (lots of changes occurred, and I wanted
 it vetted in linux-next for a bit).
 
 Now those changes are queued for 3.7 and are currently in the tip
 tree.  You can supply your own temporary recursion protection to the
 function tracer callback, or wait till my changes make it into Linus's
 tree.

Great! Btw, the particular recursion issue that I faced back then was
triggered by a missing 'notrace' specifier for the -write() callback in
pstore code, i.e. a bug in pstore.

Running without any recursion protection is prone to weird
lockups/reboots, and probably a good idea to have it on a production
system. But recursion during tracing is still an evidence of some other
bugs, right? At least the fact that I didn't have it helped me to find a
bug. So, does it make sense to make the recursion protection optionally
disabled? Maybe as some CONFIG_DEBUG_* option (briefly looking into
kernel/trace/Kconfig I didn't find any)?

Thanks,

Anton.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-08-21 Thread Steven Rostedt
On Tue, 2012-08-21 at 19:10 -0700, Anton Vorontsov wrote:

 Running without any recursion protection is prone to weird
 lockups/reboots, and probably a good idea to have it on a production
 system. But recursion during tracing is still an evidence of some other
 bugs, right? At least the fact that I didn't have it helped me to find a
 bug. So, does it make sense to make the recursion protection optionally
 disabled? Maybe as some CONFIG_DEBUG_* option (briefly looking into
 kernel/trace/Kconfig I didn't find any)?

The problem is that recursion bugs are usually due to calling something
that might be traced. Really, I've hit so many recursion bugs, that
having the protection is probably the best thing. I wouldn't turn it
off.

The worse that recursion can do (with proper protection) is that it
causes a little wasted effort during the trace (it wastes cycles tracing
something again and then recognizing that it is doing it due to
recursion).

Therefore, the 'notrace' annotations are mostly for speed up (don't
trace this while tracing, because the tracer uses it too).

-- Steve


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-08-20 Thread Anton Vorontsov
On Wed, Jul 18, 2012 at 12:30:52PM -0700, Anton Vorontsov wrote:
> With this patch we no longer reuse function tracer infrastructure, now
> we register our own tracer back-end via a debugfs knob.
> 
> It's a bit more code, but that is the only downside. On the bright side we
> have:
> 
> - Ability to make persistent_ram module removable (when needed, we can
>   move ftrace_ops struct into a module). Note that persistent_ram is still
>   not removable for other reasons, but with this patch it's just one
>   thing less to worry about;
> 
> - Pstore part is more isolated from the generic function tracer. We tried
>   it already by registering our own tracer in available_tracers, but that
>   way we're loosing ability to see the traces while we record them to
>   pstore. This solution is somewhere in the middle: we only register
>   "internal ftracer" back-end, but not the "front-end";
> 
> - When there is only pstore tracing enabled, the kernel will only write
>   to the pstore buffer, omitting function tracer buffer (which, of course,
>   still can be enabled via 'echo function > current_tracer').
> 
> Suggested-by: Steven Rostedt 
> Signed-off-by: Anton Vorontsov 
> ---

Hi Steven,

Unless there are any issues, may I take the patch via linux-pstore.git
tree?

Thanks!

>  Documentation/ramoops.txt  |4 +-
>  fs/pstore/Kconfig  |1 +
>  fs/pstore/ftrace.c |   96 
> +++-
>  fs/pstore/internal.h   |6 +++
>  fs/pstore/platform.c   |1 +
>  include/linux/pstore.h |8 
>  kernel/trace/trace_functions.c |   15 +--
>  7 files changed, 105 insertions(+), 26 deletions(-)
> 
> diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt
> index 197ad59..69b3cac 100644
> --- a/Documentation/ramoops.txt
> +++ b/Documentation/ramoops.txt
> @@ -102,9 +102,7 @@ related hangs. The functions call chain log is stored in 
> a "ftrace-ramoops"
>  file. Here is an example of usage:
>  
>   # mount -t debugfs debugfs /sys/kernel/debug/
> - # cd /sys/kernel/debug/tracing
> - # echo function > current_tracer
> - # echo 1 > options/func_pstore
> + # echo 1 > /sys/kernel/debug/pstore/record_ftrace
>   # reboot -f
>   [...]
>   # mount -t pstore pstore /mnt/
> diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
> index d39bb5c..ca71db6 100644
> --- a/fs/pstore/Kconfig
> +++ b/fs/pstore/Kconfig
> @@ -23,6 +23,7 @@ config PSTORE_FTRACE
>   bool "Persistent function tracer"
>   depends on PSTORE
>   depends on FUNCTION_TRACER
> + depends on DEBUG_FS
>   help
> With this option kernel traces function calls into a persistent
> ram buffer that can be decoded and dumped after reboot through
> diff --git a/fs/pstore/ftrace.c b/fs/pstore/ftrace.c
> index a130d48..2d57e1a 100644
> --- a/fs/pstore/ftrace.c
> +++ b/fs/pstore/ftrace.c
> @@ -17,19 +17,113 @@
>  #include 
>  #include 
>  #include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
>  #include 
>  #include "internal.h"
>  
> -void notrace pstore_ftrace_call(unsigned long ip, unsigned long parent_ip)
> +static void notrace pstore_ftrace_call(unsigned long ip,
> +unsigned long parent_ip)
>  {
> + unsigned long flags;
>   struct pstore_ftrace_record rec = {};
>  
>   if (unlikely(oops_in_progress))
>   return;
>  
> + local_irq_save(flags);
> +
>   rec.ip = ip;
>   rec.parent_ip = parent_ip;
>   pstore_ftrace_encode_cpu(, raw_smp_processor_id());
>   psinfo->write_buf(PSTORE_TYPE_FTRACE, 0, NULL, 0, (void *),
> sizeof(rec), psinfo);
> +
> + local_irq_restore(flags);
> +}
> +
> +static struct ftrace_ops pstore_ftrace_ops __read_mostly = {
> + .func   = pstore_ftrace_call,
> +};
> +
> +static DEFINE_MUTEX(pstore_ftrace_lock);
> +static bool pstore_ftrace_enabled;
> +
> +static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user 
> *buf,
> + size_t count, loff_t *ppos)
> +{
> + u8 on;
> + ssize_t ret;
> +
> + ret = kstrtou8_from_user(buf, count, 2, );
> + if (ret)
> + return ret;
> +
> + mutex_lock(_ftrace_lock);
> +
> + if (!on ^ pstore_ftrace_enabled)
> + goto out;
> +
> + if (on)
> + ret = register_ftrace_function(_ftrace_ops);
> + else
> + ret = unregister_ftrace_function(_ftrace_ops);
> + if (ret) {
> + pr_err("%s: unable to %sregister ftrace ops: %zd\n",
> +__func__, on ? "" : "un", ret);
> + goto err;
> + }
> +
> + pstore_ftrace_enabled = on;
> +out:
> + ret = count;
> +err:
> + mutex_unlock(_ftrace_lock);
> +
> + return ret;
> +}
> +
> +static ssize_t pstore_ftrace_knob_read(struct file *f, char __user *buf,
> +size_t count, loff_t *ppos)
> +{
> + 

Re: [PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-08-20 Thread Anton Vorontsov
On Wed, Jul 18, 2012 at 12:30:52PM -0700, Anton Vorontsov wrote:
 With this patch we no longer reuse function tracer infrastructure, now
 we register our own tracer back-end via a debugfs knob.
 
 It's a bit more code, but that is the only downside. On the bright side we
 have:
 
 - Ability to make persistent_ram module removable (when needed, we can
   move ftrace_ops struct into a module). Note that persistent_ram is still
   not removable for other reasons, but with this patch it's just one
   thing less to worry about;
 
 - Pstore part is more isolated from the generic function tracer. We tried
   it already by registering our own tracer in available_tracers, but that
   way we're loosing ability to see the traces while we record them to
   pstore. This solution is somewhere in the middle: we only register
   internal ftracer back-end, but not the front-end;
 
 - When there is only pstore tracing enabled, the kernel will only write
   to the pstore buffer, omitting function tracer buffer (which, of course,
   still can be enabled via 'echo function  current_tracer').
 
 Suggested-by: Steven Rostedt rost...@goodmis.org
 Signed-off-by: Anton Vorontsov anton.voront...@linaro.org
 ---

Hi Steven,

Unless there are any issues, may I take the patch via linux-pstore.git
tree?

Thanks!

  Documentation/ramoops.txt  |4 +-
  fs/pstore/Kconfig  |1 +
  fs/pstore/ftrace.c |   96 
 +++-
  fs/pstore/internal.h   |6 +++
  fs/pstore/platform.c   |1 +
  include/linux/pstore.h |8 
  kernel/trace/trace_functions.c |   15 +--
  7 files changed, 105 insertions(+), 26 deletions(-)
 
 diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt
 index 197ad59..69b3cac 100644
 --- a/Documentation/ramoops.txt
 +++ b/Documentation/ramoops.txt
 @@ -102,9 +102,7 @@ related hangs. The functions call chain log is stored in 
 a ftrace-ramoops
  file. Here is an example of usage:
  
   # mount -t debugfs debugfs /sys/kernel/debug/
 - # cd /sys/kernel/debug/tracing
 - # echo function  current_tracer
 - # echo 1  options/func_pstore
 + # echo 1  /sys/kernel/debug/pstore/record_ftrace
   # reboot -f
   [...]
   # mount -t pstore pstore /mnt/
 diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
 index d39bb5c..ca71db6 100644
 --- a/fs/pstore/Kconfig
 +++ b/fs/pstore/Kconfig
 @@ -23,6 +23,7 @@ config PSTORE_FTRACE
   bool Persistent function tracer
   depends on PSTORE
   depends on FUNCTION_TRACER
 + depends on DEBUG_FS
   help
 With this option kernel traces function calls into a persistent
 ram buffer that can be decoded and dumped after reboot through
 diff --git a/fs/pstore/ftrace.c b/fs/pstore/ftrace.c
 index a130d48..2d57e1a 100644
 --- a/fs/pstore/ftrace.c
 +++ b/fs/pstore/ftrace.c
 @@ -17,19 +17,113 @@
  #include linux/percpu.h
  #include linux/smp.h
  #include linux/atomic.h
 +#include linux/types.h
 +#include linux/mutex.h
 +#include linux/ftrace.h
 +#include linux/fs.h
 +#include linux/debugfs.h
 +#include linux/err.h
 +#include linux/cache.h
  #include asm/barrier.h
  #include internal.h
  
 -void notrace pstore_ftrace_call(unsigned long ip, unsigned long parent_ip)
 +static void notrace pstore_ftrace_call(unsigned long ip,
 +unsigned long parent_ip)
  {
 + unsigned long flags;
   struct pstore_ftrace_record rec = {};
  
   if (unlikely(oops_in_progress))
   return;
  
 + local_irq_save(flags);
 +
   rec.ip = ip;
   rec.parent_ip = parent_ip;
   pstore_ftrace_encode_cpu(rec, raw_smp_processor_id());
   psinfo-write_buf(PSTORE_TYPE_FTRACE, 0, NULL, 0, (void *)rec,
 sizeof(rec), psinfo);
 +
 + local_irq_restore(flags);
 +}
 +
 +static struct ftrace_ops pstore_ftrace_ops __read_mostly = {
 + .func   = pstore_ftrace_call,
 +};
 +
 +static DEFINE_MUTEX(pstore_ftrace_lock);
 +static bool pstore_ftrace_enabled;
 +
 +static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user 
 *buf,
 + size_t count, loff_t *ppos)
 +{
 + u8 on;
 + ssize_t ret;
 +
 + ret = kstrtou8_from_user(buf, count, 2, on);
 + if (ret)
 + return ret;
 +
 + mutex_lock(pstore_ftrace_lock);
 +
 + if (!on ^ pstore_ftrace_enabled)
 + goto out;
 +
 + if (on)
 + ret = register_ftrace_function(pstore_ftrace_ops);
 + else
 + ret = unregister_ftrace_function(pstore_ftrace_ops);
 + if (ret) {
 + pr_err(%s: unable to %sregister ftrace ops: %zd\n,
 +__func__, on ?  : un, ret);
 + goto err;
 + }
 +
 + pstore_ftrace_enabled = on;
 +out:
 + ret = count;
 +err:
 + mutex_unlock(pstore_ftrace_lock);
 +
 + return ret;
 +}
 +
 +static ssize_t pstore_ftrace_knob_read(struct file *f, char __user *buf,
 +  

[PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-07-18 Thread Anton Vorontsov
With this patch we no longer reuse function tracer infrastructure, now
we register our own tracer back-end via a debugfs knob.

It's a bit more code, but that is the only downside. On the bright side we
have:

- Ability to make persistent_ram module removable (when needed, we can
  move ftrace_ops struct into a module). Note that persistent_ram is still
  not removable for other reasons, but with this patch it's just one
  thing less to worry about;

- Pstore part is more isolated from the generic function tracer. We tried
  it already by registering our own tracer in available_tracers, but that
  way we're loosing ability to see the traces while we record them to
  pstore. This solution is somewhere in the middle: we only register
  "internal ftracer" back-end, but not the "front-end";

- When there is only pstore tracing enabled, the kernel will only write
  to the pstore buffer, omitting function tracer buffer (which, of course,
  still can be enabled via 'echo function > current_tracer').

Suggested-by: Steven Rostedt 
Signed-off-by: Anton Vorontsov 
---

On Wed, Jul 18, 2012 at 11:59:21AM -0700, Stephen Boyd wrote:
[...]
> > So, I think it is fine to check for IS_ERR_OR_NULL(), although today
> > it's always NULL for our case, true.
> 
> What does PTR_ERR(NULL) mean then? It will always print "unable to
> create pstore/ftrace file: 0"?

Well, that might be not pretty, yeah. OK, since debugfs is mandatory
anyway, let's check for !NULL then, it's also less lines of code. :-)

Thanks a lot for the review, Stephen!

 Documentation/ramoops.txt  |4 +-
 fs/pstore/Kconfig  |1 +
 fs/pstore/ftrace.c |   96 +++-
 fs/pstore/internal.h   |6 +++
 fs/pstore/platform.c   |1 +
 include/linux/pstore.h |8 
 kernel/trace/trace_functions.c |   15 +--
 7 files changed, 105 insertions(+), 26 deletions(-)

diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt
index 197ad59..69b3cac 100644
--- a/Documentation/ramoops.txt
+++ b/Documentation/ramoops.txt
@@ -102,9 +102,7 @@ related hangs. The functions call chain log is stored in a 
"ftrace-ramoops"
 file. Here is an example of usage:
 
  # mount -t debugfs debugfs /sys/kernel/debug/
- # cd /sys/kernel/debug/tracing
- # echo function > current_tracer
- # echo 1 > options/func_pstore
+ # echo 1 > /sys/kernel/debug/pstore/record_ftrace
  # reboot -f
  [...]
  # mount -t pstore pstore /mnt/
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index d39bb5c..ca71db6 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -23,6 +23,7 @@ config PSTORE_FTRACE
bool "Persistent function tracer"
depends on PSTORE
depends on FUNCTION_TRACER
+   depends on DEBUG_FS
help
  With this option kernel traces function calls into a persistent
  ram buffer that can be decoded and dumped after reboot through
diff --git a/fs/pstore/ftrace.c b/fs/pstore/ftrace.c
index a130d48..2d57e1a 100644
--- a/fs/pstore/ftrace.c
+++ b/fs/pstore/ftrace.c
@@ -17,19 +17,113 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include "internal.h"
 
-void notrace pstore_ftrace_call(unsigned long ip, unsigned long parent_ip)
+static void notrace pstore_ftrace_call(unsigned long ip,
+  unsigned long parent_ip)
 {
+   unsigned long flags;
struct pstore_ftrace_record rec = {};
 
if (unlikely(oops_in_progress))
return;
 
+   local_irq_save(flags);
+
rec.ip = ip;
rec.parent_ip = parent_ip;
pstore_ftrace_encode_cpu(, raw_smp_processor_id());
psinfo->write_buf(PSTORE_TYPE_FTRACE, 0, NULL, 0, (void *),
  sizeof(rec), psinfo);
+
+   local_irq_restore(flags);
+}
+
+static struct ftrace_ops pstore_ftrace_ops __read_mostly = {
+   .func   = pstore_ftrace_call,
+};
+
+static DEFINE_MUTEX(pstore_ftrace_lock);
+static bool pstore_ftrace_enabled;
+
+static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user *buf,
+   size_t count, loff_t *ppos)
+{
+   u8 on;
+   ssize_t ret;
+
+   ret = kstrtou8_from_user(buf, count, 2, );
+   if (ret)
+   return ret;
+
+   mutex_lock(_ftrace_lock);
+
+   if (!on ^ pstore_ftrace_enabled)
+   goto out;
+
+   if (on)
+   ret = register_ftrace_function(_ftrace_ops);
+   else
+   ret = unregister_ftrace_function(_ftrace_ops);
+   if (ret) {
+   pr_err("%s: unable to %sregister ftrace ops: %zd\n",
+  __func__, on ? "" : "un", ret);
+   goto err;
+   }
+
+   pstore_ftrace_enabled = on;
+out:
+   ret = count;
+err:
+   mutex_unlock(_ftrace_lock);
+
+   return ret;
+}
+
+static ssize_t pstore_ftrace_knob_read(struct file *f, 

[PATCH v3] pstore/ftrace: Convert to its own enable/disable debugfs knob

2012-07-18 Thread Anton Vorontsov
With this patch we no longer reuse function tracer infrastructure, now
we register our own tracer back-end via a debugfs knob.

It's a bit more code, but that is the only downside. On the bright side we
have:

- Ability to make persistent_ram module removable (when needed, we can
  move ftrace_ops struct into a module). Note that persistent_ram is still
  not removable for other reasons, but with this patch it's just one
  thing less to worry about;

- Pstore part is more isolated from the generic function tracer. We tried
  it already by registering our own tracer in available_tracers, but that
  way we're loosing ability to see the traces while we record them to
  pstore. This solution is somewhere in the middle: we only register
  internal ftracer back-end, but not the front-end;

- When there is only pstore tracing enabled, the kernel will only write
  to the pstore buffer, omitting function tracer buffer (which, of course,
  still can be enabled via 'echo function  current_tracer').

Suggested-by: Steven Rostedt rost...@goodmis.org
Signed-off-by: Anton Vorontsov anton.voront...@linaro.org
---

On Wed, Jul 18, 2012 at 11:59:21AM -0700, Stephen Boyd wrote:
[...]
  So, I think it is fine to check for IS_ERR_OR_NULL(), although today
  it's always NULL for our case, true.
 
 What does PTR_ERR(NULL) mean then? It will always print unable to
 create pstore/ftrace file: 0?

Well, that might be not pretty, yeah. OK, since debugfs is mandatory
anyway, let's check for !NULL then, it's also less lines of code. :-)

Thanks a lot for the review, Stephen!

 Documentation/ramoops.txt  |4 +-
 fs/pstore/Kconfig  |1 +
 fs/pstore/ftrace.c |   96 +++-
 fs/pstore/internal.h   |6 +++
 fs/pstore/platform.c   |1 +
 include/linux/pstore.h |8 
 kernel/trace/trace_functions.c |   15 +--
 7 files changed, 105 insertions(+), 26 deletions(-)

diff --git a/Documentation/ramoops.txt b/Documentation/ramoops.txt
index 197ad59..69b3cac 100644
--- a/Documentation/ramoops.txt
+++ b/Documentation/ramoops.txt
@@ -102,9 +102,7 @@ related hangs. The functions call chain log is stored in a 
ftrace-ramoops
 file. Here is an example of usage:
 
  # mount -t debugfs debugfs /sys/kernel/debug/
- # cd /sys/kernel/debug/tracing
- # echo function  current_tracer
- # echo 1  options/func_pstore
+ # echo 1  /sys/kernel/debug/pstore/record_ftrace
  # reboot -f
  [...]
  # mount -t pstore pstore /mnt/
diff --git a/fs/pstore/Kconfig b/fs/pstore/Kconfig
index d39bb5c..ca71db6 100644
--- a/fs/pstore/Kconfig
+++ b/fs/pstore/Kconfig
@@ -23,6 +23,7 @@ config PSTORE_FTRACE
bool Persistent function tracer
depends on PSTORE
depends on FUNCTION_TRACER
+   depends on DEBUG_FS
help
  With this option kernel traces function calls into a persistent
  ram buffer that can be decoded and dumped after reboot through
diff --git a/fs/pstore/ftrace.c b/fs/pstore/ftrace.c
index a130d48..2d57e1a 100644
--- a/fs/pstore/ftrace.c
+++ b/fs/pstore/ftrace.c
@@ -17,19 +17,113 @@
 #include linux/percpu.h
 #include linux/smp.h
 #include linux/atomic.h
+#include linux/types.h
+#include linux/mutex.h
+#include linux/ftrace.h
+#include linux/fs.h
+#include linux/debugfs.h
+#include linux/err.h
+#include linux/cache.h
 #include asm/barrier.h
 #include internal.h
 
-void notrace pstore_ftrace_call(unsigned long ip, unsigned long parent_ip)
+static void notrace pstore_ftrace_call(unsigned long ip,
+  unsigned long parent_ip)
 {
+   unsigned long flags;
struct pstore_ftrace_record rec = {};
 
if (unlikely(oops_in_progress))
return;
 
+   local_irq_save(flags);
+
rec.ip = ip;
rec.parent_ip = parent_ip;
pstore_ftrace_encode_cpu(rec, raw_smp_processor_id());
psinfo-write_buf(PSTORE_TYPE_FTRACE, 0, NULL, 0, (void *)rec,
  sizeof(rec), psinfo);
+
+   local_irq_restore(flags);
+}
+
+static struct ftrace_ops pstore_ftrace_ops __read_mostly = {
+   .func   = pstore_ftrace_call,
+};
+
+static DEFINE_MUTEX(pstore_ftrace_lock);
+static bool pstore_ftrace_enabled;
+
+static ssize_t pstore_ftrace_knob_write(struct file *f, const char __user *buf,
+   size_t count, loff_t *ppos)
+{
+   u8 on;
+   ssize_t ret;
+
+   ret = kstrtou8_from_user(buf, count, 2, on);
+   if (ret)
+   return ret;
+
+   mutex_lock(pstore_ftrace_lock);
+
+   if (!on ^ pstore_ftrace_enabled)
+   goto out;
+
+   if (on)
+   ret = register_ftrace_function(pstore_ftrace_ops);
+   else
+   ret = unregister_ftrace_function(pstore_ftrace_ops);
+   if (ret) {
+   pr_err(%s: unable to %sregister ftrace ops: %zd\n,
+  __func__, on ?  : un, ret);
+   goto err;
+   }
+
+