aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ftrace_event.h4
-rw-r--r--kernel/trace/trace.c34
-rw-r--r--kernel/trace/trace.h9
-rw-r--r--kernel/trace/trace_kprobe.c6
4 files changed, 46 insertions, 7 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h
index 59d3ef100eb9..b1e69eefc203 100644
--- a/include/linux/ftrace_event.h
+++ b/include/linux/ftrace_event.h
@@ -129,6 +129,10 @@ void trace_current_buffer_unlock_commit(struct ring_buffer *buffer,
129void trace_nowake_buffer_unlock_commit(struct ring_buffer *buffer, 129void trace_nowake_buffer_unlock_commit(struct ring_buffer *buffer,
130 struct ring_buffer_event *event, 130 struct ring_buffer_event *event,
131 unsigned long flags, int pc); 131 unsigned long flags, int pc);
132void trace_nowake_buffer_unlock_commit_regs(struct ring_buffer *buffer,
133 struct ring_buffer_event *event,
134 unsigned long flags, int pc,
135 struct pt_regs *regs);
132void trace_current_buffer_discard_commit(struct ring_buffer *buffer, 136void trace_current_buffer_discard_commit(struct ring_buffer *buffer,
133 struct ring_buffer_event *event); 137 struct ring_buffer_event *event);
134 138
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index c977018e87c2..d9c16123f6e2 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1193,6 +1193,18 @@ void trace_nowake_buffer_unlock_commit(struct ring_buffer *buffer,
1193} 1193}
1194EXPORT_SYMBOL_GPL(trace_nowake_buffer_unlock_commit); 1194EXPORT_SYMBOL_GPL(trace_nowake_buffer_unlock_commit);
1195 1195
1196void trace_nowake_buffer_unlock_commit_regs(struct ring_buffer *buffer,
1197 struct ring_buffer_event *event,
1198 unsigned long flags, int pc,
1199 struct pt_regs *regs)
1200{
1201 ring_buffer_unlock_commit(buffer, event);
1202
1203 ftrace_trace_stack_regs(buffer, flags, 0, pc, regs);
1204 ftrace_trace_userstack(buffer, flags, pc);
1205}
1206EXPORT_SYMBOL_GPL(trace_nowake_buffer_unlock_commit_regs);
1207
1196void trace_current_buffer_discard_commit(struct ring_buffer *buffer, 1208void trace_current_buffer_discard_commit(struct ring_buffer *buffer,
1197 struct ring_buffer_event *event) 1209 struct ring_buffer_event *event)
1198{ 1210{
@@ -1238,7 +1250,7 @@ ftrace(struct trace_array *tr, struct trace_array_cpu *data,
1238#ifdef CONFIG_STACKTRACE 1250#ifdef CONFIG_STACKTRACE
1239static void __ftrace_trace_stack(struct ring_buffer *buffer, 1251static void __ftrace_trace_stack(struct ring_buffer *buffer,
1240 unsigned long flags, 1252 unsigned long flags,
1241 int skip, int pc) 1253 int skip, int pc, struct pt_regs *regs)
1242{ 1254{
1243 struct ftrace_event_call *call = &event_kernel_stack; 1255 struct ftrace_event_call *call = &event_kernel_stack;
1244 struct ring_buffer_event *event; 1256 struct ring_buffer_event *event;
@@ -1257,24 +1269,36 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer,
1257 trace.skip = skip; 1269 trace.skip = skip;
1258 trace.entries = entry->caller; 1270 trace.entries = entry->caller;
1259 1271
1260 save_stack_trace(&trace); 1272 if (regs)
1273 save_stack_trace_regs(regs, &trace);
1274 else
1275 save_stack_trace(&trace);
1261 if (!filter_check_discard(call, entry, buffer, event)) 1276 if (!filter_check_discard(call, entry, buffer, event))
1262 ring_buffer_unlock_commit(buffer, event); 1277 ring_buffer_unlock_commit(buffer, event);
1263} 1278}
1264 1279
1280void ftrace_trace_stack_regs(struct ring_buffer *buffer, unsigned long flags,
1281 int skip, int pc, struct pt_regs *regs)
1282{
1283 if (!(trace_flags & TRACE_ITER_STACKTRACE))
1284 return;
1285
1286 __ftrace_trace_stack(buffer, flags, skip, pc, regs);
1287}
1288
1265void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags, 1289void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags,
1266 int skip, int pc) 1290 int skip, int pc)
1267{ 1291{
1268 if (!(trace_flags & TRACE_ITER_STACKTRACE)) 1292 if (!(trace_flags & TRACE_ITER_STACKTRACE))
1269 return; 1293 return;
1270 1294
1271 __ftrace_trace_stack(buffer, flags, skip, pc); 1295 __ftrace_trace_stack(buffer, flags, skip, pc, NULL);
1272} 1296}
1273 1297
1274void __trace_stack(struct trace_array *tr, unsigned long flags, int skip, 1298void __trace_stack(struct trace_array *tr, unsigned long flags, int skip,
1275 int pc) 1299 int pc)
1276{ 1300{
1277 __ftrace_trace_stack(tr->buffer, flags, skip, pc); 1301 __ftrace_trace_stack(tr->buffer, flags, skip, pc, NULL);
1278} 1302}
1279 1303
1280/** 1304/**
@@ -1290,7 +1314,7 @@ void trace_dump_stack(void)
1290 local_save_flags(flags); 1314 local_save_flags(flags);
1291 1315
1292 /* skipping 3 traces, seems to get us at the caller of this function */ 1316 /* skipping 3 traces, seems to get us at the caller of this function */
1293 __ftrace_trace_stack(global_trace.buffer, flags, 3, preempt_count()); 1317 __ftrace_trace_stack(global_trace.buffer, flags, 3, preempt_count(), NULL);
1294} 1318}
1295 1319
1296static DEFINE_PER_CPU(int, user_stack_count); 1320static DEFINE_PER_CPU(int, user_stack_count);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 742f545ae185..a3e2db708072 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -389,6 +389,9 @@ void update_max_tr_single(struct trace_array *tr,
389void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags, 389void ftrace_trace_stack(struct ring_buffer *buffer, unsigned long flags,
390 int skip, int pc); 390 int skip, int pc);
391 391
392void ftrace_trace_stack_regs(struct ring_buffer *buffer, unsigned long flags,
393 int skip, int pc, struct pt_regs *regs);
394
392void ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, 395void ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags,
393 int pc); 396 int pc);
394 397
@@ -400,6 +403,12 @@ static inline void ftrace_trace_stack(struct ring_buffer *buffer,
400{ 403{
401} 404}
402 405
406static inline void ftrace_trace_stack_regs(struct ring_buffer *buffer,
407 unsigned long flags, int skip,
408 int pc, struct pt_regs *regs)
409{
410}
411
403static inline void ftrace_trace_userstack(struct ring_buffer *buffer, 412static inline void ftrace_trace_userstack(struct ring_buffer *buffer,
404 unsigned long flags, int pc) 413 unsigned long flags, int pc)
405{ 414{
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index f925c45f0afa..7053ef3d73d2 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -1397,7 +1397,8 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs)
1397 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); 1397 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
1398 1398
1399 if (!filter_current_check_discard(buffer, call, entry, event)) 1399 if (!filter_current_check_discard(buffer, call, entry, event))
1400 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); 1400 trace_nowake_buffer_unlock_commit_regs(buffer, event,
1401 irq_flags, pc, regs);
1401} 1402}
1402 1403
1403/* Kretprobe handler */ 1404/* Kretprobe handler */
@@ -1429,7 +1430,8 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri,
1429 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); 1430 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
1430 1431
1431 if (!filter_current_check_discard(buffer, call, entry, event)) 1432 if (!filter_current_check_discard(buffer, call, entry, event))
1432 trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); 1433 trace_nowake_buffer_unlock_commit_regs(buffer, event,
1434 irq_flags, pc, regs);
1433} 1435}
1434 1436
1435/* Event entry printers */ 1437/* Event entry printers */