History

perf core: Allow setting up max frame stack depth via sysctl

The default remains 127, which is good for most cases, and not even hit most of the time, but then for some cases, as reported by Brendan, 1024+ deep frames are appearing on the radar for things like groovy, ruby. And in some workloads putting a _lower_ cap on this may make sense. One that is per event still needs to be put in place tho. The new file is: # cat /proc/sys/kernel/perf_event_max_stack 127 Chaging it: # echo 256 > /proc/sys/kernel/perf_event_max_stack # cat /proc/sys/kernel/perf_event_max_stack 256 But as soon as there is some event using callchains we get: # echo 512 > /proc/sys/kernel/perf_event_max_stack -bash: echo: write error: Device or resource busy # Because we only allocate the callchain percpu data structures when there is a user, which allows for changing the max easily, its just a matter of having no callchain users at that point.

Arnaldo Carvalho de Melo committed 10 years ago

Commit c5dfd781 parent c2a218c13 files · +84 −23Browse files

Showing the changes to kernel/bpf/stackmap.c (1 of 13 files). Show all

Unified · Split

kernel/bpf/stackmap.c+4−4
@@ -66,7 +66,7 @@ static struct bpf_map *stack_map_alloc(union bpf_attr *attr) · 65 unmodified lines
6666 /* check sanity of attributes */
6767 if (attr->max_entries == 0 || attr->key_size != 4 ||
6868 value_size < 8 || value_size % 8 ||
69− value_size / 8 > PERF_MAX_STACK_DEPTH)
69+ value_size / 8 > sysctl_perf_event_max_stack)
7070 return ERR_PTR(-EINVAL);
7171
7272 /* hash table size must be power of 2 */
@@ -124,8 +124,8 @@ static u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5) · 51 unmodified lines
124124 struct perf_callchain_entry *trace;
125125 struct stack_map_bucket *bucket, *new_bucket, *old_bucket;
126126 u32 max_depth = map->value_size / 8;
127− /* stack_map_alloc() checks that max_depth <= PERF_MAX_STACK_DEPTH */
128− u32 init_nr = PERF_MAX_STACK_DEPTH - max_depth;
127+ /* stack_map_alloc() checks that max_depth <= sysctl_perf_event_max_stack */
128+ u32 init_nr = sysctl_perf_event_max_stack - max_depth;
129129 u32 skip = flags & BPF_F_SKIP_FIELD_MASK;
130130 u32 hash, id, trace_nr, trace_len;
131131 bool user = flags & BPF_F_USER_STACK;
@@ -143,7 +143,7 @@ static u64 bpf_get_stackid(u64 r1, u64 r2, u64 flags, u64 r4, u64 r5) · 11 unmodified lines
143143 return -EFAULT;
144144
145145 /* get_perf_callchain() guarantees that trace->nr >= init_nr
146− * and trace-nr <= PERF_MAX_STACK_DEPTH, so trace_nr <= max_depth
146+ * and trace-nr <= sysctl_perf_event_max_stack, so trace_nr <= max_depth
147147 */
148148 trace_nr = trace->nr - init_nr;
149149