aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_functions.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_functions.c')
-rw-r--r--kernel/trace/trace_functions.c79
1 files changed, 44 insertions, 35 deletions
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index b95f56ba9744..7775e1ca5bad 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -268,9 +268,10 @@ static struct tracer function_trace __tracer_data =
268 268
269#ifdef CONFIG_DYNAMIC_FTRACE 269#ifdef CONFIG_DYNAMIC_FTRACE
270static void update_traceon_count(struct ftrace_probe_ops *ops, 270static void update_traceon_count(struct ftrace_probe_ops *ops,
271 unsigned long ip, bool on) 271 unsigned long ip, bool on,
272 void *data)
272{ 273{
273 struct ftrace_func_mapper *mapper = ops->private_data; 274 struct ftrace_func_mapper *mapper = data;
274 long *count; 275 long *count;
275 long old_count; 276 long old_count;
276 277
@@ -329,23 +330,23 @@ static void update_traceon_count(struct ftrace_probe_ops *ops,
329static void 330static void
330ftrace_traceon_count(unsigned long ip, unsigned long parent_ip, 331ftrace_traceon_count(unsigned long ip, unsigned long parent_ip,
331 struct trace_array *tr, struct ftrace_probe_ops *ops, 332 struct trace_array *tr, struct ftrace_probe_ops *ops,
332 void **data) 333 void *data)
333{ 334{
334 update_traceon_count(ops, ip, 1); 335 update_traceon_count(ops, ip, 1, data);
335} 336}
336 337
337static void 338static void
338ftrace_traceoff_count(unsigned long ip, unsigned long parent_ip, 339ftrace_traceoff_count(unsigned long ip, unsigned long parent_ip,
339 struct trace_array *tr, struct ftrace_probe_ops *ops, 340 struct trace_array *tr, struct ftrace_probe_ops *ops,
340 void **data) 341 void *data)
341{ 342{
342 update_traceon_count(ops, ip, 0); 343 update_traceon_count(ops, ip, 0, data);
343} 344}
344 345
345static void 346static void
346ftrace_traceon(unsigned long ip, unsigned long parent_ip, 347ftrace_traceon(unsigned long ip, unsigned long parent_ip,
347 struct trace_array *tr, struct ftrace_probe_ops *ops, 348 struct trace_array *tr, struct ftrace_probe_ops *ops,
348 void **data) 349 void *data)
349{ 350{
350 if (tracing_is_on()) 351 if (tracing_is_on())
351 return; 352 return;
@@ -356,7 +357,7 @@ ftrace_traceon(unsigned long ip, unsigned long parent_ip,
356static void 357static void
357ftrace_traceoff(unsigned long ip, unsigned long parent_ip, 358ftrace_traceoff(unsigned long ip, unsigned long parent_ip,
358 struct trace_array *tr, struct ftrace_probe_ops *ops, 359 struct trace_array *tr, struct ftrace_probe_ops *ops,
359 void **data) 360 void *data)
360{ 361{
361 if (!tracing_is_on()) 362 if (!tracing_is_on())
362 return; 363 return;
@@ -376,7 +377,7 @@ ftrace_traceoff(unsigned long ip, unsigned long parent_ip,
376static void 377static void
377ftrace_stacktrace(unsigned long ip, unsigned long parent_ip, 378ftrace_stacktrace(unsigned long ip, unsigned long parent_ip,
378 struct trace_array *tr, struct ftrace_probe_ops *ops, 379 struct trace_array *tr, struct ftrace_probe_ops *ops,
379 void **data) 380 void *data)
380{ 381{
381 trace_dump_stack(STACK_SKIP); 382 trace_dump_stack(STACK_SKIP);
382} 383}
@@ -384,9 +385,9 @@ ftrace_stacktrace(unsigned long ip, unsigned long parent_ip,
384static void 385static void
385ftrace_stacktrace_count(unsigned long ip, unsigned long parent_ip, 386ftrace_stacktrace_count(unsigned long ip, unsigned long parent_ip,
386 struct trace_array *tr, struct ftrace_probe_ops *ops, 387 struct trace_array *tr, struct ftrace_probe_ops *ops,
387 void **data) 388 void *data)
388{ 389{
389 struct ftrace_func_mapper *mapper = ops->private_data; 390 struct ftrace_func_mapper *mapper = data;
390 long *count; 391 long *count;
391 long old_count; 392 long old_count;
392 long new_count; 393 long new_count;
@@ -423,9 +424,10 @@ ftrace_stacktrace_count(unsigned long ip, unsigned long parent_ip,
423 } while (new_count != old_count); 424 } while (new_count != old_count);
424} 425}
425 426
426static int update_count(struct ftrace_probe_ops *ops, unsigned long ip) 427static int update_count(struct ftrace_probe_ops *ops, unsigned long ip,
428 void *data)
427{ 429{
428 struct ftrace_func_mapper *mapper = ops->private_data; 430 struct ftrace_func_mapper *mapper = data;
429 long *count = NULL; 431 long *count = NULL;
430 432
431 if (mapper) 433 if (mapper)
@@ -443,9 +445,9 @@ static int update_count(struct ftrace_probe_ops *ops, unsigned long ip)
443static void 445static void
444ftrace_dump_probe(unsigned long ip, unsigned long parent_ip, 446ftrace_dump_probe(unsigned long ip, unsigned long parent_ip,
445 struct trace_array *tr, struct ftrace_probe_ops *ops, 447 struct trace_array *tr, struct ftrace_probe_ops *ops,
446 void **data) 448 void *data)
447{ 449{
448 if (update_count(ops, ip)) 450 if (update_count(ops, ip, data))
449 ftrace_dump(DUMP_ALL); 451 ftrace_dump(DUMP_ALL);
450} 452}
451 453
@@ -453,17 +455,18 @@ ftrace_dump_probe(unsigned long ip, unsigned long parent_ip,
453static void 455static void
454ftrace_cpudump_probe(unsigned long ip, unsigned long parent_ip, 456ftrace_cpudump_probe(unsigned long ip, unsigned long parent_ip,
455 struct trace_array *tr, struct ftrace_probe_ops *ops, 457 struct trace_array *tr, struct ftrace_probe_ops *ops,
456 void **data) 458 void *data)
457{ 459{
458 if (update_count(ops, ip)) 460 if (update_count(ops, ip, data))
459 ftrace_dump(DUMP_ORIG); 461 ftrace_dump(DUMP_ORIG);
460} 462}
461 463
462static int 464static int
463ftrace_probe_print(const char *name, struct seq_file *m, 465ftrace_probe_print(const char *name, struct seq_file *m,
464 unsigned long ip, struct ftrace_probe_ops *ops) 466 unsigned long ip, struct ftrace_probe_ops *ops,
467 void *data)
465{ 468{
466 struct ftrace_func_mapper *mapper = ops->private_data; 469 struct ftrace_func_mapper *mapper = data;
467 long *count = NULL; 470 long *count = NULL;
468 471
469 seq_printf(m, "%ps:%s", (void *)ip, name); 472 seq_printf(m, "%ps:%s", (void *)ip, name);
@@ -484,52 +487,64 @@ ftrace_traceon_print(struct seq_file *m, unsigned long ip,
484 struct ftrace_probe_ops *ops, 487 struct ftrace_probe_ops *ops,
485 void *data) 488 void *data)
486{ 489{
487 return ftrace_probe_print("traceon", m, ip, ops); 490 return ftrace_probe_print("traceon", m, ip, ops, data);
488} 491}
489 492
490static int 493static int
491ftrace_traceoff_print(struct seq_file *m, unsigned long ip, 494ftrace_traceoff_print(struct seq_file *m, unsigned long ip,
492 struct ftrace_probe_ops *ops, void *data) 495 struct ftrace_probe_ops *ops, void *data)
493{ 496{
494 return ftrace_probe_print("traceoff", m, ip, ops); 497 return ftrace_probe_print("traceoff", m, ip, ops, data);
495} 498}
496 499
497static int 500static int
498ftrace_stacktrace_print(struct seq_file *m, unsigned long ip, 501ftrace_stacktrace_print(struct seq_file *m, unsigned long ip,
499 struct ftrace_probe_ops *ops, void *data) 502 struct ftrace_probe_ops *ops, void *data)
500{ 503{
501 return ftrace_probe_print("stacktrace", m, ip, ops); 504 return ftrace_probe_print("stacktrace", m, ip, ops, data);
502} 505}
503 506
504static int 507static int
505ftrace_dump_print(struct seq_file *m, unsigned long ip, 508ftrace_dump_print(struct seq_file *m, unsigned long ip,
506 struct ftrace_probe_ops *ops, void *data) 509 struct ftrace_probe_ops *ops, void *data)
507{ 510{
508 return ftrace_probe_print("dump", m, ip, ops); 511 return ftrace_probe_print("dump", m, ip, ops, data);
509} 512}
510 513
511static int 514static int
512ftrace_cpudump_print(struct seq_file *m, unsigned long ip, 515ftrace_cpudump_print(struct seq_file *m, unsigned long ip,
513 struct ftrace_probe_ops *ops, void *data) 516 struct ftrace_probe_ops *ops, void *data)
514{ 517{
515 return ftrace_probe_print("cpudump", m, ip, ops); 518 return ftrace_probe_print("cpudump", m, ip, ops, data);
516} 519}
517 520
518 521
519static int 522static int
520ftrace_count_init(struct ftrace_probe_ops *ops, struct trace_array *tr, 523ftrace_count_init(struct ftrace_probe_ops *ops, struct trace_array *tr,
521 unsigned long ip, void *data) 524 unsigned long ip, void *init_data, void **data)
522{ 525{
523 struct ftrace_func_mapper *mapper = ops->private_data; 526 struct ftrace_func_mapper *mapper = *data;
527
528 if (!mapper) {
529 mapper = allocate_ftrace_func_mapper();
530 if (!mapper)
531 return -ENOMEM;
532 *data = mapper;
533 }
524 534
525 return ftrace_func_mapper_add_ip(mapper, ip, data); 535 return ftrace_func_mapper_add_ip(mapper, ip, init_data);
526} 536}
527 537
528static void 538static void
529ftrace_count_free(struct ftrace_probe_ops *ops, struct trace_array *tr, 539ftrace_count_free(struct ftrace_probe_ops *ops, struct trace_array *tr,
530 unsigned long ip, void **_data) 540 unsigned long ip, void *data)
531{ 541{
532 struct ftrace_func_mapper *mapper = ops->private_data; 542 struct ftrace_func_mapper *mapper = data;
543
544 if (!ip) {
545 free_ftrace_func_mapper(mapper, NULL);
546 return;
547 }
533 548
534 ftrace_func_mapper_remove_ip(mapper, ip); 549 ftrace_func_mapper_remove_ip(mapper, ip);
535} 550}
@@ -607,12 +622,6 @@ ftrace_trace_probe_callback(struct trace_array *tr,
607 if (!strlen(number)) 622 if (!strlen(number))
608 goto out_reg; 623 goto out_reg;
609 624
610 if (!ops->private_data) {
611 ops->private_data = allocate_ftrace_func_mapper();
612 if (!ops->private_data)
613 return -ENOMEM;
614 }
615
616 /* 625 /*
617 * We use the callback data field (which is a pointer) 626 * We use the callback data field (which is a pointer)
618 * as our counter. 627 * as our counter.