Merge branches 'tracing/ftrace', 'tracing/syscalls' and 'linus' into tracing/core
authorIngo Molnar <mingo@elte.hu>
Mon, 16 Mar 2009 08:12:42 +0000 (09:12 +0100)
committerIngo Molnar <mingo@elte.hu>
Mon, 16 Mar 2009 08:12:42 +0000 (09:12 +0100)
Conflicts:
arch/parisc/kernel/irq.c

1  2  3 
MAINTAINERS
arch/parisc/kernel/irq.c
include/linux/ftrace.h
kernel/trace/trace.h
mm/vmscan.c

diff --combined MAINTAINERS
@@@@ -2621,12 -2621,12 -2621,6 +2621,12 @@@@ M: jason.wessel@windriver.co
   L:   kgdb-bugreport@lists.sourceforge.net
   S:   Maintained
   
  +KMEMTRACE
  +P:   Eduard - Gabriel Munteanu
  +M:   eduard.munteanu@linux360.ro
  +L:   linux-kernel@vger.kernel.org
  +S:   Maintained
  +
   KPROBES
   P:   Ananth N Mavinakayanahalli
   M:   ananth@in.ibm.com
@@@@ -3356,10 -3356,10 -3350,8 +3356,8 @@@@ S:  Maintaine
   PARISC ARCHITECTURE
   P:   Kyle McMartin
   M:   kyle@mcmartin.ca
-- P:   Matthew Wilcox
-- M:   matthew@wil.cx
-- P:   Grant Grundler
-- M:   grundler@parisc-linux.org
++ P:   Helge Deller
++ M:   deller@gmx.de
   L:   linux-parisc@vger.kernel.org
   W:   http://www.parisc-linux.org/
   T:   git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
diff --combined arch/parisc/kernel/irq.c
@@@@ -112,7 -112,7 -112,7 +112,7 @@@@ void cpu_end_irq(unsigned int irq
   }
   
   #ifdef CONFIG_SMP
-- int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
++ int cpu_check_affinity(unsigned int irq, const struct cpumask *dest)
   {
        int cpu_dest;
   
        if (CHECK_IRQ_PER_CPU(irq)) {
                /* Bad linux design decision.  The mask has already
                 * been set; we must reset it */
--              cpumask_setall(irq_desc[irq].affinity);
++              cpumask_setall(&irq_desc[irq].affinity);
                return -EINVAL;
        }
   
        /* whatever mask they set, we just allow one CPU */
        cpu_dest = first_cpu(*dest);
--      *dest = cpumask_of_cpu(cpu_dest);
   
--      return 0;
++      return cpu_dest;
   }
   
   static void cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
   {
--      if (cpu_check_affinity(irq, dest))
++      int cpu_dest;
++ 
++      cpu_dest = cpu_check_affinity(irq, dest);
++      if (cpu_dest < 0)
                return;
   
--      cpumask_copy(irq_desc[irq].affinity, dest);
  -     cpumask_copy(&irq_desc[irq].affinity, &cpumask_of_cpu(cpu_dest));
+++     cpumask_copy(&irq_desc[irq].affinity, dest);
   }
   #endif
   
