History

Merge branch 'tip/perf/urgent-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into trace/tip/perf/urgent-4

Conflicts: kernel/trace/trace_events.c

Steven Rostedt committed 16 years ago

Commit d244b6b2 parents da5cabf 1aa54bc5 files · +169 −69Browse files

Unified · Split

5 files
  1. kernel/trace/ring_buffer.c +3 −0
  2. kernel/trace/trace.c +8 −3
  3. kernel/trace/trace_events.c +143 −64
  4. kernel/trace/trace_functions_graph.c +9 −1
  5. scripts/recordmcount.pl +6 −1
kernel/trace/ring_buffer.c+3−0
@@ -3846,6 +3846,9 @@ int ring_buffer_read_page(struct ring_buffer *buffer, · 3845 unmodified lines
3846 rpos = reader->read;3846 rpos = reader->read;
3847 pos += size;3847 pos += size;
3848 3848
3849 if (rpos >= commit)
3850 break;
3851
3849 event = rb_reader_event(cpu_buffer);3852 event = rb_reader_event(cpu_buffer);
3850 size = rb_event_length(event);3853 size = rb_event_length(event);
3851 } while (len > size);3854 } while (len > size);
kernel/trace/trace.c+8−3
@@ -3463,6 +3463,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, · 3462 unmodified lines
3463 size_t cnt, loff_t *fpos)3463 size_t cnt, loff_t *fpos)
3464{3464{
3465 char *buf;3465 char *buf;
3466 size_t written;
3466 3467
3467 if (tracing_disabled)3468 if (tracing_disabled)
3468 return -EINVAL;3469 return -EINVAL;
@@ -3484,11 +3485,15 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, · 15 unmodified lines
3484 } else3485 } else
3485 buf[cnt] = '\0';3486 buf[cnt] = '\0';
3486 3487
3487 cnt = mark_printk("%s", buf);3488 written = mark_printk("%s", buf);
3488 kfree(buf);3489 kfree(buf);
3489 *fpos += cnt;3490 *fpos += written;
3490 3491
3491 return cnt;3492 /* don't tell userspace we wrote more - it might confuse them */
3493 if (written > cnt)
3494 written = cnt;
3495
3496 return written;
3492}3497}
3493 3498
3494static int tracing_clock_show(struct seq_file *m, void *v)3499static int tracing_clock_show(struct seq_file *m, void *v)
kernel/trace/trace_events.c+143−64
@@ -598,88 +598,165 @@ out: · 597 unmodified lines
598 return ret;598 return ret;
599}599}
600 600
601static void print_event_fields(struct trace_seq *s, struct list_head *head)601enum {
602 FORMAT_HEADER = 1,
603 FORMAT_PRINTFMT = 2,
604};
605
606static void *f_next(struct seq_file *m, void *v, loff_t *pos)
602{607{
608 struct ftrace_event_call *call = m->private;
603 struct ftrace_event_field *field;609 struct ftrace_event_field *field;
610 struct list_head *head;
604 611
605 list_for_each_entry_reverse(field, head, link) {612 (*pos)++;
606 /*
607 * Smartly shows the array type(except dynamic array).
608 * Normal:
609 * field:TYPE VAR
610 * If TYPE := TYPE[LEN], it is shown:
611 * field:TYPE VAR[LEN]
612 */
613 const char *array_descriptor = strchr(field->type, '[');
614 613
615 if (!strncmp(field->type, "__data_loc", 10))614 switch ((unsigned long)v) {
616 array_descriptor = NULL;615 case FORMAT_HEADER:
616 head = &ftrace_common_fields;
617 617
618 if (!array_descriptor) {618 if (unlikely(list_empty(head)))
619 trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;"619 return NULL;
620 "\tsize:%u;\tsigned:%d;\n",620
621 field->type, field->name, field->offset,621 field = list_entry(head->prev, struct ftrace_event_field, link);
622 field->size, !!field->is_signed);622 return field;
623 } else {623
624 trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;"624 case FORMAT_PRINTFMT:
625 "\tsize:%u;\tsigned:%d;\n",625 /* all done */
626 (int)(array_descriptor - field->type),626 return NULL;
627 field->type, field->name,627 }
628 array_descriptor, field->offset,628
629 field->size, !!field->is_signed);629 head = trace_get_fields(call);
630 }630
631 /*
632 * To separate common fields from event fields, the
633 * LSB is set on the first event field. Clear it in case.
634 */
635 v = (void *)((unsigned long)v & ~1L);
636
637 field = v;
638 /*
639 * If this is a common field, and at the end of the list, then
640 * continue with main list.
641 */
642 if (field->link.prev == &ftrace_common_fields) {
643 if (unlikely(list_empty(head)))
644 return NULL;
645 field = list_entry(head->prev, struct ftrace_event_field, link);
646 /* Set the LSB to notify f_show to print an extra newline */
647 field = (struct ftrace_event_field *)
648 ((unsigned long)field | 1);
649 return field;
631 }650 }
651
652 /* If we are done tell f_show to print the format */
653 if (field->link.prev == head)
654 return (void *)FORMAT_PRINTFMT;
655
656 field = list_entry(field->link.prev, struct ftrace_event_field, link);
657
658 return field;
632}659}
633 660
634static ssize_t661static void *f_start(struct seq_file *m, loff_t *pos)
635event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
636 loff_t *ppos)
637{662{
638 struct ftrace_event_call *call = filp->private_data;663 loff_t l = 0;
639 struct list_head *head;664 void *p;
640 struct trace_seq *s;
641 char *buf;
642 int r;
643 665
644 if (*ppos)666 /* Start by showing the header */
667 if (!*pos)
668 return (void *)FORMAT_HEADER;
669
670 p = (void *)FORMAT_HEADER;
671 do {
672 p = f_next(m, p, &l);
673 } while (p && l < *pos);
674
675 return p;
676}
677
678static int f_show(struct seq_file *m, void *v)
679{
680 struct ftrace_event_call *call = m->private;
681 struct ftrace_event_field *field;
682 const char *array_descriptor;
683
684 switch ((unsigned long)v) {
685 case FORMAT_HEADER:
686 seq_printf(m, "name: %s\n", call->name);
687 seq_printf(m, "ID: %d\n", call->event.type);
688 seq_printf(m, "format:\n");
645 return 0;689 return 0;
646 690
647 s = kmalloc(sizeof(*s), GFP_KERNEL);691 case FORMAT_PRINTFMT:
648 if (!s)692 seq_printf(m, "\nprint fmt: %s\n",
649 return -ENOMEM;693 call->print_fmt);
694 return 0;
695 }
650 696
651 trace_seq_init(s);697 /*
698 * To separate common fields from event fields, the
699 * LSB is set on the first event field. Clear it and
700 * print a newline if it is set.
701 */
702 if ((unsigned long)v & 1) {
703 seq_putc(m, '\n');
704 v = (void *)((unsigned long)v & ~1L);
705 }
652 706
653 trace_seq_printf(s, "name: %s\n", call->name);707 field = v;
654 trace_seq_printf(s, "ID: %d\n", call->event.type);
655 trace_seq_printf(s, "format:\n");
656 708
657 /* print common fields */709 /*
658 print_event_fields(s, &ftrace_common_fields);710 * Smartly shows the array type(except dynamic array).
711 * Normal:
712 * field:TYPE VAR
713 * If TYPE := TYPE[LEN], it is shown:
714 * field:TYPE VAR[LEN]
715 */
716 array_descriptor = strchr(field->type, '[');
659 717
660 trace_seq_putc(s, '\n');718 if (!strncmp(field->type, "__data_loc", 10))
719 array_descriptor = NULL;
661 720
662 /* print event specific fields */721 if (!array_descriptor)
663 head = trace_get_fields(call);722 seq_printf(m, "\tfield:%s %s;\toffset:%u;\tsize:%u;\tsigned:%d;\n",
664 print_event_fields(s, head);723 field->type, field->name, field->offset,
724 field->size, !!field->is_signed);
725 else
726 seq_printf(m, "\tfield:%.*s %s%s;\toffset:%u;\tsize:%u;\tsigned:%d;\n",
727 (int)(array_descriptor - field->type),
728 field->type, field->name,
729 array_descriptor, field->offset,
730 field->size, !!field->is_signed);
665 731
666 r = trace_seq_printf(s, "\nprint fmt: %s\n", call->print_fmt);732 return 0;
733}
667 734
668 if (!r) {735static void f_stop(struct seq_file *m, void *p)
669 /*736{
670 * ug! The format output is bigger than a PAGE!!737}
671 */
672 buf = "FORMAT TOO BIG\n";
673 r = simple_read_from_buffer(ubuf, cnt, ppos,
674 buf, strlen(buf));
675 goto out;
676 }
677 738
678 r = simple_read_from_buffer(ubuf, cnt, ppos,739static const struct seq_operations trace_format_seq_ops = {
679 s->buffer, s->len);740 .start = f_start,
680 out:741 .next = f_next,
681 kfree(s);742 .stop = f_stop,
682 return r;743 .show = f_show,
744};
745
746static int trace_format_open(struct inode *inode, struct file *file)
747{
748 struct ftrace_event_call *call = inode->i_private;
749 struct seq_file *m;
750 int ret;
751
752 ret = seq_open(file, &trace_format_seq_ops);
753 if (ret < 0)
754 return ret;
755
756 m = file->private_data;
757 m->private = call;
758
759 return 0;
683}760}
684 761
685static ssize_t762static ssize_t
@@ -877,8 +954,10 @@ static const struct file_operations ftrace_enable_fops = { · 191 unmodified lines
877};954};
878 955
879static const struct file_operations ftrace_event_format_fops = {956static const struct file_operations ftrace_event_format_fops = {
880 .open = tracing_open_generic,957 .open = trace_format_open,
881 .read = event_format_read,958 .read = seq_read,
959 .llseek = seq_lseek,
960 .release = seq_release,
882};961};
883 962
884static const struct file_operations ftrace_event_id_fops = {963static const struct file_operations ftrace_event_id_fops = {
kernel/trace/trace_functions_graph.c+9−1
@@ -507,7 +507,15 @@ get_return_for_leaf(struct trace_iterator *iter, · 506 unmodified lines
507 * if the output fails.507 * if the output fails.
508 */508 */
509 data->ent = *curr;509 data->ent = *curr;
510 data->ret = *next;510 /*
511 * If the next event is not a return type, then
512 * we only care about what type it is. Otherwise we can
513 * safely copy the entire event.
514 */
515 if (next->ent.type == TRACE_GRAPH_RET)
516 data->ret = *next;
517 else
518 data->ret.ent.type = next->ent.type;
511 }519 }
512 }520 }
513 521
scripts/recordmcount.pl+6−1
@@ -159,6 +159,7 @@ my $section_regex; # Find the start of a section · 158 unmodified lines
159my $function_regex; # Find the name of a function159my $function_regex; # Find the name of a function
160 # (return offset and func name)160 # (return offset and func name)
161my $mcount_regex; # Find the call site to mcount (return offset)161my $mcount_regex; # Find the call site to mcount (return offset)
162my $mcount_adjust; # Address adjustment to mcount offset
162my $alignment; # The .align value to use for $mcount_section163my $alignment; # The .align value to use for $mcount_section
163my $section_type; # Section header plus possible alignment command164my $section_type; # Section header plus possible alignment command
164my $can_use_local = 0; # If we can use local function references165my $can_use_local = 0; # If we can use local function references
@@ -213,6 +214,7 @@ $section_regex = "Disassembly of section\\s+(\\S+):"; · 48 unmodified lines
213$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";214$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
214$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";215$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
215$section_type = '@progbits';216$section_type = '@progbits';
217$mcount_adjust = 0;
216$type = ".long";218$type = ".long";
217 219
218if ($arch eq "x86_64") {220if ($arch eq "x86_64") {
@@ -351,6 +353,9 @@ if ($arch eq "x86_64") { · 132 unmodified lines
351} elsif ($arch eq "microblaze") {353} elsif ($arch eq "microblaze") {
352 # Microblaze calls '_mcount' instead of plain 'mcount'.354 # Microblaze calls '_mcount' instead of plain 'mcount'.
353 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";355 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
356} elsif ($arch eq "blackfin") {
357 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
358 $mcount_adjust = -4;
354} else {359} else {
355 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";360 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
356}361}
@@ -511,7 +516,7 @@ while (<IN>) { · 154 unmodified lines
511 }516 }
512 # is this a call site to mcount? If so, record it to print later517 # is this a call site to mcount? If so, record it to print later
513 if ($text_found && /$mcount_regex/) {518 if ($text_found && /$mcount_regex/) {
514 push(@offsets, hex $1);519 push(@offsets, (hex $1) + $mcount_adjust);
515 }520 }
516}521}
517 522