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
38463846 rpos = reader->read;
38473847 pos += size;
38483848
3849+ if (rpos >= commit)
3850+ break;
3851+
38493852 event = rb_reader_event(cpu_buffer);
38503853 size = rb_event_length(event);
38513854 } 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
34633463 size_t cnt, loff_t *fpos)
34643464 {
34653465 char *buf;
3466+ size_t written;
34663467
34673468 if (tracing_disabled)
34683469 return -EINVAL;
@@ -3484,11 +3485,15 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, · 15 unmodified lines
34843485 } else
34853486 buf[cnt] = '\0';
34863487
3487− cnt = mark_printk("%s", buf);
3488+ written = mark_printk("%s", buf);
34883489 kfree(buf);
3489− *fpos += cnt;
3490+ *fpos += written;
34903491
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;
34923497 }
34933498
34943499 static 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
598598 return ret;
599599 }
600600
601−static void print_event_fields(struct trace_seq *s, struct list_head *head)
601+enum {
602+ FORMAT_HEADER = 1,
603+ FORMAT_PRINTFMT = 2,
604+};
605+
606+static void *f_next(struct seq_file *m, void *v, loff_t *pos)
602607 {
608+ struct ftrace_event_call *call = m->private;
603609 struct ftrace_event_field *field;
610+ struct list_head *head;
604611
605− list_for_each_entry_reverse(field, head, link) {
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, '[');
612+ (*pos)++;
614613
615− if (!strncmp(field->type, "__data_loc", 10))
616− array_descriptor = NULL;
614+ switch ((unsigned long)v) {
615+ case FORMAT_HEADER:
616+ head = &ftrace_common_fields;
617617
618− if (!array_descriptor) {
619− trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;"
620− "\tsize:%u;\tsigned:%d;\n",
621− field->type, field->name, field->offset,
622− field->size, !!field->is_signed);
623− } else {
624− trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;"
625− "\tsize:%u;\tsigned:%d;\n",
626− (int)(array_descriptor - field->type),
627− field->type, field->name,
628− array_descriptor, field->offset,
629− field->size, !!field->is_signed);
630− }
618+ if (unlikely(list_empty(head)))
619+ return NULL;
620+
621+ field = list_entry(head->prev, struct ftrace_event_field, link);
622+ return field;
623+
624+ case FORMAT_PRINTFMT:
625+ /* all done */
626+ return NULL;
627+ }
628+
629+ head = trace_get_fields(call);
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;
631650 }
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;
632659 }
633660
634−static ssize_t
635−event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
636− loff_t *ppos)
661+static void *f_start(struct seq_file *m, loff_t *pos)
637662 {
638− struct ftrace_event_call *call = filp->private_data;
639− struct list_head *head;
640− struct trace_seq *s;
641− char *buf;
642− int r;
663+ loff_t l = 0;
664+ void *p;
643665
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+
678+static 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");
645689 return 0;
646690
647− s = kmalloc(sizeof(*s), GFP_KERNEL);
648− if (!s)
649− return -ENOMEM;
691+ case FORMAT_PRINTFMT:
692+ seq_printf(m, "\nprint fmt: %s\n",
693+ call->print_fmt);
694+ return 0;
695+ }
650696
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+ }
652706
653− trace_seq_printf(s, "name: %s\n", call->name);
654− trace_seq_printf(s, "ID: %d\n", call->event.type);
655− trace_seq_printf(s, "format:\n");
707+ field = v;
656708
657− /* print common fields */
658− print_event_fields(s, &ftrace_common_fields);
709+ /*
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, '[');
659717
660− trace_seq_putc(s, '\n');
718+ if (!strncmp(field->type, "__data_loc", 10))
719+ array_descriptor = NULL;
661720
662− /* print event specific fields */
663− head = trace_get_fields(call);
664− print_event_fields(s, head);
721+ if (!array_descriptor)
722+ seq_printf(m, "\tfield:%s %s;\toffset:%u;\tsize:%u;\tsigned:%d;\n",
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);
665731
666− r = trace_seq_printf(s, "\nprint fmt: %s\n", call->print_fmt);
732+ return 0;
733+}
667734
668− if (!r) {
669− /*
670− * ug! The format output is bigger than a PAGE!!
671− */
672− buf = "FORMAT TOO BIG\n";
673− r = simple_read_from_buffer(ubuf, cnt, ppos,
674− buf, strlen(buf));
675− goto out;
676− }
735+static void f_stop(struct seq_file *m, void *p)
736+{
737+}
677738
678− r = simple_read_from_buffer(ubuf, cnt, ppos,
679− s->buffer, s->len);
680− out:
681− kfree(s);
682− return r;
739+static const struct seq_operations trace_format_seq_ops = {
740+ .start = f_start,
741+ .next = f_next,
742+ .stop = f_stop,
743+ .show = f_show,
744+};
745+
746+static 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;
683760 }
684761
685762 static ssize_t
@@ -877,8 +954,10 @@ static const struct file_operations ftrace_enable_fops = { · 191 unmodified lines
877954 };
878955
879956 static const struct file_operations ftrace_event_format_fops = {
880− .open = tracing_open_generic,
881− .read = event_format_read,
957+ .open = trace_format_open,
958+ .read = seq_read,
959+ .llseek = seq_lseek,
960+ .release = seq_release,
882961 };
883962
884963 static 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
507507 * if the output fails.
508508 */
509509 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;
511519 }
512520 }
513521
scripts/recordmcount.pl+6−1
@@ -159,6 +159,7 @@ my $section_regex; # Find the start of a section · 158 unmodified lines
159159 my $function_regex; # Find the name of a function
160160 # (return offset and func name)
161161 my $mcount_regex; # Find the call site to mcount (return offset)
162+my $mcount_adjust; # Address adjustment to mcount offset
162163 my $alignment; # The .align value to use for $mcount_section
163164 my $section_type; # Section header plus possible alignment command
164165 my $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
213214 $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
214215 $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
215216 $section_type = '@progbits';
217+$mcount_adjust = 0;
216218 $type = ".long";
217219
218220 if ($arch eq "x86_64") {
@@ -351,6 +353,9 @@ if ($arch eq "x86_64") { · 132 unmodified lines
351353 } elsif ($arch eq "microblaze") {
352354 # Microblaze calls '_mcount' instead of plain 'mcount'.
353355 $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;
354359 } else {
355360 die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
356361 }
@@ -511,7 +516,7 @@ while (<IN>) { · 154 unmodified lines
511516 }
512517 # is this a call site to mcount? If so, record it to print later
513518 if ($text_found && /$mcount_regex/) {
514− push(@offsets, hex $1);
519+ push(@offsets, (hex $1) + $mcount_adjust);
515520 }
516521 }
517522