@@@@ -295,7 -295,7 -297,7 +297,7 @@@@ int txn_alloc_irq(unsigned int bits_wid
   unsigned long txn_affinity_addr(unsigned int irq, int cpu)
   {
   #ifdef CONFIG_SMP
--      cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
++      cpumask_copy(&irq_desc[irq].affinity, cpumask_of(cpu));
   #endif
   
        return per_cpu(cpu_data, cpu).txn_addr;
@@@@ -352,7 -352,7 -354,7 +354,7 @@@@ void do_cpu_irq_mask(struct pt_regs *re
        irq = eirr_to_irq(eirr_val);
   
   #ifdef CONFIG_SMP
--      cpumask_copy(&dest, irq_desc[irq].affinity);
++      cpumask_copy(&dest, &irq_desc[irq].affinity);
        if (CHECK_IRQ_PER_CPU(irq_desc[irq].status) &&
            !cpu_isset(smp_processor_id(), dest)) {
                int cpu = first_cpu(dest);
diff --combined include/linux/ftrace.h
   #ifndef _LINUX_FTRACE_H
   #define _LINUX_FTRACE_H
   
  -#include <linux/linkage.h>
  -#include <linux/fs.h>
  -#include <linux/ktime.h>
  -#include <linux/init.h>
  -#include <linux/types.h>
  -#include <linux/module.h>
  +#include <linux/trace_clock.h>
   #include <linux/kallsyms.h>
  +#include <linux/linkage.h>
   #include <linux/bitops.h>
  +#include <linux/module.h>
  +#include <linux/ktime.h>
   #include <linux/sched.h>
  +#include <linux/types.h>
  +#include <linux/init.h>
  +#include <linux/fs.h>
  +
  +#include <asm/ftrace.h>
   
   #ifdef CONFIG_FUNCTION_TRACER
   
@@@@ -98,41 -98,41 -95,9 +98,41 @@@@ stack_trace_sysctl(struct ctl_table *ta
                   loff_t *ppos);
   #endif
   
  +struct ftrace_func_command {
  +     struct list_head        list;
  +     char                    *name;
  +     int                     (*func)(char *func, char *cmd,
  +                                     char *params, int enable);
  +};
  +
   #ifdef CONFIG_DYNAMIC_FTRACE
  -/* asm/ftrace.h must be defined for archs supporting dynamic ftrace */
  -#include <asm/ftrace.h>
  +
  +int ftrace_arch_code_modify_prepare(void);
  +int ftrace_arch_code_modify_post_process(void);
  +
  +struct seq_file;
  +
  +struct ftrace_probe_ops {
  +     void                    (*func)(unsigned long ip,
  +                                     unsigned long parent_ip,
  +                                     void **data);
  +     int                     (*callback)(unsigned long ip, void **data);
  +     void                    (*free)(void **data);
  +     int                     (*print)(struct seq_file *m,
  +                                      unsigned long ip,
  +                                      struct ftrace_probe_ops *ops,
  +                                      void *data);
  +};
  +
  +extern int
  +register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
  +                           void *data);
  +extern void
  +unregister_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
  +                             void *data);
  +extern void
  +unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops);
  +extern void unregister_ftrace_function_probe_all(char *glob);
   
   enum {
        FTRACE_FL_FREE          = (1 << 0),
   };
   
   struct dyn_ftrace {
 --     struct list_head        list;
        unsigned long           ip; /* address of mcount call-site */
        unsigned long           flags;
        struct dyn_arch_ftrace  arch;
   int ftrace_force_update(void);
   void ftrace_set_filter(unsigned char *buf, int len, int reset);
   
  +int register_ftrace_command(struct ftrace_func_command *cmd);
  +int unregister_ftrace_command(struct ftrace_func_command *cmd);
  +
   /* defined in arch */
   extern int ftrace_ip_converted(unsigned long ip);
   extern int ftrace_dyn_arch_init(void *data);
@@@@ -163,10 -164,10 -126,6 +163,10 @@@@ extern int ftrace_update_ftrace_func(ft
   extern void ftrace_caller(void);
   extern void ftrace_call(void);
   extern void mcount_call(void);
  +
  +#ifndef FTRACE_ADDR
  +#define FTRACE_ADDR ((unsigned long)ftrace_caller)
  +#endif
   #ifdef CONFIG_FUNCTION_GRAPH_TRACER
   extern void ftrace_graph_caller(void);
   extern int ftrace_enable_ftrace_graph_caller(void);
@@@@ -177,7 -178,7 -136,7 +177,7 @@@@ static inline int ftrace_disable_ftrace
   #endif
   
   /**
  - * ftrace_make_nop - convert code into top
  + * ftrace_make_nop - convert code into nop
    * @mod: module structure if called by module load initialization
    * @rec: the mcount call site record
    * @addr: the address that the call site should be calling
@@@@ -222,6 -223,6 -181,7 +222,6 @@@@ extern int ftrace_make_nop(struct modul
    */
   extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
   
  -
   /* May be defined in arch */
   extern int ftrace_arch_read_dyn_info(char *buf, int size);
   
@@@@ -238,14 -239,14 -198,6 +238,14 @@@@ extern void ftrace_enable_daemon(void)
   # define ftrace_disable_daemon()             do { } while (0)
   # define ftrace_enable_daemon()                      do { } while (0)
   static inline void ftrace_release(void *start, unsigned long size) { }
  +static inline int register_ftrace_command(struct ftrace_func_command *cmd)
  +{
  +     return -EINVAL;
  +}
  +static inline int unregister_ftrace_command(char *cmd_name)
  +{
  +     return -EINVAL;
  +}
   #endif /* CONFIG_DYNAMIC_FTRACE */
   
   /* totally disable ftrace - can not re-enable after this */
@@@@ -281,25 -282,25 -233,24 +281,25 @@@@ static inline void __ftrace_enabled_res
   #endif
   }
   
  -#ifdef CONFIG_FRAME_POINTER
  -/* TODO: need to fix this for ARM */
  -# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  -# define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
  -# define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
  -# define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
  -# define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
  -# define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
  -# define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
  -#else
  -# define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  -# define CALLER_ADDR1 0UL
  -# define CALLER_ADDR2 0UL
  -# define CALLER_ADDR3 0UL
  -# define CALLER_ADDR4 0UL
  -# define CALLER_ADDR5 0UL
  -# define CALLER_ADDR6 0UL
  -#endif
  +#ifndef HAVE_ARCH_CALLER_ADDR
  +# ifdef CONFIG_FRAME_POINTER
  +#  define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  +#  define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
  +#  define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
  +#  define CALLER_ADDR3 ((unsigned long)__builtin_return_address(3))
  +#  define CALLER_ADDR4 ((unsigned long)__builtin_return_address(4))
  +#  define CALLER_ADDR5 ((unsigned long)__builtin_return_address(5))
  +#  define CALLER_ADDR6 ((unsigned long)__builtin_return_address(6))
  +# else
  +#  define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
  +#  define CALLER_ADDR1 0UL
  +#  define CALLER_ADDR2 0UL
  +#  define CALLER_ADDR3 0UL
  +#  define CALLER_ADDR4 0UL
  +#  define CALLER_ADDR5 0UL
  +#  define CALLER_ADDR6 0UL
  +# endif
  +#endif /* ifndef HAVE_ARCH_CALLER_ADDR */
   
   #ifdef CONFIG_IRQSOFF_TRACER
     extern void time_hardirqs_on(unsigned long a0, unsigned long a1);
   # define trace_preempt_off(a0, a1)           do { } while (0)
   #endif
   
  -#ifdef CONFIG_TRACING
  -extern int ftrace_dump_on_oops;
  -
  -extern void tracing_start(void);
  -extern void tracing_stop(void);
  -extern void ftrace_off_permanent(void);
  -
  -extern void
  -ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
  -
  -/**
  - * ftrace_printk - printf formatting in the ftrace buffer
  - * @fmt: the printf format for printing
  - *
  - * Note: __ftrace_printk is an internal function for ftrace_printk and
  - *       the @ip is passed in via the ftrace_printk macro.
  - *
  - * This function allows a kernel developer to debug fast path sections
  - * that printk is not appropriate for. By scattering in various
  - * printk like tracing in the code, a developer can quickly see
  - * where problems are occurring.
  - *
  - * This is intended as a debugging tool for the developer only.
  - * Please refrain from leaving ftrace_printks scattered around in
  - * your code.
  - */
  -# define ftrace_printk(fmt...) __ftrace_printk(_THIS_IP_, fmt)
  -extern int
  -__ftrace_printk(unsigned long ip, const char *fmt, ...)
  -     __attribute__ ((format (printf, 2, 3)));
  -extern void ftrace_dump(void);
  -#else
  -static inline void
  -ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
  -static inline int
  -ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
  -
  -static inline void tracing_start(void) { }
  -static inline void tracing_stop(void) { }
  -static inline void ftrace_off_permanent(void) { }
  -static inline int
  -ftrace_printk(const char *fmt, ...)
  -{
  -     return 0;
  -}
  -static inline void ftrace_dump(void) { }
  -#endif
  -
   #ifdef CONFIG_FTRACE_MCOUNT_RECORD
   extern void ftrace_init(void);
   extern void ftrace_init_module(struct module *mod,
@@@@ -328,6 -329,6 -327,36 +328,6 @@@@ ftrace_init_module(struct module *mod
                   unsigned long *start, unsigned long *end) { }
   #endif
   
  -enum {
  -     POWER_NONE = 0,
  -     POWER_CSTATE = 1,
  -     POWER_PSTATE = 2,
  -};
  -
  -struct power_trace {
  -#ifdef CONFIG_POWER_TRACER
  -     ktime_t                 stamp;
  -     ktime_t                 end;
  -     int                     type;
  -     int                     state;
  -#endif
  -};
  -
  -#ifdef CONFIG_POWER_TRACER
  -extern void trace_power_start(struct power_trace *it, unsigned int type,
  -                                     unsigned int state);
  -extern void trace_power_mark(struct power_trace *it, unsigned int type,
  -                                     unsigned int state);
  -extern void trace_power_end(struct power_trace *it);
  -#else
  -static inline void trace_power_start(struct power_trace *it, unsigned int type,
  -                                     unsigned int state) { }
  -static inline void trace_power_mark(struct power_trace *it, unsigned int type,
  -                                     unsigned int state) { }
  -static inline void trace_power_end(struct power_trace *it) { }
  -#endif
  -
  -
   /*
    * Structure that defines an entry function trace.
    */
@@@@ -351,30 -352,30 -380,6 +351,30 @@@@ struct ftrace_graph_ret 
   #ifdef CONFIG_FUNCTION_GRAPH_TRACER
   
   /*
  + * Stack of return addresses for functions
  + * of a thread.
  + * Used in struct thread_info
  + */
  +struct ftrace_ret_stack {
  +     unsigned long ret;
  +     unsigned long func;
  +     unsigned long long calltime;
  +};
  +
  +/*
  + * Primary handler of a function return.
  + * It relays on ftrace_return_to_handler.
  + * Defined in entry_32/64.S
  + */
  +extern void return_to_handler(void);
  +
  +extern int
  +ftrace_push_return_trace(unsigned long ret, unsigned long long time,
  +                      unsigned long func, int *depth);
  +extern void
  +ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret);
  +
  +/*
    * Sometimes we don't want to trace a function with the function
    * graph tracer but we want them to keep traced by the usual function
    * tracer if the function graph tracer is not configured.
@@@@ -485,42 -486,50 -490,6 +485,50 @@@@ static inline int test_tsk_trace_graph(
        return tsk->trace & TSK_TRACE_FL_GRAPH;
   }
   
  +extern int ftrace_dump_on_oops;
  +
   #endif /* CONFIG_TRACING */
   
-   * @syscall_nr: syscall number
  +
  +#ifdef CONFIG_HW_BRANCH_TRACER
  +
  +void trace_hw_branch(u64 from, u64 to);
  +void trace_hw_branch_oops(void);
  +
  +#else /* CONFIG_HW_BRANCH_TRACER */
  +
  +static inline void trace_hw_branch(u64 from, u64 to) {}
  +static inline void trace_hw_branch_oops(void) {}
  +
  +#endif /* CONFIG_HW_BRANCH_TRACER */
  +
  +/*
  + * A syscall entry in the ftrace syscalls array.
  + *
-  struct syscall_trace_entry {
-       int             syscall_nr;
+ + * @name: name of the syscall
+ + * @nb_args: number of parameters it takes
+ + * @types: list of types as strings
+ + * @args: list of args as strings (args[i] matches types[i])
  + */
+ +struct syscall_metadata {
+ +     const char      *name;
+ +     int             nb_args;
+ +     const char      **types;
+ +     const char      **args;
  +};
  +
  +#ifdef CONFIG_FTRACE_SYSCALLS
+ +extern void arch_init_ftrace_syscalls(void);
+ +extern struct syscall_metadata *syscall_nr_to_meta(int nr);
  +extern void start_ftrace_syscalls(void);
  +extern void stop_ftrace_syscalls(void);
  +extern void ftrace_syscall_enter(struct pt_regs *regs);
  +extern void ftrace_syscall_exit(struct pt_regs *regs);
  +#else
  +static inline void start_ftrace_syscalls(void) { }
  +static inline void stop_ftrace_syscalls(void) { }
  +static inline void ftrace_syscall_enter(struct pt_regs *regs) { }
  +static inline void ftrace_syscall_exit(struct pt_regs *regs) { }
  +#endif
  +
   #endif /* _LINUX_FTRACE_H */
diff --combined kernel/trace/trace.h
@@@@ -9,8 -9,8 -9,6 +9,8 @@@@
   #include <linux/mmiotrace.h>
   #include <linux/ftrace.h>
   #include <trace/boot.h>
  +#include <trace/kmemtrace.h>
  +#include <trace/power.h>
   
   enum trace_type {
        __TRACE_FIRST_TYPE = 0,
        TRACE_FN,
        TRACE_CTX,
        TRACE_WAKE,
  -     TRACE_CONT,
        TRACE_STACK,
        TRACE_PRINT,
 ++     TRACE_BPRINT,
        TRACE_SPECIAL,
        TRACE_MMIO_RW,
        TRACE_MMIO_MAP,
        TRACE_GRAPH_ENT,
        TRACE_USER_STACK,
        TRACE_HW_BRANCHES,
  +     TRACE_SYSCALL_ENTER,
  +     TRACE_SYSCALL_EXIT,
  +     TRACE_KMEM_ALLOC,
  +     TRACE_KMEM_FREE,
        TRACE_POWER,
  +     TRACE_BLK,
   
  -     __TRACE_LAST_TYPE
  +     __TRACE_LAST_TYPE,
   };
   
   /*
    */
   struct trace_entry {
        unsigned char           type;
  -     unsigned char           cpu;
        unsigned char           flags;
        unsigned char           preempt_count;
        int                     pid;
@@@@ -66,13 -65,13 -60,13 +66,13 @@@@ struct ftrace_entry 
   
   /* Function call entry */
   struct ftrace_graph_ent_entry {
  -     struct trace_entry                      ent;
  +     struct trace_entry              ent;
        struct ftrace_graph_ent         graph_ent;
   };
   
   /* Function return entry */
   struct ftrace_graph_ret_entry {
  -     struct trace_entry                      ent;
  +     struct trace_entry              ent;
        struct ftrace_graph_ret         ret;
   };
   extern struct tracer boot_tracer;
@@@@ -118,23 -117,16 -112,15 +118,23 @@@@ struct userstack_entry 
   };
   
   /*
  - * ftrace_printk entry:
  + * trace_printk entry:
    */
 - struct print_entry {
 ++struct bprint_entry {
  +     struct trace_entry      ent;
  +     unsigned long           ip;
  +     int                     depth;
  +     const char              *fmt;
  +     u32                     buf[];
  +};
  +
 + struct print_entry {
 +      struct trace_entry      ent;
 +      unsigned long           ip;
 +      int                     depth;
 +      char                    buf[];
 + };
 + 
   #define TRACE_OLD_SIZE               88
   
   struct trace_field_cont {
@@@@ -184,32 -176,45 -170,15 +184,45 @@@@ struct trace_power 
        struct power_trace      state_data;
   };
   
  +struct kmemtrace_alloc_entry {
  +     struct trace_entry      ent;
  +     enum kmemtrace_type_id type_id;
  +     unsigned long call_site;
  +     const void *ptr;
  +     size_t bytes_req;
  +     size_t bytes_alloc;
  +     gfp_t gfp_flags;
  +     int node;
  +};
  +
  +struct kmemtrace_free_entry {
  +     struct trace_entry      ent;
  +     enum kmemtrace_type_id type_id;
  +     unsigned long call_site;
  +     const void *ptr;
  +};
  +
+ +struct syscall_trace_enter {
+ +     struct trace_entry      ent;
+ +     int                     nr;
+ +     unsigned long           args[];
+ +};
+ +
+ +struct syscall_trace_exit {
+ +     struct trace_entry      ent;
+ +     int                     nr;
+ +     unsigned long           ret;
+ +};
+ +
+ +
   /*
    * trace_flag_type is an enumeration that holds different
    * states when a trace occurs. These are:
    *  IRQS_OFF         - interrupts were disabled
  - *  IRQS_NOSUPPORT   - arch does not support irqs_disabled_flags
  + *  IRQS_NOSUPPORT   - arch does not support irqs_disabled_flags
    *  NEED_RESCED              - reschedule is requested
    *  HARDIRQ          - inside an interrupt handler
    *  SOFTIRQ          - inside a softirq handler
  - *  CONT             - multiple entries hold the trace item
    */
   enum trace_flag_type {
        TRACE_FLAG_IRQS_OFF             = 0x01,
        TRACE_FLAG_NEED_RESCHED         = 0x04,
        TRACE_FLAG_HARDIRQ              = 0x08,
        TRACE_FLAG_SOFTIRQ              = 0x10,
  -     TRACE_FLAG_CONT                 = 0x20,
   };
   
   #define TRACE_BUF_SIZE               1024
    */
   struct trace_array_cpu {
        atomic_t                disabled;
  +     void                    *buffer_page;   /* ring buffer spare */
   
        /* these fields get copied into max-trace: */
        unsigned long           trace_idx;
@@@@ -293,10 -298,9 -262,10 +306,10 @@@@ extern void __ftrace_bad_type(void)
        do {                                                            \
                IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN);     \
                IF_ASSIGN(var, ent, struct ctx_switch_entry, 0);        \
  -             IF_ASSIGN(var, ent, struct trace_field_cont, TRACE_CONT); \
                IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK);   \
                IF_ASSIGN(var, ent, struct userstack_entry, TRACE_USER_STACK);\
                IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT);   \
 ++             IF_ASSIGN(var, ent, struct bprint_entry, TRACE_BPRINT); \
                IF_ASSIGN(var, ent, struct special_entry, 0);           \
                IF_ASSIGN(var, ent, struct trace_mmiotrace_rw,          \
                          TRACE_MMIO_RW);                               \
                IF_ASSIGN(var, ent, struct ftrace_graph_ret_entry,      \
                          TRACE_GRAPH_RET);             \
                IF_ASSIGN(var, ent, struct hw_branch_entry, TRACE_HW_BRANCHES);\
  -             IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \
  +             IF_ASSIGN(var, ent, struct trace_power, TRACE_POWER); \
  +             IF_ASSIGN(var, ent, struct kmemtrace_alloc_entry,       \
  +                       TRACE_KMEM_ALLOC);    \
  +             IF_ASSIGN(var, ent, struct kmemtrace_free_entry,        \
  +                       TRACE_KMEM_FREE);     \
+ +             IF_ASSIGN(var, ent, struct syscall_trace_enter,         \
+ +                       TRACE_SYSCALL_ENTER);                         \
+ +             IF_ASSIGN(var, ent, struct syscall_trace_exit,          \
+ +                       TRACE_SYSCALL_EXIT);                          \
                __ftrace_bad_type();                                    \
        } while (0)
   
   enum print_line_t {
        TRACE_TYPE_PARTIAL_LINE = 0,    /* Retry after flushing the seq */
        TRACE_TYPE_HANDLED      = 1,
  -     TRACE_TYPE_UNHANDLED    = 2     /* Relay to other output functions */
  +     TRACE_TYPE_UNHANDLED    = 2,    /* Relay to other output functions */
  +     TRACE_TYPE_NO_CONSUME   = 3     /* Handled but ask to not consume */
   };
   
   
    * flags value in struct tracer_flags.
    */
   struct tracer_opt {
  -     const char      *name; /* Will appear on the trace_options file */
  -     u32             bit; /* Mask assigned in val field in tracer_flags */
  +     const char      *name; /* Will appear on the trace_options file */
  +     u32             bit; /* Mask assigned in val field in tracer_flags */
   };
   
   /*
    */
   struct tracer_flags {
        u32                     val;
  -     struct tracer_opt       *opts;
  +     struct tracer_opt       *opts;
   };
   
   /* Makes more easy to define a tracer opt */
   #define TRACER_OPT(s, b)     .name = #s, .bit = b
   
  -/*
  - * A specific tracer, represented by methods that operate on a trace array:
  +
  +/**
  + * struct tracer - a specific tracer and its callbacks to interact with debugfs
  + * @name: the name chosen to select it on the available_tracers file
  + * @init: called when one switches to this tracer (echo name > current_tracer)
  + * @reset: called when one switches to another tracer
  + * @start: called when tracing is unpaused (echo 1 > tracing_enabled)
  + * @stop: called when tracing is paused (echo 0 > tracing_enabled)
  + * @open: called when the trace file is opened
  + * @pipe_open: called when the trace_pipe file is opened
  + * @wait_pipe: override how the user waits for traces on trace_pipe
  + * @close: called when the trace file is released
  + * @read: override the default read callback on trace_pipe
  + * @splice_read: override the default splice_read callback on trace_pipe
  + * @selftest: selftest to run on boot (see trace_selftest.c)
  + * @print_headers: override the first lines that describe your columns
  + * @print_line: callback that prints a trace
  + * @set_flag: signals one of your private flags changed (trace_options file)
  + * @flags: your private flags
    */
   struct tracer {
        const char              *name;
  -     /* Your tracer should raise a warning if init fails */
        int                     (*init)(struct trace_array *tr);
        void                    (*reset)(struct trace_array *tr);
        void                    (*start)(struct trace_array *tr);
        void                    (*stop)(struct trace_array *tr);
        void                    (*open)(struct trace_iterator *iter);
        void                    (*pipe_open)(struct trace_iterator *iter);
  +     void                    (*wait_pipe)(struct trace_iterator *iter);
        void                    (*close)(struct trace_iterator *iter);
        ssize_t                 (*read)(struct trace_iterator *iter,
                                        struct file *filp, char __user *ubuf,
                                        size_t cnt, loff_t *ppos);
  +     ssize_t                 (*splice_read)(struct trace_iterator *iter,
  +                                            struct file *filp,
  +                                            loff_t *ppos,
  +                                            struct pipe_inode_info *pipe,
  +                                            size_t len,
  +                                            unsigned int flags);
   #ifdef CONFIG_FTRACE_STARTUP_TEST
        int                     (*selftest)(struct tracer *trace,
                                            struct trace_array *tr);
        int                     (*set_flag)(u32 old_flags, u32 bit, int set);
        struct tracer           *next;
        int                     print_max;
  -     struct tracer_flags     *flags;
  +     struct tracer_flags     *flags;
  +     struct tracer_stat      *stats;
   };
   
   struct trace_seq {
        unsigned int            readpos;
   };
   
  +static inline void
  +trace_seq_init(struct trace_seq *s)
  +{
  +     s->len = 0;
  +     s->readpos = 0;
  +}
  +
  +
  +#define TRACE_PIPE_ALL_CPU   -1
  +
   /*
    * Trace iterator - used by printout routines who present trace
    * results to users and which routines might sleep, etc:
@@@@ -426,8 -434,8 -356,6 +443,8 @@@@ struct trace_iterator 
        struct trace_array      *tr;
        struct tracer           *trace;
        void                    *private;
  +     int                     cpu_file;
  +     struct mutex            mutex;
        struct ring_buffer_iter *buffer_iter[NR_CPUS];
   
        /* The below is zeroed out in pipe_read */
        cpumask_var_t           started;
   };
   
  +int tracer_init(struct tracer *t, struct trace_array *tr);
   int tracing_is_enabled(void);
   void trace_wake_up(void);
   void tracing_reset(struct trace_array *tr, int cpu);
