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
66 /* check sanity of attributes */66 /* check sanity of attributes */
67 if (attr->max_entries == 0 || attr->key_size != 4 ||67 if (attr->max_entries == 0 || attr->key_size != 4 ||
68 value_size < 8 || value_size % 8 ||68 value_size < 8 || value_size % 8 ||
69 value_size / 8 > PERF_MAX_STACK_DEPTH)69 value_size / 8 > sysctl_perf_event_max_stack)
70 return ERR_PTR(-EINVAL);70 return ERR_PTR(-EINVAL);
71 71
72 /* hash table size must be power of 2 */72 /* 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
124 struct perf_callchain_entry *trace;124 struct perf_callchain_entry *trace;
125 struct stack_map_bucket *bucket, *new_bucket, *old_bucket;125 struct stack_map_bucket *bucket, *new_bucket, *old_bucket;
126 u32 max_depth = map->value_size / 8;126 u32 max_depth = map->value_size / 8;
127 /* stack_map_alloc() checks that max_depth <= PERF_MAX_STACK_DEPTH */127 /* stack_map_alloc() checks that max_depth <= sysctl_perf_event_max_stack */
128 u32 init_nr = PERF_MAX_STACK_DEPTH - max_depth;128 u32 init_nr = sysctl_perf_event_max_stack - max_depth;
129 u32 skip = flags & BPF_F_SKIP_FIELD_MASK;129 u32 skip = flags & BPF_F_SKIP_FIELD_MASK;
130 u32 hash, id, trace_nr, trace_len;130 u32 hash, id, trace_nr, trace_len;
131 bool user = flags & BPF_F_USER_STACK;131 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
143 return -EFAULT;143 return -EFAULT;
144 144
145 /* get_perf_callchain() guarantees that trace->nr >= init_nr145 /* get_perf_callchain() guarantees that trace->nr >= init_nr
146 * and trace-nr <= PERF_MAX_STACK_DEPTH, so trace_nr <= max_depth146 * and trace-nr <= sysctl_perf_event_max_stack, so trace_nr <= max_depth
147 */147 */
148 trace_nr = trace->nr - init_nr;148 trace_nr = trace->nr - init_nr;
149 149