Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d244b6bd authored by Steven Rostedt's avatar Steven Rostedt Committed by Steven Rostedt
Browse files

Merge branch 'tip/perf/urgent-3' of...

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

Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parents da5cabf8 1aa54bca
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3846,6 +3846,9 @@ int ring_buffer_read_page(struct ring_buffer *buffer,
			rpos = reader->read;
			pos += size;

			if (rpos >= commit)
				break;

			event = rb_reader_event(cpu_buffer);
			size = rb_event_length(event);
		} while (len > size);
+8 −3
Original line number Diff line number Diff line
@@ -3463,6 +3463,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
					size_t cnt, loff_t *fpos)
{
	char *buf;
	size_t written;

	if (tracing_disabled)
		return -EINVAL;
@@ -3484,11 +3485,15 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
	} else
		buf[cnt] = '\0';

	cnt = mark_printk("%s", buf);
	written = mark_printk("%s", buf);
	kfree(buf);
	*fpos += cnt;
	*fpos += written;

	return cnt;
	/* don't tell userspace we wrote more - it might confuse them */
	if (written > cnt)
		written = cnt;

	return written;
}

static int tracing_clock_show(struct seq_file *m, void *v)
+143 −64
Original line number Diff line number Diff line
@@ -598,11 +598,114 @@ system_enable_write(struct file *filp, const char __user *ubuf, size_t cnt,
	return ret;
}

static void print_event_fields(struct trace_seq *s, struct list_head *head)
enum {
	FORMAT_HEADER		= 1,
	FORMAT_PRINTFMT		= 2,
};

static void *f_next(struct seq_file *m, void *v, loff_t *pos)
{
	struct ftrace_event_call *call = m->private;
	struct ftrace_event_field *field;
	struct list_head *head;

	(*pos)++;

	switch ((unsigned long)v) {
	case FORMAT_HEADER:
		head = &ftrace_common_fields;

		if (unlikely(list_empty(head)))
			return NULL;

		field = list_entry(head->prev, struct ftrace_event_field, link);
		return field;

	case FORMAT_PRINTFMT:
		/* all done */
		return NULL;
	}

	head = trace_get_fields(call);

	/*
	 * To separate common fields from event fields, the
	 * LSB is set on the first event field. Clear it in case.
	 */
	v = (void *)((unsigned long)v & ~1L);

	field = v;
	/*
	 * If this is a common field, and at the end of the list, then
	 * continue with main list.
	 */
	if (field->link.prev == &ftrace_common_fields) {
		if (unlikely(list_empty(head)))
			return NULL;
		field = list_entry(head->prev, struct ftrace_event_field, link);
		/* Set the LSB to notify f_show to print an extra newline */
		field = (struct ftrace_event_field *)
			((unsigned long)field | 1);
		return field;
	}

	/* If we are done tell f_show to print the format */
	if (field->link.prev == head)
		return (void *)FORMAT_PRINTFMT;

	field = list_entry(field->link.prev, struct ftrace_event_field, link);

	return field;
}

static void *f_start(struct seq_file *m, loff_t *pos)
{
	loff_t l = 0;
	void *p;

	/* Start by showing the header */
	if (!*pos)
		return (void *)FORMAT_HEADER;

	p = (void *)FORMAT_HEADER;
	do {
		p = f_next(m, p, &l);
	} while (p && l < *pos);

	return p;
}