@@@@ -452,48 -460,48 -379,26 +469,48 @@@@ int tracing_open_generic(struct inode *
   struct dentry *tracing_init_dentry(void);
   void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
   
  +struct ring_buffer_event;
  +
  +struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
  +                                                 unsigned char type,
  +                                                 unsigned long len,
  +                                                 unsigned long flags,
  +                                                 int pc);
  +void trace_buffer_unlock_commit(struct trace_array *tr,
  +                             struct ring_buffer_event *event,
  +                             unsigned long flags, int pc);
  +
  +struct ring_buffer_event *
  +trace_current_buffer_lock_reserve(unsigned char type, unsigned long len,
  +                               unsigned long flags, int pc);
  +void trace_current_buffer_unlock_commit(struct ring_buffer_event *event,
  +                                     unsigned long flags, int pc);
  +
   struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
                                                struct trace_array_cpu *data);
  +
  +struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
  +                                       int *ent_cpu, u64 *ent_ts);
  +
   void tracing_generic_entry_update(struct trace_entry *entry,
                                  unsigned long flags,
                                  int pc);
   
  +void default_wait_pipe(struct trace_iterator *iter);
  +void poll_wait_pipe(struct trace_iterator *iter);
  +
   void ftrace(struct trace_array *tr,
                            struct trace_array_cpu *data,
                            unsigned long ip,
                            unsigned long parent_ip,
                            unsigned long flags, int pc);
   void tracing_sched_switch_trace(struct trace_array *tr,
  -                             struct trace_array_cpu *data,
                                struct task_struct *prev,
                                struct task_struct *next,
                                unsigned long flags, int pc);
   void tracing_record_cmdline(struct task_struct *tsk);
   
   void tracing_sched_wakeup_trace(struct trace_array *tr,
  -                             struct trace_array_cpu *data,
                                struct task_struct *wakee,
                                struct task_struct *cur,
                                unsigned long flags, int pc);
