trace_functions_graph.c 17.9 KB
Newer Older
1 2 3
/*
 *
 * Function graph tracer.
4
 * Copyright (c) 2008-2009 Frederic Weisbecker <fweisbec@gmail.com>
5 6 7 8 9 10 11 12 13 14
 * Mostly borrowed from function tracer which
 * is Copyright (c) Steven Rostedt <srostedt@redhat.com>
 *
 */
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
#include <linux/fs.h>

#include "trace.h"
15
#include "trace_output.h"
16

17
#define TRACE_GRAPH_INDENT	2
18

19
/* Flag options */
20
#define TRACE_GRAPH_PRINT_OVERRUN	0x1
21 22
#define TRACE_GRAPH_PRINT_CPU		0x2
#define TRACE_GRAPH_PRINT_OVERHEAD	0x4
23
#define TRACE_GRAPH_PRINT_PROC		0x8
24 25
#define TRACE_GRAPH_PRINT_DURATION	0x10
#define TRACE_GRAPH_PRINT_ABS_TIME	0X20
26

27
static struct tracer_opt trace_opts[] = {
28
	/* Display overruns? (for self-debug purpose) */
29 30 31 32 33
	{ TRACER_OPT(funcgraph-overrun, TRACE_GRAPH_PRINT_OVERRUN) },
	/* Display CPU ? */
	{ TRACER_OPT(funcgraph-cpu, TRACE_GRAPH_PRINT_CPU) },
	/* Display Overhead ? */
	{ TRACER_OPT(funcgraph-overhead, TRACE_GRAPH_PRINT_OVERHEAD) },
34 35
	/* Display proc name/pid */
	{ TRACER_OPT(funcgraph-proc, TRACE_GRAPH_PRINT_PROC) },
36 37 38 39
	/* Display duration of execution */
	{ TRACER_OPT(funcgraph-duration, TRACE_GRAPH_PRINT_DURATION) },
	/* Display absolute time of an entry */
	{ TRACER_OPT(funcgraph-abstime, TRACE_GRAPH_PRINT_ABS_TIME) },
40 41 42 43
	{ } /* Empty entry */
};

static struct tracer_flags tracer_flags = {
44
	/* Don't display overruns and proc by default */
45 46
	.val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD |
	       TRACE_GRAPH_PRINT_DURATION,
47 48 49
	.opts = trace_opts
};

50
/* pid on the last trace processed */
51

52 53 54

static int graph_trace_init(struct trace_array *tr)
{
55
	int ret = register_ftrace_graph(&trace_graph_return,
56
					&trace_graph_entry);
57 58 59 60 61
	if (ret)
		return ret;
	tracing_start_cmdline_record();

	return 0;
62 63 64 65
}

static void graph_trace_reset(struct trace_array *tr)
{
66 67
	tracing_stop_cmdline_record();
	unregister_ftrace_graph();
68 69
}

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
static inline int log10_cpu(int nb)
{
	if (nb / 100)
		return 3;
	if (nb / 10)
		return 2;
	return 1;
}

static enum print_line_t
print_graph_cpu(struct trace_seq *s, int cpu)
{
	int i;
	int ret;
	int log10_this = log10_cpu(cpu);
85
	int log10_all = log10_cpu(cpumask_weight(cpu_online_mask));
86 87


88 89 90 91 92 93 94 95 96 97 98 99 100
	/*
	 * Start with a space character - to make it stand out
	 * to the right a bit when trace output is pasted into
	 * email:
	 */
	ret = trace_seq_printf(s, " ");

	/*
	 * Tricky - we space the CPU field according to the max
	 * number of online CPUs. On a 2-cpu system it would take
	 * a maximum of 1 digit - on a 128 cpu system it would
	 * take up to 3 digits:
	 */
101 102 103 104 105 106 107
	for (i = 0; i < log10_all - log10_this; i++) {
		ret = trace_seq_printf(s, " ");
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}
	ret = trace_seq_printf(s, "%d) ", cpu);
	if (!ret)
108 109
		return TRACE_TYPE_PARTIAL_LINE;

110 111 112
	return TRACE_TYPE_HANDLED;
}

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
#define TRACE_GRAPH_PROCINFO_LENGTH	14

