aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_functions.c
diff options
context:
space:
mode:
authorSteven Rostedt (VMware) <rostedt@goodmis.org>2017-04-03 23:22:41 -0400
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2017-04-20 22:06:39 -0400
commitfe014e24b6adfecdf8b3d0de1ef4d55a3eaf2b50 (patch)
treea70fe315210167d313088f92d022bcf951267376 /kernel/trace/trace_functions.c
parent1a93f8bd19bd24f9b41136e70188d8f4de90c6a2 (diff)
ftrace: Convert the rest of the function trigger over to the mapping functions
As the data pointer for individual ips will soon be removed and no longer passed to the callback function probe handlers, convert the rest of the function trigger counters over to the new ftrace_func_mapper helper functions. Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace/trace_functions.c')
-rw-r--r--kernel/trace/trace_functions.c123
1 files changed, 85 insertions, 38 deletions
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index b99f6231281e..d9cbde8575a8 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -267,10 +267,12 @@ static struct tracer function_trace __tracer_data =
267}; 267};
268 268
269#ifdef CONFIG_DYNAMIC_FTRACE 269#ifdef CONFIG_DYNAMIC_FTRACE
270static void update_traceon_count(void **data, bool on) 270static void update_traceon_count(struct ftrace_probe_ops *ops,
271 unsigned long ip, bool on)
271{ 272{
272 long *count = (long *)data; 273 struct ftrace_func_mapper *mapper = ops->private_data;
273 long old_count = *count; 274 long *count;
275 long old_count;
274 276
275 /* 277 /*
276 * Tracing gets disabled (or enabled) once per count. 278 * Tracing gets disabled (or enabled) once per count.
@@ -301,7 +303,10 @@ static void update_traceon_count(void **data, bool on)
301 * setting the tracing_on file. But we currently don't care 303 * setting the tracing_on file. But we currently don't care
302 * about that. 304 * about that.
303 */ 305 */
304 if (!old_count) 306 count = (long *)ftrace_func_mapper_find_ip(mapper, ip);
307 old_count = *count;
308
309 if (old_count <= 0)
305 return; 310 return;
306 311
307 /* Make sure we see count before checking tracing state */ 312 /* Make sure we see count before checking tracing state */
@@ -315,10 +320,6 @@ static void update_traceon_count(void **data, bool on)
315 else 320 else
316 tracing_off(); 321 tracing_off();
317 322
318 /* unlimited? */
319 if (old_count == -1)
320 return;
321
322 /* Make sure tracing state is visible before updating count */ 323 /* Make sure tracing state is visible before updating count */
323 smp_wmb(); 324 smp_wmb();
324 325
@@ -329,14 +330,14 @@ static void
329ftrace_traceon_count(unsigned long ip, unsigned long parent_ip, 330ftrace_traceon_count(unsigned long ip, unsigned long parent_ip,
330 struct ftrace_probe_ops *ops, void **data) 331 struct ftrace_probe_ops *ops, void **data)
331{ 332{
332 update_traceon_count(data, 1); 333 update_traceon_count(ops, ip, 1);
333} 334}
334 335
335static void 336static void
336ftrace_traceoff_count(unsigned long ip, unsigned long parent_ip, 337ftrace_traceoff_count(unsigned long ip, unsigned long parent_ip,
337 struct ftrace_probe_ops *ops, void **data) 338 struct ftrace_probe_ops *ops, void **data)
338{ 339{
339 update_traceon_count(data, 0); 340 update_traceon_count(ops, ip, 0);
340} 341}
341 342
342static void 343static void
@@ -379,47 +380,56 @@ static void
379ftrace_stacktrace_count(unsigned long ip, unsigned long parent_ip, 380ftrace_stacktrace_count(unsigned long ip, unsigned long parent_ip,
380 struct ftrace_probe_ops *ops, void **data) 381 struct ftrace_probe_ops *ops, void **data)
381{ 382{
382 long *count = (long *)data; 383 struct ftrace_func_mapper *mapper = ops->private_data;
384 long *count;
383 long old_count; 385 long old_count;
384 long new_count; 386 long new_count;
385 387
388 if (!tracing_is_on())
389 return;
390
391 /* unlimited? */
392 if (!mapper) {
393 trace_dump_stack(STACK_SKIP);
394 return;
395 }
396
397 count = (long *)ftrace_func_mapper_find_ip(mapper, ip);
398
386 /* 399 /*
387 * Stack traces should only execute the number of times the 400 * Stack traces should only execute the number of times the
388 * user specified in the counter. 401 * user specified in the counter.
389 */ 402 */
390 do { 403 do {
391
392 if (!tracing_is_on())
393 return;
394
395 old_count = *count; 404 old_count = *count;
396 405
397 if (!old_count) 406 if (!old_count)
398 return; 407 return;
399 408
400 /* unlimited? */
401 if (old_count == -1) {
402 trace_dump_stack(STACK_SKIP);
403 return;
404 }
405
406 new_count = old_count - 1; 409 new_count = old_count - 1;
407 new_count = cmpxchg(count, old_count, new_count); 410 new_count = cmpxchg(count, old_count, new_count);
408 if (new_count == old_count) 411 if (new_count == old_count)
409 trace_dump_stack(STACK_SKIP); 412 trace_dump_stack(STACK_SKIP);
410 413
414 if (!tracing_is_on())
415 return;
416
411 } while (new_count != old_count); 417 } while (new_count != old_count);
412} 418}
413 419
414static int update_count(void **data) 420static int update_count(struct ftrace_probe_ops *ops, unsigned long ip)
415{ 421{
416 unsigned long *count = (long *)data; 422 struct ftrace_func_mapper *mapper = ops->private_data;
423 long *count = NULL;
417 424
418 if (!*count) 425 if (mapper)
419 return 0; 426 count = (long *)ftrace_func_mapper_find_ip(mapper, ip);
420 427
421 if (*count != -1) 428 if (count) {
429 if (*count <= 0)
430 return 0;
422 (*count)--; 431 (*count)--;
432 }
423 433
424 return 1; 434 return 1;
425} 435}
@@ -428,7 +438,7 @@ static void
428ftrace_dump_probe(unsigned long ip, unsigned long parent_ip, 438ftrace_dump_probe(unsigned long ip, unsigned long parent_ip,
429 struct ftrace_probe_ops *ops, void **data) 439 struct ftrace_probe_ops *ops, void **data)
430{ 440{
431 if (update_count(data)) 441 if (update_count(ops, ip))
432 ftrace_dump(DUMP_ALL); 442 ftrace_dump(DUMP_ALL);
433} 443}
434 444
@@ -437,22 +447,26 @@ static void
437ftrace_cpudump_probe(unsigned long ip, unsigned long parent_ip, 447ftrace_cpudump_probe(unsigned long ip, unsigned long parent_ip,
438 struct ftrace_probe_ops *ops, void **data) 448 struct ftrace_probe_ops *ops, void **data)
439{ 449{
440 if (update_count(data)) 450 if (update_count(ops, ip))
441 ftrace_dump(DUMP_ORIG); 451 ftrace_dump(DUMP_ORIG);
442} 452}
443 453
444static int 454static int
445ftrace_probe_print(const char *name, struct seq_file *m, 455ftrace_probe_print(const char *name, struct seq_file *m,
446 unsigned long ip, void *data) 456 unsigned long ip, struct ftrace_probe_ops *ops)
447{ 457{
448 long count = (long)data; 458 struct ftrace_func_mapper *mapper = ops->private_data;
459 long *count = NULL;
449 460
450 seq_printf(m, "%ps:%s", (void *)ip, name); 461 seq_printf(m, "%ps:%s", (void *)ip, name);
451 462
452 if (count == -1) 463 if (mapper)
453 seq_puts(m, ":unlimited\n"); 464 count = (long *)ftrace_func_mapper_find_ip(mapper, ip);
465
466 if (count)
467 seq_printf(m, ":count=%ld\n", *count);
454 else 468 else
455 seq_printf(m, ":count=%ld\n", count); 469 seq_puts(m, ":unlimited\n");
456 470
457 return 0; 471 return 0;
458} 472}
@@ -461,55 +475,82 @@ static int
461ftrace_traceon_print(struct seq_file *m, unsigned long ip, 475ftrace_traceon_print(struct seq_file *m, unsigned long ip,
462 struct ftrace_probe_ops *ops, void *data) 476 struct ftrace_probe_ops *ops, void *data)
463{ 477{
464 return ftrace_probe_print("traceon", m, ip, data); 478 return ftrace_probe_print("traceon", m, ip, ops);
465} 479}
466 480
467static int 481static int
468ftrace_traceoff_print(struct seq_file *m, unsigned long ip, 482ftrace_traceoff_print(struct seq_file *m, unsigned long ip,
469 struct ftrace_probe_ops *ops, void *data) 483 struct ftrace_probe_ops *ops, void *data)
470{ 484{
471 return ftrace_probe_print("traceoff", m, ip, data); 485 return ftrace_probe_print("traceoff", m, ip, ops);
472} 486}
473 487
474static int 488static int
475ftrace_stacktrace_print(struct seq_file *m, unsigned long ip, 489ftrace_stacktrace_print(struct seq_file *m, unsigned long ip,
476 struct ftrace_probe_ops *ops, void *data) 490 struct ftrace_probe_ops *ops, void *data)
477{ 491{
478 return ftrace_probe_print("stacktrace", m, ip, data); 492 return ftrace_probe_print("stacktrace", m, ip, ops);
479} 493}
480 494
481static int 495static int
482ftrace_dump_print(struct seq_file *m, unsigned long ip, 496ftrace_dump_print(struct seq_file *m, unsigned long ip,
483 struct ftrace_probe_ops *ops, void *data) 497 struct ftrace_probe_ops *ops, void *data)
484{ 498{
485 return ftrace_probe_print("dump", m, ip, data); 499 return ftrace_probe_print("dump", m, ip, ops);
486} 500}
487 501
488static int 502static int
489ftrace_cpudump_print(struct seq_file *m, unsigned long ip, 503ftrace_cpudump_print(struct seq_file *m, unsigned long ip,
490 struct ftrace_probe_ops *ops, void *data) 504 struct ftrace_probe_ops *ops, void *data)
491{ 505{
492 return ftrace_probe_print("cpudump", m, ip, data); 506 return ftrace_probe_print("cpudump", m, ip, ops);
507}
508
509
510static int
511ftrace_count_init(struct ftrace_probe_ops *ops, unsigned long ip,
512 void **data)
513{
514 struct ftrace_func_mapper *mapper = ops->private_data;
515
516 return ftrace_func_mapper_add_ip(mapper, ip, *data);
517}
518
519static void
520ftrace_count_free(struct ftrace_probe_ops *ops, unsigned long ip,
521 void **_data)
522{
523 struct ftrace_func_mapper *mapper = ops->private_data;
524
525 ftrace_func_mapper_remove_ip(mapper, ip);
493} 526}
494 527
495static struct ftrace_probe_ops traceon_count_probe_ops = { 528static struct ftrace_probe_ops traceon_count_probe_ops = {
496 .func = ftrace_traceon_count, 529 .func = ftrace_traceon_count,
497 .print = ftrace_traceon_print, 530 .print = ftrace_traceon_print,
531 .init = ftrace_count_init,
532 .free = ftrace_count_free,
498}; 533};
499 534
500static struct ftrace_probe_ops traceoff_count_probe_ops = { 535static struct ftrace_probe_ops traceoff_count_probe_ops = {
501 .func = ftrace_traceoff_count, 536 .func = ftrace_traceoff_count,
502 .print = ftrace_traceoff_print, 537 .print = ftrace_traceoff_print,
538 .init = ftrace_count_init,
539 .free = ftrace_count_free,
503}; 540};
504 541
505static struct ftrace_probe_ops stacktrace_count_probe_ops = { 542static struct ftrace_probe_ops stacktrace_count_probe_ops = {
506 .func = ftrace_stacktrace_count, 543 .func = ftrace_stacktrace_count,
507 .print = ftrace_stacktrace_print, 544 .print = ftrace_stacktrace_print,
545 .init = ftrace_count_init,
546 .free = ftrace_count_free,
508}; 547};
509 548
510static struct ftrace_probe_ops dump_probe_ops = { 549static struct ftrace_probe_ops dump_probe_ops = {
511 .func = ftrace_dump_probe, 550 .func = ftrace_dump_probe,
512 .print = ftrace_dump_print, 551 .print = ftrace_dump_print,
552 .init = ftrace_count_init,
553 .free = ftrace_count_free,
513}; 554};
514 555
515static struct ftrace_probe_ops cpudump_probe_ops = { 556static struct ftrace_probe_ops cpudump_probe_ops = {
@@ -558,6 +599,12 @@ ftrace_trace_probe_callback(struct ftrace_probe_ops *ops,
558 if (!strlen(number)) 599 if (!strlen(number))
559 goto out_reg; 600 goto out_reg;
560 601
602 if (!ops->private_data) {
603 ops->private_data = allocate_ftrace_func_mapper();
604 if (!ops->private_data)
605 return -ENOMEM;
606 }
607
561 /* 608 /*
562 * We use the callback data field (which is a pointer) 609 * We use the callback data field (which is a pointer)
563 * as our counter. 610 * as our counter.