static int f_show(struct seq_file *m, void *v)
{
	struct ftrace_event_call *call = m->private;
	struct ftrace_event_field *field;
	const char *array_descriptor;

	switch ((unsigned long)v) {
	case FORMAT_HEADER:
		seq_printf(m, "name: %s\n", call->name);
		seq_printf(m, "ID: %d\n", call->event.type);
		seq_printf(m, "format:\n");
		return 0;

	case FORMAT_PRINTFMT:
		seq_printf(m, "\nprint fmt: %s\n",
			   call->print_fmt);
		return 0;
	}

	/*
	 * To separate common fields from event fields, the
	 * LSB is set on the first event field. Clear it and
	 * print a newline if it is set.
	 */
	if ((unsigned long)v & 1) {
		seq_putc(m, '\n');
		v = (void *)((unsigned long)v & ~1L);
	}

	field = v;

	list_for_each_entry_reverse(field, head, link) {
	/*
	 * Smartly shows the array type(except dynamic array).
	 * Normal:
@@ -610,76 +713,50 @@ static void print_event_fields(struct trace_seq *s, struct list_head *head)
	 * If TYPE := TYPE[LEN], it is shown:
	 *	field:TYPE VAR[LEN]
	 */
		const char *array_descriptor = strchr(field->type, '[');
	array_descriptor = strchr(field->type, '[');

	if (!strncmp(field->type, "__data_loc", 10))
		array_descriptor = NULL;

		if (!array_descriptor) {
			trace_seq_printf(s, "\tfield:%s %s;\toffset:%u;"
					"\tsize:%u;\tsigned:%d;\n",
	if (!array_descriptor)
		seq_printf(m, "\tfield:%s %s;\toffset:%u;\tsize:%u;\tsigned:%d;\n",
			   field->type, field->name, field->offset,
			   field->size, !!field->is_signed);
		} else {
			trace_seq_printf(s, "\tfield:%.*s %s%s;\toffset:%u;"
					"\tsize:%u;\tsigned:%d;\n",
	else
		seq_printf(m, "\tfield:%.*s %s%s;\toffset:%u;\tsize:%u;\tsigned:%d;\n",
			   (int)(array_descriptor - field->type),
			   field->type, field->name,
			   array_descriptor, field->offset,
			   field->size, !!field->is_signed);
		}
	}
}

static ssize_t
event_format_read(struct file *filp, char __user *ubuf, size_t cnt,
		  loff_t *ppos)
{
	struct ftrace_event_call *call = filp->private_data;
	struct list_head *head;
	struct trace_seq *s;
	char *buf;
	int r;

	if (*ppos)
	return 0;
}

	s = kmalloc(sizeof(*s), GFP_KERNEL);
	if (!s)
		return -ENOMEM;

	trace_seq_init(s);

	trace_seq_printf(s, "name: %s\n", call->name);
	trace_seq_printf(s, "ID: %d\n", call->event.type);
	trace_seq_printf(s, "format:\n");

	/* print common fields */
	print_event_fields(s, &ftrace_common_fields);
static void f_stop(struct seq_file *m, void *p)
{
}

	trace_seq_putc(s, '\n');
static const struct seq_operations trace_format_seq_ops = {
	.start		= f_start,
	.next		= f_next,
	.stop		= f_stop,
	.show		= f_show,
};

	/* print event specific fields */
	head = trace_get_fields(call);
	print_event_fields(s, head);
static int trace_format_open(struct inode *inode, struct file *file)
{
	struct ftrace_event_call *call = inode->i_private;
	struct seq_file *m;
	int ret;

	r = trace_seq_printf(s, "\nprint fmt: %s\n", call->print_fmt);
	ret = seq_open(file, &trace_format_seq_ops);
	if (ret < 0)
		return ret;

	if (!r) {
		/*
		 * ug!  The format output is bigger than a PAGE!!
		 */
		buf = "FORMAT TOO BIG\n";
		r = simple_read_from_buffer(ubuf, cnt, ppos,
					      buf, strlen(buf));
		goto out;
	}
	m = file->private_data;
	m->private = call;

	r = simple_read_from_buffer(ubuf, cnt, ppos,
				    s->buffer, s->len);
 out:
	kfree(s);
	return r;
	return 0;
}

static ssize_t
@@ -877,8 +954,10 @@ static const struct file_operations ftrace_enable_fops = {
};

static const struct file_operations ftrace_event_format_fops = {
	.open = tracing_open_generic,
	.read = event_format_read,
	.open = trace_format_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = seq_release,
};

static const struct file_operations ftrace_event_id_fops = {
+9 −1
Original line number Diff line number Diff line
@@ -507,7 +507,15 @@ get_return_for_leaf(struct trace_iterator *iter,
			 * if the output fails.
			 */
			data->ent = *curr;
			/*
			 * If the next event is not a return type, then
			 * we only care about what type it is. Otherwise we can
			 * safely copy the entire event.
			 */
			if (next->ent.type == TRACE_GRAPH_RET)
				data->ret = *next;
			else
				data->ret.ent.type = next->ent.type;
		}
	}

+6 −1
Original line number Diff line number Diff line
@@ -159,6 +159,7 @@ my $section_regex; # Find the start of a section
my $function_regex;	# Find the name of a function
			#    (return offset and func name)
my $mcount_regex;	# Find the call site to mcount (return offset)
my $mcount_adjust;	# Address adjustment to mcount offset
my $alignment;		# The .align value to use for $mcount_section
my $section_type;	# Section header plus possible alignment command
my $can_use_local = 0; 	# If we can use local function references
@@ -213,6 +214,7 @@ $section_regex = "Disassembly of section\\s+(\\S+):";
$function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
$section_type = '@progbits';
$mcount_adjust = 0;
$type = ".long";

if ($arch eq "x86_64") {
@@ -351,6 +353,9 @@ if ($arch eq "x86_64") {
} elsif ($arch eq "microblaze") {
    # Microblaze calls '_mcount' instead of plain 'mcount'.
    $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$";
} elsif ($arch eq "blackfin") {
    $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s__mcount\$";
    $mcount_adjust = -4;
} else {
    die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
}
@@ -511,7 +516,7 @@ while (<IN>) {
    }
    # is this a call site to mcount? If so, record it to print later
    if ($text_found && /$mcount_regex/) {
	push(@offsets, hex $1);
	push(@offsets, (hex $1) + $mcount_adjust);
    }
}