We will use it to count how many addresses are in the entry->ip[] array,
excluding PERF_CONTEXT_{KERNEL,USER,etc} entries, so that we can really
return the number of entries specified by the user via the relevant
sysctl, kernel.perf_event_max_contexts, or via the per event
perf_event_attr.sample_max_stack knob.
This way we keep the perf_sample->ip_callchain->nr meaning, that is the
number of entries, be it real addresses or PERF_CONTEXT_ entries, while
honouring the max_stack knobs, i.e. the end result will be max_stack
entries if we have at least that many entries in a given stack trace.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/n/tip-s8teto51tdqvlfhefndtat9r@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
 
        tail = (struct frame_tail __user *)regs->ARM_fp - 1;
 
-       while ((entry->entry->nr < entry->max_stack) &&
+       while ((entry->nr < entry->max_stack) &&
               tail && !((unsigned long)tail & 0x3))
                tail = user_backtrace(tail, entry);
 }
 
 
                tail = (struct frame_tail __user *)regs->regs[29];
 
-               while (entry->entry->nr < entry->max_stack &&
+               while (entry->nr < entry->max_stack &&
                       tail && !((unsigned long)tail & 0xf))
                        tail = user_backtrace(tail, entry);
        } else {
 
                tail = (struct compat_frame_tail __user *)regs->compat_fp - 1;
 
-               while ((entry->entry->nr < entry->max_stack) &&
+               while ((entry->nr < entry->max_stack) &&
                        tail && !((unsigned long)tail & 0x3))
                        tail = compat_user_backtrace(tail, entry);
 #endif
 
 
        --frame;
 
-       while ((entry->entry->nr < entry->max_stack) && frame)
+       while ((entry->nr < entry->max_stack) && frame)
                frame = user_backtrace(frame, entry);
 }
 
 
                addr = *sp++;
                if (__kernel_text_address(addr)) {
                        perf_callchain_store(entry, addr);
-                       if (entry->entry->nr >= entry->max_stack)
+                       if (entry->nr >= entry->max_stack)
                                break;
                }
        }
        }
        do {
                perf_callchain_store(entry, pc);
-               if (entry->entry->nr >= entry->max_stack)
+               if (entry->nr >= entry->max_stack)
                        break;
                pc = unwind_stack(current, &sp, pc, &ra);
        } while (pc);
 
        sp = regs->gpr[1];
        perf_callchain_store(entry, next_ip);
 
-       while (entry->entry->nr < entry->max_stack) {
+       while (entry->nr < entry->max_stack) {
                fp = (unsigned long __user *) sp;
                if (!valid_user_sp(sp, 1) || read_user_stack_64(fp, &next_sp))
                        return;
        sp = regs->gpr[1];
        perf_callchain_store(entry, next_ip);
 
-       while (entry->entry->nr < entry->max_stack) {
+       while (entry->nr < entry->max_stack) {
                fp = (unsigned int __user *) (unsigned long) sp;
                if (!valid_user_sp(sp, 0) || read_user_stack_32(fp, &next_sp))
                        return;
 
                        }
                }
 #endif
-       } while (entry->entry->nr < entry->max_stack);
+       } while (entry->nr < entry->max_stack);
 }
 
 static inline int
                pc = sf.callers_pc;
                ufp = (unsigned long)sf.fp + STACK_BIAS;
                perf_callchain_store(entry, pc);
-       } while (entry->entry->nr < entry->max_stack);
+       } while (entry->nr < entry->max_stack);
 }
 
 static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
                        ufp = (unsigned long)sf.fp;
                }
                perf_callchain_store(entry, pc);
-       } while (entry->entry->nr < entry->max_stack);
+       } while (entry->nr < entry->max_stack);
 }
 
 void
 
 
        fp = compat_ptr(ss_base + regs->bp);
        pagefault_disable();
-       while (entry->entry->nr < entry->max_stack) {
+       while (entry->nr < entry->max_stack) {
                unsigned long bytes;
                frame.next_frame     = 0;
                frame.return_address = 0;
                return;
 
        pagefault_disable();
-       while (entry->entry->nr < entry->max_stack) {
+       while (entry->nr < entry->max_stack) {
                unsigned long bytes;
                frame.next_frame             = NULL;
                frame.return_address = 0;
 
 struct perf_callchain_entry_ctx {
        struct perf_callchain_entry *entry;
        u32                         max_stack;
+       u32                         nr;
 };
 
 struct perf_raw_record {
 
 static inline int perf_callchain_store(struct perf_callchain_entry_ctx *ctx, u64 ip)
 {
-       struct perf_callchain_entry *entry = ctx->entry;
-       if (entry->nr < ctx->max_stack) {
+       if (ctx->nr < ctx->max_stack) {
+               struct perf_callchain_entry *entry = ctx->entry;
                entry->ip[entry->nr++] = ip;
+               ++ctx->nr;
                return 0;
        } else {
                return -1; /* no more room, stop walking the stack */
 
 
        ctx.entry     = entry;
        ctx.max_stack = max_stack;
-
-       entry->nr = init_nr;
+       ctx.nr        = entry->nr = init_nr;
 
        if (kernel && !user_mode(regs)) {
                if (add_mark)