static enum print_line_t
print_graph_proc(struct trace_seq *s, pid_t pid)
{
	int i;
	int ret;
	int len;
	char comm[8];
	int spaces = 0;
	/* sign + log10(MAX_INT) + '\0' */
	char pid_str[11];

	strncpy(comm, trace_find_cmdline(pid), 7);
	comm[7] = '\0';
	sprintf(pid_str, "%d", pid);

	/* 1 stands for the "-" character */
	len = strlen(comm) + strlen(pid_str) + 1;

	if (len < TRACE_GRAPH_PROCINFO_LENGTH)
		spaces = TRACE_GRAPH_PROCINFO_LENGTH - len;

	/* First spaces to align center */
	for (i = 0; i < spaces / 2; i++) {
		ret = trace_seq_printf(s, " ");
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}

	ret = trace_seq_printf(s, "%s-%s", comm, pid_str);
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

	/* Last spaces to align center */
	for (i = 0; i < spaces - (spaces / 2); i++) {
		ret = trace_seq_printf(s, " ");
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}
	return TRACE_TYPE_HANDLED;
}

156

157
/* If the pid changed since the last trace, output this event */
158
static enum print_line_t
159
verif_pid(struct trace_seq *s, pid_t pid, int cpu, pid_t *last_pids_cpu)
160
{
161
	pid_t prev_pid;
162
	pid_t *last_pid;
163
	int ret;
164

165 166 167 168 169 170
	if (!last_pids_cpu)
		return TRACE_TYPE_HANDLED;

	last_pid = per_cpu_ptr(last_pids_cpu, cpu);

	if (*last_pid == pid)
171
		return TRACE_TYPE_HANDLED;
172

173 174
	prev_pid = *last_pid;
	*last_pid = pid;
175

176 177
	if (prev_pid == -1)
		return TRACE_TYPE_HANDLED;
178 179 180 181 182 183 184 185 186
/*
 * Context-switch trace line:

 ------------------------------------------
 | 1)  migration/0--1  =>  sshd-1755
 ------------------------------------------

 */
	ret = trace_seq_printf(s,
187
		" ------------------------------------------\n");
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
	if (!ret)
		TRACE_TYPE_PARTIAL_LINE;

	ret = print_graph_cpu(s, cpu);
	if (ret == TRACE_TYPE_PARTIAL_LINE)
		TRACE_TYPE_PARTIAL_LINE;

	ret = print_graph_proc(s, prev_pid);
	if (ret == TRACE_TYPE_PARTIAL_LINE)
		TRACE_TYPE_PARTIAL_LINE;

	ret = trace_seq_printf(s, " => ");
	if (!ret)
		TRACE_TYPE_PARTIAL_LINE;

	ret = print_graph_proc(s, pid);
	if (ret == TRACE_TYPE_PARTIAL_LINE)
		TRACE_TYPE_PARTIAL_LINE;

	ret = trace_seq_printf(s,
		"\n ------------------------------------------\n\n");
	if (!ret)
		TRACE_TYPE_PARTIAL_LINE;

212
	return ret;
213 214
}

215 216 217 218 219 220 221 222 223 224 225 226 227
static bool
trace_branch_is_leaf(struct trace_iterator *iter,
		struct ftrace_graph_ent_entry *curr)
{
	struct ring_buffer_iter *ring_iter;
	struct ring_buffer_event *event;
	struct ftrace_graph_ret_entry *next;

	ring_iter = iter->buffer_iter[iter->cpu];

	if (!ring_iter)
		return false;

228
	event = ring_buffer_iter_peek(ring_iter, NULL);
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244

	if (!event)
		return false;

	next = ring_buffer_event_data(event);

	if (next->ent.type != TRACE_GRAPH_RET)
		return false;

	if (curr->ent.pid != next->ent.pid ||
			curr->graph_ent.func != next->ret.func)
		return false;

	return true;
}

245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269
/* Signal a overhead of time execution to the output */
static int
print_graph_overhead(unsigned long long duration, struct trace_seq *s)
{
	/* If duration disappear, we don't need anything */
	if (!(tracer_flags.val & TRACE_GRAPH_PRINT_DURATION))
		return 1;

	/* Non nested entry or return */
	if (duration == -1)
		return trace_seq_printf(s, "  ");

	if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERHEAD) {
		/* Duration exceeded 100 msecs */
		if (duration > 100000ULL)
			return trace_seq_printf(s, "! ");

		/* Duration exceeded 10 msecs */
		if (duration > 10000ULL)
			return trace_seq_printf(s, "+ ");
	}

	return trace_seq_printf(s, "  ");
}

270 271
static enum print_line_t
print_graph_irq(struct trace_seq *s, unsigned long addr,
272
		enum trace_type type, int cpu, pid_t pid)