@@@@ -503,12 -511,12 -408,14 +520,12 @@@@ void trace_special(struct trace_array *
                   unsigned long arg2,
                   unsigned long arg3, int pc);
   void trace_function(struct trace_array *tr,
  -                 struct trace_array_cpu *data,
                    unsigned long ip,
                    unsigned long parent_ip,
                    unsigned long flags, int pc);
   
   void trace_graph_return(struct ftrace_graph_ret *trace);
   int trace_graph_entry(struct ftrace_graph_ent *trace);
  -void trace_hw_branch(struct trace_array *tr, u64 from, u64 to);
   
   void tracing_start_cmdline_record(void);
   void tracing_stop_cmdline_record(void);
@@@@ -527,11 -535,11 -434,15 +544,11 @@@@ void update_max_tr(struct trace_array *
   void update_max_tr_single(struct trace_array *tr,
                          struct task_struct *tsk, int cpu);
   
  -extern cycle_t ftrace_now(int cpu);
  +void __trace_stack(struct trace_array *tr,
  +                unsigned long flags,
  +                int skip, int pc);
   
  -#ifdef CONFIG_FUNCTION_TRACER
  -void tracing_start_function_trace(void);
  -void tracing_stop_function_trace(void);
  -#else
  -# define tracing_start_function_trace()              do { } while (0)
  -# define tracing_stop_function_trace()               do { } while (0)
  -#endif
  +extern cycle_t ftrace_now(int cpu);
   
   #ifdef CONFIG_CONTEXT_SWITCH_TRACER
   typedef void
@@@@ -545,10 -553,10 -456,10 +562,10 @@@@ struct tracer_switch_ops 
        void                            *private;
        struct tracer_switch_ops        *next;
   };
  -
  -char *trace_find_cmdline(int pid);
   #endif /* CONFIG_CONTEXT_SWITCH_TRACER */
   
  +extern char *trace_find_cmdline(int pid);
  +
   #ifdef CONFIG_DYNAMIC_FTRACE
   extern unsigned long ftrace_update_tot_cnt;
   #define DYN_FTRACE_TEST_NAME trace_selftest_dynamic_test_func
