#define LIKELY_PROFILE()
 #endif
 
+#ifdef CONFIG_PROFILE_ALL_BRANCHES
+#define BRANCH_PROFILE()       VMLINUX_SYMBOL(__start_branch_profile) = .;   \
+                               *(_ftrace_branch)                             \
+                               VMLINUX_SYMBOL(__stop_branch_profile) = .;
+#else
+#define BRANCH_PROFILE()
+#endif
+
 /* .data section */
 #define DATA_DATA                                                      \
        *(.data)                                                        \
        VMLINUX_SYMBOL(__start___tracepoints) = .;                      \
        *(__tracepoints)                                                \
        VMLINUX_SYMBOL(__stop___tracepoints) = .;                       \
-       LIKELY_PROFILE()
+       LIKELY_PROFILE()                                                \
+       BRANCH_PROFILE()
 
 #define RO_DATA(align)                                                 \
        . = ALIGN((align));                                             \
 
        const char *func;
        const char *file;
        unsigned line;
-       unsigned long correct;
-       unsigned long incorrect;
+       union {
+               struct {
+                       unsigned long correct;
+                       unsigned long incorrect;
+               };
+               struct {
+                       unsigned long miss;
+                       unsigned long hit;
+               };
+       };
 };
 
 /*
 # ifndef unlikely
 #  define unlikely(x)  (__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
 # endif
+
+#ifdef CONFIG_PROFILE_ALL_BRANCHES
+/*
+ * "Define 'is'", Bill Clinton
+ * "Define 'if'", Steven Rostedt
+ */
+#define if(cond) if (__builtin_constant_p((cond)) ? !!(cond) :         \
+       ({                                                              \
+               int ______r;                                            \
+               static struct ftrace_branch_data                        \
+                       __attribute__((__aligned__(4)))                 \
+                       __attribute__((section("_ftrace_branch")))      \
+                       ______f = {                                     \
+                               .func = __func__,                       \
+                               .file = __FILE__,                       \
+                               .line = __LINE__,                       \
+                       };                                              \
+               ______r = !!(cond);                                     \
+               if (______r)                                            \
+                       ______f.hit++;                                  \
+               else                                                    \
+                       ______f.miss++;                                 \
+               ______r;                                                \
+       }))
+#endif /* CONFIG_PROFILE_ALL_BRANCHES */
+
 #else
 # define likely(x)     __builtin_expect(!!(x), 1)
 # define unlikely(x)   __builtin_expect(!!(x), 0)
 
 
          Say N if unsure.
 
+config PROFILE_ALL_BRANCHES
+       bool "Profile all if conditionals"
+       depends on TRACE_BRANCH_PROFILING
+       help
+         This tracer profiles all branch conditions. Every if ()
+         taken in the kernel is recorded whether it hit or miss.
+         The results will be displayed in:
+
+         /debugfs/tracing/profile_branch
+
+         This configuration, when enabled, will impose a great overhead
+         on the system. This should only be enabled when the system
+         is to be analyzed
+
+         Say N if unsure.
+
 config TRACING_BRANCHES
        bool
        help
 
 struct ftrace_pointer {
        void            *start;
        void            *stop;
+       int             hit;
 };
 
 static void *
 
 static int t_show(struct seq_file *m, void *v)
 {
+       struct ftrace_pointer *fp = m->private;
        struct ftrace_branch_data *p = v;
        const char *f;
        long percent;
 
        if (v == (void *)1) {
-               seq_printf(m, " correct incorrect  %% "
-                             "       Function                "
+               if (fp->hit)
+                       seq_printf(m, "   miss      hit    %% ");
+               else
+                       seq_printf(m, " correct incorrect  %% ");
+               seq_printf(m, "       Function                "
                              "  File              Line\n"
                              " ------- ---------  - "
                              "       --------                "
                f--;
        f++;
 
+       /*
+        * The miss is overlayed on correct, and hit on incorrect.
+        */
        if (p->correct) {
                percent = p->incorrect * 100;
                percent /= p->correct + p->incorrect;
        .llseek         = seq_lseek,
 };
 
+#ifdef CONFIG_PROFILE_ALL_BRANCHES
+extern unsigned long __start_branch_profile[];
+extern unsigned long __stop_branch_profile[];
+
+static struct ftrace_pointer ftrace_branch_pos = {
+       .start                  = __start_branch_profile,
+       .stop                   = __stop_branch_profile,
+       .hit                    = 1,
+};
+
+#endif /* CONFIG_PROFILE_ALL_BRANCHES */
+
 extern unsigned long __start_annotated_branch_profile[];
 extern unsigned long __stop_annotated_branch_profile[];
 
                pr_warning("Could not create debugfs "
                           "'profile_annotatet_branch' entry\n");
 
+#ifdef CONFIG_PROFILE_ALL_BRANCHES
+       entry = debugfs_create_file("profile_branch", 0444, d_tracer,
+                                   &ftrace_branch_pos,
+                                   &tracing_branch_fops);
+       if (!entry)
+               pr_warning("Could not create debugfs"
+                          " 'profile_branch' entry\n");
+#endif
+
        return 0;
 }