273 274 275 276 277 278 279
{
	int ret;

	if (addr < (unsigned long)__irqentry_text_start ||
		addr >= (unsigned long)__irqentry_text_end)
		return TRACE_TYPE_UNHANDLED;

280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
	/* Cpu */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
		ret = print_graph_cpu(s, cpu);
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;
	}
	/* Proc */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
		ret = print_graph_proc(s, pid);
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;
		ret = trace_seq_printf(s, " | ");
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}
295

296 297 298 299
	/* No overhead */
	ret = print_graph_overhead(-1, s);
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;
300

301 302 303 304 305 306 307 308 309 310 311 312
	if (type == TRACE_GRAPH_ENT)
		ret = trace_seq_printf(s, "==========>");
	else
		ret = trace_seq_printf(s, "<==========");

	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

	/* Don't close the duration column if haven't one */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
		trace_seq_printf(s, " |");
	ret = trace_seq_printf(s, "\n");
313 314 315 316 317

	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;
	return TRACE_TYPE_HANDLED;
}
318

319
static enum print_line_t
320 321 322
print_graph_duration(unsigned long long duration, struct trace_seq *s)
{
	unsigned long nsecs_rem = do_div(duration, 1000);
323 324 325 326 327 328 329 330 331
	/* log10(ULONG_MAX) + '\0' */
	char msecs_str[21];
	char nsecs_str[5];
	int ret, len;
	int i;

	sprintf(msecs_str, "%lu", (unsigned long) duration);

	/* Print msecs */
332
	ret = trace_seq_printf(s, "%s", msecs_str);
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

	len = strlen(msecs_str);

	/* Print nsecs (we don't want to exceed 7 numbers) */
	if (len < 7) {
		snprintf(nsecs_str, 8 - len, "%03lu", nsecs_rem);
		ret = trace_seq_printf(s, ".%s", nsecs_str);
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
		len += strlen(nsecs_str);
	}

	ret = trace_seq_printf(s, " us ");
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

	/* Print remaining spaces to fit the row's width */
	for (i = len; i < 7; i++) {
		ret = trace_seq_printf(s, " ");
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}

	ret = trace_seq_printf(s, "|  ");
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;
	return TRACE_TYPE_HANDLED;

363 364
}

365
static int print_graph_abs_time(u64 t, struct trace_seq *s)
366
{
367
	unsigned long usecs_rem;
368

369 370
	usecs_rem = do_div(t, 1000000000);
	usecs_rem /= 1000;
371

372 373
	return trace_seq_printf(s, "%5lu.%06lu |  ",
			(unsigned long)t, usecs_rem);
374 375 376
}

/* Case of a leaf function on its call entry */
377
static enum print_line_t
378 379
print_graph_entry_leaf(struct trace_iterator *iter,
		struct ftrace_graph_ent_entry *entry, struct trace_seq *s)
380
{
381 382 383 384 385
	struct ftrace_graph_ret_entry *ret_entry;
	struct ftrace_graph_ret *graph_ret;
	struct ring_buffer_event *event;
	struct ftrace_graph_ent *call;
	unsigned long long duration;
386
	int ret;
387
	int i;
388

389 390 391 392 393 394 395
	event = ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
	ret_entry = ring_buffer_event_data(event);
	graph_ret = &ret_entry->ret;
	call = &entry->graph_ent;
	duration = graph_ret->rettime - graph_ret->calltime;

	/* Overhead */
396 397 398
	ret = print_graph_overhead(duration, s);
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;
399 400

	/* Duration */
401 402 403 404 405
	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
		ret = print_graph_duration(duration, s);
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;
	}
406

407 408 409 410 411 412 413 414 415 416 417
	/* Function */
	for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) {
		ret = trace_seq_printf(s, " ");
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}

	ret = seq_print_ip_sym(s, call->func, 0);
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

418
	ret = trace_seq_printf(s, "();\n");
419 420 421 422 423 424 425 426
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

	return TRACE_TYPE_HANDLED;
}

static enum print_line_t
print_graph_entry_nested(struct ftrace_graph_ent_entry *entry,
427
			struct trace_seq *s, pid_t pid, int cpu)
428 429 430 431 432 433
{
	int i;
	int ret;
	struct ftrace_graph_ent *call = &entry->graph_ent;

	/* No overhead */
434 435 436
	ret = print_graph_overhead(-1, s);
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;
437

438 439
	/* No time */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
440 441 442 443 444
		ret = trace_seq_printf(s, "            |  ");
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}

445
	/* Function */
446 447
	for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) {
		ret = trace_seq_printf(s, " ");
448 449
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
450 451 452 453 454 455
	}

	ret = seq_print_ip_sym(s, call->func, 0);
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

456
	ret = trace_seq_printf(s, "() {\n");