@@@@ -558,8 -566,8 -469,6 +575,8 @@@@ extern int DYN_FTRACE_TEST_NAME(void)
   #ifdef CONFIG_FTRACE_STARTUP_TEST
   extern int trace_selftest_startup_function(struct tracer *trace,
                                           struct trace_array *tr);
  +extern int trace_selftest_startup_function_graph(struct tracer *trace,
  +                                              struct trace_array *tr);
   extern int trace_selftest_startup_irqsoff(struct tracer *trace,
                                          struct trace_array *tr);
   extern int trace_selftest_startup_preemptoff(struct tracer *trace,
@@@@ -579,10 -587,8 -488,17 +596,10 @@@@ extern int trace_selftest_startup_branc
   #endif /* CONFIG_FTRACE_STARTUP_TEST */
   
   extern void *head_page(struct trace_array_cpu *data);
  -extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...);
  -extern void trace_seq_print_cont(struct trace_seq *s,
  -                              struct trace_iterator *iter);
  -
  -extern int
  -seq_print_ip_sym(struct trace_seq *s, unsigned long ip,
  -             unsigned long sym_flags);
  -extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
  -                              size_t cnt);
   extern long ns2usecs(cycle_t nsec);
   extern int
 ++trace_vbprintk(unsigned long ip, int depth, const char *fmt, va_list args);
 ++extern int
   trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args);
   
   extern unsigned long trace_flags;
@@@@ -664,9 -670,9 -580,7 +681,9 @@@@ enum trace_iterator_flags 
        TRACE_ITER_ANNOTATE             = 0x2000,
        TRACE_ITER_USERSTACKTRACE       = 0x4000,
        TRACE_ITER_SYM_USEROBJ          = 0x8000,
  -     TRACE_ITER_PRINTK_MSGONLY       = 0x10000
  +     TRACE_ITER_PRINTK_MSGONLY       = 0x10000,
  +     TRACE_ITER_CONTEXT_INFO         = 0x20000, /* Print pid/cpu/time */
  +     TRACE_ITER_LATENCY_FMT          = 0x40000,
   };
   
   /*
@@@@ -687,12 -693,12 -601,12 +704,12 @@@@ extern struct tracer nop_trace
    * preempt_enable (after a disable), a schedule might take place
    * causing an infinite recursion.
    *
  - * To prevent this, we read the need_recshed flag before
  + * To prevent this, we read the need_resched flag before
    * disabling preemption. When we want to enable preemption we
    * check the flag, if it is set, then we call preempt_enable_no_resched.
    * Otherwise, we call preempt_enable.
    *
  - * The rational for doing the above is that if need resched is set
  + * The rational for doing the above is that if need_resched is set
    * and we have yet to reschedule, we are either in an atomic location
    * (where we do not need to check for scheduling) or we are inside
    * the scheduler and do not want to resched.
@@@@ -713,7 -719,7 -627,7 +730,7 @@@@ static inline int ftrace_preempt_disabl
    *
    * This is a scheduler safe way to enable preemption and not miss
    * any preemption checks. The disabled saved the state of preemption.
  - * If resched is set, then we were either inside an atomic or
  + * If resched is set, then we are either inside an atomic or
    * are inside the scheduler (we would have already scheduled
    * otherwise). In this case, we do not want to call normal
    * preempt_enable, but preempt_enable_no_resched instead.
@@@@ -750,51 -756,26 -664,4 +767,51 @@@@ static inline void trace_branch_disable
   }
   #endif /* CONFIG_BRANCH_TRACER */
   
 ++/* set ring buffers to default size if not already done so */
 ++int tracing_update_buffers(void);
 ++
  +/* trace event type bit fields, not numeric */
  +enum {
  +     TRACE_EVENT_TYPE_PRINTF         = 1,
  +     TRACE_EVENT_TYPE_RAW            = 2,
  +};
  +
  +struct ftrace_event_call {
  +     char            *name;
  +     char            *system;
  +     struct dentry   *dir;
  +     int             enabled;
  +     int             (*regfunc)(void);
  +     void            (*unregfunc)(void);
  +     int             id;
  +     int             (*raw_init)(void);
  +     int             (*show_format)(struct trace_seq *s);
  +};
  +
  +void event_trace_printk(unsigned long ip, const char *fmt, ...);
  +extern struct ftrace_event_call __start_ftrace_events[];
  +extern struct ftrace_event_call __stop_ftrace_events[];
  +
 ++extern const char *__start___trace_bprintk_fmt[];
 ++extern const char *__stop___trace_bprintk_fmt[];
 ++
 ++/*
 ++ * The double __builtin_constant_p is because gcc will give us an error
 ++ * if we try to allocate the static variable to fmt if it is not a
 ++ * constant. Even with the outer if statement optimizing out.
 ++ */
 ++#define event_trace_printk(ip, fmt, args...)                         \
 ++do {                                                                 \
 ++     __trace_printk_check_format(fmt, ##args);                       \
 ++     tracing_record_cmdline(current);                                \
 ++     if (__builtin_constant_p(fmt)) {                                \
 ++             static const char *trace_printk_fmt                     \
 ++               __attribute__((section("__trace_printk_fmt"))) =      \
 ++                     __builtin_constant_p(fmt) ? fmt : NULL;         \
 ++                                                                     \
 ++             __trace_bprintk(ip, trace_printk_fmt, ##args);          \
 ++     } else                                                          \
 ++             __trace_printk(ip, fmt, ##args);                        \
 ++} while (0)
 ++
   #endif /* _LINUX_KERNEL_TRACE_H */
diff --combined mm/vmscan.c
@@@@ -1262,7 -1262,7 -1262,6 +1262,6 @@@@ static void shrink_active_list(unsigne
         * Move the pages to the [file or anon] inactive list.
         */
        pagevec_init(&pvec, 1);
--      pgmoved = 0;
        lru = LRU_BASE + file * LRU_FILE;
   
        spin_lock_irq(&zone->lru_lock);
         */
        reclaim_stat->recent_rotated[!!file] += pgmoved;
   
++      pgmoved = 0;
        while (!list_empty(&l_inactive)) {
                page = lru_to_page(&l_inactive);
                prefetchw_prev_lru_page(page, &l_inactive, flags);
@@@@ -1965,8 -1965,8 -1965,6 +1965,8 @@@@ static int kswapd(void *p
        };
        node_to_cpumask_ptr(cpumask, pgdat->node_id);
   
  +     lockdep_set_current_reclaim_state(GFP_KERNEL);
  +
        if (!cpumask_empty(cpumask))
                set_cpus_allowed_ptr(tsk, cpumask);
        current->reclaim_state = &reclaim_state;