457 458 459
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

460 461 462
	return TRACE_TYPE_HANDLED;
}

463 464
static enum print_line_t
print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s,
465
			struct trace_iterator *iter)
466 467
{
	int ret;
468 469
	int cpu = iter->cpu;
	pid_t *last_entry = iter->private;
470
	struct trace_entry *ent = iter->ent;
471
	struct ftrace_graph_ent *call = &field->graph_ent;
472

473
	/* Pid */
474 475 476 477 478 479
	if (verif_pid(s, ent->pid, cpu, last_entry) == TRACE_TYPE_PARTIAL_LINE)
		return TRACE_TYPE_PARTIAL_LINE;

	/* Interrupt */
	ret = print_graph_irq(s, call->func, TRACE_GRAPH_ENT, cpu, ent->pid);
	if (ret == TRACE_TYPE_PARTIAL_LINE)
480 481
		return TRACE_TYPE_PARTIAL_LINE;

482 483 484 485 486 487 488
	/* Absolute time */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
		ret = print_graph_abs_time(iter->ts, s);
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}

489 490 491
	/* Cpu */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
		ret = print_graph_cpu(s, cpu);
492 493 494 495 496 497 498 499 500 501 502
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;
	}

	/* Proc */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
		ret = print_graph_proc(s, ent->pid);
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;

		ret = trace_seq_printf(s, " | ");
503 504 505
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}
506 507 508 509

	if (trace_branch_is_leaf(iter, field))
		return print_graph_entry_leaf(iter, field, s);
	else
510
		return print_graph_entry_nested(field, s, iter->ent->pid, cpu);
511 512 513

}

514 515
static enum print_line_t
print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
516
		   struct trace_entry *ent, struct trace_iterator *iter)
517 518 519
{
	int i;
	int ret;
520 521
	int cpu = iter->cpu;
	pid_t *last_pid = iter->private;
522
	unsigned long long duration = trace->rettime - trace->calltime;
523

524
	/* Pid */
525
	if (verif_pid(s, ent->pid, cpu, last_pid) == TRACE_TYPE_PARTIAL_LINE)
526 527
		return TRACE_TYPE_PARTIAL_LINE;

528 529 530 531 532 533 534
	/* Absolute time */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
		ret = print_graph_abs_time(iter->ts, s);
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}

535
	/* Cpu */
536 537
	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
		ret = print_graph_cpu(s, cpu);
538 539 540 541 542 543 544 545 546 547 548
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;
	}

	/* Proc */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
		ret = print_graph_proc(s, ent->pid);
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;

		ret = trace_seq_printf(s, " | ");
549 550 551
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}
552

553
	/* Overhead */
554 555 556
	ret = print_graph_overhead(duration, s);
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;
557 558

	/* Duration */
559 560 561 562 563
	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
		ret = print_graph_duration(duration, s);
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;
	}
564 565

	/* Closing brace */
566 567
	for (i = 0; i < trace->depth * TRACE_GRAPH_INDENT; i++) {
		ret = trace_seq_printf(s, " ");
568 569
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
570 571
	}

572
	ret = trace_seq_printf(s, "}\n");
573 574
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;
575

576
	/* Overrun */
577 578 579
	if (tracer_flags.val & TRACE_GRAPH_PRINT_OVERRUN) {
		ret = trace_seq_printf(s, " (Overruns: %lu)\n",
					trace->overrun);
580 581
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
582
	}
583 584 585 586 587

	ret = print_graph_irq(s, trace->func, TRACE_GRAPH_RET, cpu, ent->pid);
	if (ret == TRACE_TYPE_PARTIAL_LINE)
		return TRACE_TYPE_PARTIAL_LINE;

588 589 590
	return TRACE_TYPE_HANDLED;
}

591 592 593 594 595 596
static enum print_line_t
print_graph_comment(struct print_entry *trace, struct trace_seq *s,
		   struct trace_entry *ent, struct trace_iterator *iter)
{
	int i;
	int ret;
597 598 599 600 601 602 603 604 605
	int cpu = iter->cpu;
	pid_t *last_pid = iter->private;

	/* Absolute time */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME) {
		ret = print_graph_abs_time(iter->ts, s);
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}
606 607

	/* Pid */
608
	if (verif_pid(s, ent->pid, cpu, last_pid) == TRACE_TYPE_PARTIAL_LINE)
609 610 611 612
		return TRACE_TYPE_PARTIAL_LINE;

	/* Cpu */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU) {
613
		ret = print_graph_cpu(s, cpu);
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;
	}

	/* Proc */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) {
		ret = print_graph_proc(s, ent->pid);
		if (ret == TRACE_TYPE_PARTIAL_LINE)
			return TRACE_TYPE_PARTIAL_LINE;

		ret = trace_seq_printf(s, " | ");
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}

	/* No overhead */
630 631 632 633 634 635 636
	ret = print_graph_overhead(-1, s);
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

	/* No time */
	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) {
		ret = trace_seq_printf(s, "            |  ");
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
		if (!ret)
			return TRACE_TYPE_PARTIAL_LINE;
	}

	/* Indentation */
	if (trace->depth > 0)
		for (i = 0; i < (trace->depth + 1) * TRACE_GRAPH_INDENT; i++) {
			ret = trace_seq_printf(s, " ");
			if (!ret)
				return TRACE_TYPE_PARTIAL_LINE;
		}

	/* The comment */
	ret = trace_seq_printf(s, "/* %s", trace->buf);
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

654 655 656 657 658 659
	/* Strip ending newline */
	if (s->buffer[s->len - 1] == '\n') {
		s->buffer[s->len - 1] = '\0';
		s->len--;
	}

660 661 662 663 664 665 666 667
	ret = trace_seq_printf(s, " */\n");
	if (!ret)
		return TRACE_TYPE_PARTIAL_LINE;

	return TRACE_TYPE_HANDLED;
}


668 669 670 671 672
enum print_line_t
print_graph_function(struct trace_iterator *iter)
{
	struct trace_seq *s = &iter->seq;
	struct trace_entry *entry = iter->ent;
673

674 675 676 677
	switch (entry->type) {
	case TRACE_GRAPH_ENT: {
		struct ftrace_graph_ent_entry *field;
		trace_assign_type(field, entry);
678
		return print_graph_entry(field, s, iter);
679 680 681 682
	}
	case TRACE_GRAPH_RET: {
		struct ftrace_graph_ret_entry *field;
		trace_assign_type(field, entry);
683
		return print_graph_return(&field->ret, s, entry, iter);
684
	}
685 686 687 688 689
	case TRACE_PRINT: {
		struct print_entry *field;
		trace_assign_type(field, entry);
		return print_graph_comment(field, s, entry, iter);
	}
690 691
	default:
		return TRACE_TYPE_UNHANDLED;
692 693 694
	}
}

695 696 697 698
static void print_graph_headers(struct seq_file *s)
{
	/* 1st line */
	seq_printf(s, "# ");
699 700
	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
		seq_printf(s, "     TIME       ");
701
	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
702
		seq_printf(s, "CPU");
703
	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
704 705 706 707
		seq_printf(s, "  TASK/PID      ");
	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
		seq_printf(s, "  DURATION   ");
	seq_printf(s, "               FUNCTION CALLS\n");
708 709 710

	/* 2nd line */
	seq_printf(s, "# ");
711 712
	if (tracer_flags.val & TRACE_GRAPH_PRINT_ABS_TIME)
		seq_printf(s, "      |         ");
713
	if (tracer_flags.val & TRACE_GRAPH_PRINT_CPU)
714
		seq_printf(s, "|  ");
715
	if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
716 717 718 719
		seq_printf(s, "  |    |        ");
	if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
		seq_printf(s, "   |   |      ");
	seq_printf(s, "               |   |   |   |\n");
720
}
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743

static void graph_trace_open(struct trace_iterator *iter)
{
	/* pid on the last trace processed */
	pid_t *last_pid = alloc_percpu(pid_t);
	int cpu;

	if (!last_pid)
		pr_warning("function graph tracer: not enough memory\n");
	else
		for_each_possible_cpu(cpu) {
			pid_t *pid = per_cpu_ptr(last_pid, cpu);
			*pid = -1;
		}

	iter->private = last_pid;
}

static void graph_trace_close(struct trace_iterator *iter)
{
	percpu_free(iter->private);
}

744
static struct tracer graph_trace __read_mostly = {
745
	.name	     	= "function_graph",
746 747
	.open		= graph_trace_open,
	.close		= graph_trace_close,
748 749 750 751
	.init	     	= graph_trace_init,
	.reset	     	= graph_trace_reset,
	.print_line	= print_graph_function,
	.print_header	= print_graph_headers,
752
	.flags		= &tracer_flags,
753 754 755
#ifdef CONFIG_FTRACE_SELFTEST
	.selftest	= trace_selftest_startup_function_graph,
#endif
756 757 758 759 760 761 762 763
};

static __init int init_graph_trace(void)
{
	return register_tracer(&graph_trace);
}

device_initcall(init_graph_trace);