Patches contributed by Eötvös Lorand University


commit f036be96dd9ce442ffb9ab33e3c165f5178815c0
Author: Ingo Molnar <mingo@elte.hu>
Date:   Thu Feb 5 13:45:43 2009 +0100

    printk: introduce printk_once()
    
    This pattern shows up frequently in the kernel:
    
      static int once = 1;
      ...
    
                    if (once) {
                            once = 0;
                            printk(KERN_ERR "message\n");
                    }
      ...
    
    So add a printk_once() helper macro that reduces this to a single line
    of:
    
                    printk_once(KERN_ERR "message\n");
    
    It works analogously to WARN_ONCE() & friends. (We use a macro not
    an inline because vararg expansion in inlines looks awkward and the
    macro is simple enough.)
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 343df9ef2412..3c183d9864ae 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -242,6 +242,19 @@ extern struct ratelimit_state printk_ratelimit_state;
 extern int printk_ratelimit(void);
 extern bool printk_timed_ratelimit(unsigned long *caller_jiffies,
 				   unsigned int interval_msec);
+
+/*
+ * Print a one-time message (analogous to WARN_ONCE() et al):
+ */
+#define printk_once(x...) ({			\
+	static int __print_once = 1;		\
+						\
+	if (__print_once) {			\
+		__print_once = 0;		\
+		printk(x);			\
+	}					\
+})
+
 #else
 static inline int vprintk(const char *s, va_list args)
 	__attribute__ ((format (printf, 1, 0)));
@@ -253,6 +266,10 @@ static inline int printk_ratelimit(void) { return 0; }
 static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \
 					  unsigned int interval_msec)	\
 		{ return false; }
+
+/* No effect, but we still get type checking even in the !PRINTK case: */
+#define printk_once(x...) printk(x)
+
 #endif
 
 extern int printk_needs_cpu(int cpu);

commit 83895147b702434e6f236deeca75211fd0e3da3a
Merge: a6a95406c676 483b4ee60edb
Author: Ingo Molnar <mingo@elte.hu>
Date:   Thu Feb 5 13:03:28 2009 +0100

    Merge branch 'sched/urgent' into timers/urgent
    
    Merging it here because an upcoming timers/urgent fix relies on
    a change already in sched/urgent and not yet upstream.
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

commit ce70a0b472e06feae3a580ecb3fbef1e1e020a9b
Merge: 939b366977d2 79fb0768fbd3 229c4ef8ae56
Author: Ingo Molnar <mingo@elte.hu>
Date:   Wed Feb 4 20:45:41 2009 +0100

    Merge branches 'tracing/blktrace', 'tracing/ftrace', 'tracing/urgent' and 'linus' into tracing/core

diff --cc kernel/trace/trace.c
index 152d0969adf8,40edef4255c5,17bb88d86ac2..bbdfaa2cbdb9
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@@@ -1352,6 -1378,57 -1704,103 +1379,6 @@@@ print_trace_header(struct seq_file *m, 
   	seq_puts(m, "\n");
   }
   
 --static void
 --lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
 --{
 --	int hardirq, softirq;
 --	char *comm;
 --
 --	comm = trace_find_cmdline(entry->pid);
 --
 --	trace_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid);
 --	trace_seq_printf(s, "%3d", cpu);
 --	trace_seq_printf(s, "%c%c",
 --			(entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
 --			 (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' : '.',
 --			((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
 --
 --	hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
 --	softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
 --	if (hardirq && softirq) {
 --		trace_seq_putc(s, 'H');
 --	} else {
 --		if (hardirq) {
 --			trace_seq_putc(s, 'h');
 --		} else {
 --			if (softirq)
 --				trace_seq_putc(s, 's');
 --			else
 --				trace_seq_putc(s, '.');
 --		}
 --	}
 --
 --	if (entry->preempt_count)
 --		trace_seq_printf(s, "%x", entry->preempt_count);
 --	else
 --		trace_seq_puts(s, ".");
 --}
 --
 --unsigned long preempt_mark_thresh = 100;
 --
 --static void
 --lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
 --		    unsigned long rel_usecs)
 --{
 --	trace_seq_printf(s, " %4lldus", abs_usecs);
 --	if (rel_usecs > preempt_mark_thresh)
 --		trace_seq_puts(s, "!: ");
 --	else if (rel_usecs > 1)
 --		trace_seq_puts(s, "+: ");
 --	else
 --		trace_seq_puts(s, " : ");
  -}
  -
  -static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
  -
  -static int task_state_char(unsigned long state)
  -{
  -	int bit = state ? __ffs(state) + 1 : 0;
  -
  -	return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
  -}
  -
  -/*
  - * The message is supposed to contain an ending newline.
  - * If the printing stops prematurely, try to add a newline of our own.
  - */
  -void trace_seq_print_cont(struct trace_seq *s, struct trace_iterator *iter)
  -{
  -	struct trace_entry *ent;
  -	struct trace_field_cont *cont;
  -	bool ok = true;
  -
  -	ent = peek_next_entry(iter, iter->cpu, NULL);
  -	if (!ent || ent->type != TRACE_CONT) {
  -		trace_seq_putc(s, '\n');
  -		return;
  -	}
  -
  -	do {
  -		cont = (struct trace_field_cont *)ent;
  -		if (ok)
  -			ok = (trace_seq_printf(s, "%s", cont->buf) > 0);
  -
  -		ftrace_disable_cpu();
  -
  -		if (iter->buffer_iter[iter->cpu])
  -			ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
  -		else
  -			ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL);
  -
  -		ftrace_enable_cpu();
  -
  -		ent = peek_next_entry(iter, iter->cpu, NULL);
  -	} while (ent && ent->type == TRACE_CONT);
  -
  -	if (!ok)
  -		trace_seq_putc(s, '\n');
 --}
 --
   static void test_cpu_buff_start(struct trace_iterator *iter)
   {
   	struct trace_seq *s = &iter->seq;
@@@@ -1373,28 -1451,49 -1823,132 +1400,28 @@@@ static enum print_line_t print_lat_fmt(
   {
   	struct trace_seq *s = &iter->seq;
   	unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
 --	struct trace_entry *next_entry;
  -	unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
  +	struct trace_event *event;
 - 	unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
   	struct trace_entry *entry = iter->ent;
 --	unsigned long abs_usecs;
 --	unsigned long rel_usecs;
 --	u64 next_ts;
 --	char *comm;
  -	int S, T;
  -	int i;
  -
  -	if (entry->type == TRACE_CONT)
  -		return TRACE_TYPE_HANDLED;
  +	int ret;
   
   	test_cpu_buff_start(iter);
   
 --	next_entry = find_next_entry(iter, NULL, &next_ts);
 --	if (!next_entry)
 --		next_ts = iter->ts;
 --	rel_usecs = ns2usecs(next_ts - iter->ts);
 --	abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
 --
 --	if (verbose) {
 --		comm = trace_find_cmdline(entry->pid);
 --		trace_seq_printf(s, "%16s %5d %3d %d %08x %08x [%08lx]"
 --				 " %ld.%03ldms (+%ld.%03ldms): ",
 --				 comm,
 --				 entry->pid, cpu, entry->flags,
 --				 entry->preempt_count, trace_idx,
 --				 ns2usecs(iter->ts),
 --				 abs_usecs/1000,
 --				 abs_usecs % 1000, rel_usecs/1000,
 --				 rel_usecs % 1000);
 --	} else {
 --		lat_print_generic(s, entry, cpu);
 --		lat_print_timestamp(s, abs_usecs, rel_usecs);
  -	}
  -	switch (entry->type) {
  -	case TRACE_FN: {
  -		struct ftrace_entry *field;
  -
  -		trace_assign_type(field, entry);
 ++	event = ftrace_find_event(entry->type);
 + 
  -		seq_print_ip_sym(s, field->ip, sym_flags);
  -		trace_seq_puts(s, " (");
  -		seq_print_ip_sym(s, field->parent_ip, sym_flags);
  -		trace_seq_puts(s, ")\n");
  -		break;
  -	}
  -	case TRACE_CTX:
  -	case TRACE_WAKE: {
  -		struct ctx_switch_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		T = task_state_char(field->next_state);
  -		S = task_state_char(field->prev_state);
  -		comm = trace_find_cmdline(field->next_pid);
  -		trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
  -				 field->prev_pid,
  -				 field->prev_prio,
  -				 S, entry->type == TRACE_CTX ? "==>" : "  +",
  -				 field->next_cpu,
  -				 field->next_pid,
  -				 field->next_prio,
  -				 T, comm);
  -		break;
  -	}
  -	case TRACE_SPECIAL: {
  -		struct special_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		trace_seq_printf(s, "# %ld %ld %ld\n",
  -				 field->arg1,
  -				 field->arg2,
  -				 field->arg3);
  -		break;
  -	}
  -	case TRACE_STACK: {
  -		struct stack_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
  -			if (i)
  -				trace_seq_puts(s, " <= ");
  -			seq_print_ip_sym(s, field->caller[i], sym_flags);
  -		}
  -		trace_seq_puts(s, "\n");
  -		break;
  -	}
  -	case TRACE_PRINT: {
  -		struct print_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		seq_print_ip_sym(s, field->ip, sym_flags);
  -		trace_seq_printf(s, ": %s", field->buf);
  -		if (entry->flags & TRACE_FLAG_CONT)
  -			trace_seq_print_cont(s, iter);
  -		break;
 ++	if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
 ++		ret = trace_print_lat_context(iter);
 ++		if (ret)
 ++			return ret;
   	}
  -	case TRACE_BRANCH: {
  -		struct trace_branch *field;
   
 - 	event = ftrace_find_event(entry->type);
  -		trace_assign_type(field, entry);
  -
  -		trace_seq_printf(s, "[%s] %s:%s:%d\n",
  -				 field->correct ? "  ok  " : " MISS ",
  -				 field->func,
  -				 field->file,
  -				 field->line);
  -		break;
  +	if (event && event->latency_trace) {
 - 		ret = event->latency_trace(s, entry, sym_flags);
 ++		ret = event->latency_trace(iter, sym_flags);
  +		if (ret)
  +			return ret;
  +		return TRACE_TYPE_HANDLED;
   	}
  -	case TRACE_USER_STACK: {
  -		struct userstack_entry *field;
   
  -		trace_assign_type(field, entry);
  -
  -		seq_print_userip_objs(field, s, sym_flags);
  -		trace_seq_putc(s, '\n');
  -		break;
  -	}
  -	default:
  -		trace_seq_printf(s, "Unknown type %d\n", entry->type);
  -	}
  +	trace_seq_printf(s, "Unknown type %d\n", entry->type);
   	return TRACE_TYPE_HANDLED;
   }
   
@@@@ -1403,31 -1502,44 -1957,160 +1430,31 @@@@ static enum print_line_t print_trace_fm
   	struct trace_seq *s = &iter->seq;
   	unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
   	struct trace_entry *entry;
  -	unsigned long usec_rem;
  -	unsigned long long t;
  -	unsigned long secs;
  -	char *comm;
  +	struct trace_event *event;
 - 	unsigned long usec_rem;
 - 	unsigned long long t;
 - 	unsigned long secs;
 - 	char *comm;
   	int ret;
  -	int S, T;
  -	int i;
   
   	entry = iter->ent;
   
  -	if (entry->type == TRACE_CONT)
  -		return TRACE_TYPE_HANDLED;
  -
   	test_cpu_buff_start(iter);
   
 --	comm = trace_find_cmdline(iter->ent->pid);
 --
 --	t = ns2usecs(iter->ts);
 --	usec_rem = do_div(t, 1000000ULL);
 --	secs = (unsigned long)t;
  -
  -	ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
  -	if (!ret)
  -		return TRACE_TYPE_PARTIAL_LINE;
  -	ret = trace_seq_printf(s, "[%03d] ", iter->cpu);
  -	if (!ret)
  -		return TRACE_TYPE_PARTIAL_LINE;
  -	ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
  -	if (!ret)
  -		return TRACE_TYPE_PARTIAL_LINE;
  -
  -	switch (entry->type) {
  -	case TRACE_FN: {
  -		struct ftrace_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		ret = seq_print_ip_sym(s, field->ip, sym_flags);
  -		if (!ret)
  -			return TRACE_TYPE_PARTIAL_LINE;
  -		if ((sym_flags & TRACE_ITER_PRINT_PARENT) &&
  -						field->parent_ip) {
  -			ret = trace_seq_printf(s, " <-");
  -			if (!ret)
  -				return TRACE_TYPE_PARTIAL_LINE;
  -			ret = seq_print_ip_sym(s,
  -					       field->parent_ip,
  -					       sym_flags);
  -			if (!ret)
  -				return TRACE_TYPE_PARTIAL_LINE;
  -		}
  -		ret = trace_seq_printf(s, "\n");
  -		if (!ret)
  -			return TRACE_TYPE_PARTIAL_LINE;
  -		break;
  -	}
  -	case TRACE_CTX:
  -	case TRACE_WAKE: {
  -		struct ctx_switch_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		T = task_state_char(field->next_state);
  -		S = task_state_char(field->prev_state);
  -		ret = trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c\n",
  -				       field->prev_pid,
  -				       field->prev_prio,
  -				       S,
  -				       entry->type == TRACE_CTX ? "==>" : "  +",
  -				       field->next_cpu,
  -				       field->next_pid,
  -				       field->next_prio,
  -				       T);
  -		if (!ret)
  -			return TRACE_TYPE_PARTIAL_LINE;
  -		break;
  -	}
  -	case TRACE_SPECIAL: {
  -		struct special_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		ret = trace_seq_printf(s, "# %ld %ld %ld\n",
  -				 field->arg1,
  -				 field->arg2,
  -				 field->arg3);
  -		if (!ret)
  -			return TRACE_TYPE_PARTIAL_LINE;
  -		break;
  -	}
  -	case TRACE_STACK: {
  -		struct stack_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
  -			if (i) {
  -				ret = trace_seq_puts(s, " <= ");
  -				if (!ret)
  -					return TRACE_TYPE_PARTIAL_LINE;
  -			}
  -			ret = seq_print_ip_sym(s, field->caller[i],
  -					       sym_flags);
  -			if (!ret)
  -				return TRACE_TYPE_PARTIAL_LINE;
  -		}
  -		ret = trace_seq_puts(s, "\n");
  -		if (!ret)
  -			return TRACE_TYPE_PARTIAL_LINE;
  -		break;
  -	}
  -	case TRACE_PRINT: {
  -		struct print_entry *field;
  -
  -		trace_assign_type(field, entry);
 ++	event = ftrace_find_event(entry->type);
   
 - 	ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
 - 	if (!ret)
 - 		return TRACE_TYPE_PARTIAL_LINE;
 - 	ret = trace_seq_printf(s, "[%03d] ", iter->cpu);
 - 	if (!ret)
 - 		return TRACE_TYPE_PARTIAL_LINE;
 - 	ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
 - 	if (!ret)
 - 		return TRACE_TYPE_PARTIAL_LINE;
  -		seq_print_ip_sym(s, field->ip, sym_flags);
  -		trace_seq_printf(s, ": %s", field->buf);
  -		if (entry->flags & TRACE_FLAG_CONT)
  -			trace_seq_print_cont(s, iter);
  -		break;
  -	}
  -	case TRACE_GRAPH_RET: {
  -		return print_graph_function(iter);
  -	}
  -	case TRACE_GRAPH_ENT: {
  -		return print_graph_function(iter);
 ++	if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
 ++		ret = trace_print_context(iter);
 ++		if (ret)
 ++			return ret;
 + 	}
  -	case TRACE_BRANCH: {
  -		struct trace_branch *field;
   
 - 	event = ftrace_find_event(entry->type);
  -		trace_assign_type(field, entry);
  -
  -		trace_seq_printf(s, "[%s] %s:%s:%d\n",
  -				 field->correct ? "  ok  " : " MISS ",
  -				 field->func,
  -				 field->file,
  -				 field->line);
  -		break;
  +	if (event && event->trace) {
 - 		ret = event->trace(s, entry, sym_flags);
 ++		ret = event->trace(iter, sym_flags);
  +		if (ret)
  +			return ret;
  +		return TRACE_TYPE_HANDLED;
   	}
  -	case TRACE_USER_STACK: {
  -		struct userstack_entry *field;
  -
  -		trace_assign_type(field, entry);
  +	ret = trace_seq_printf(s, "Unknown type %d\n", entry->type);
  +	if (!ret)
  +		return TRACE_TYPE_PARTIAL_LINE;
   
  -		ret = seq_print_userip_objs(field, s, sym_flags);
  -		if (!ret)
  -			return TRACE_TYPE_PARTIAL_LINE;
  -		ret = trace_seq_putc(s, '\n');
  -		if (!ret)
  -			return TRACE_TYPE_PARTIAL_LINE;
  -		break;
  -	}
  -	}
   	return TRACE_TYPE_HANDLED;
   }
   
@@@@ -1440,24 -1552,22 -2122,75 +1467,24 @@@@ static enum print_line_t print_raw_fmt(
   
   	entry = iter->ent;
   
  -	if (entry->type == TRACE_CONT)
  -		return TRACE_TYPE_HANDLED;
  -
 --	ret = trace_seq_printf(s, "%d %d %llu ",
 --		entry->pid, iter->cpu, iter->ts);
 --	if (!ret)
 --		return TRACE_TYPE_PARTIAL_LINE;
  -
  -	switch (entry->type) {
  -	case TRACE_FN: {
  -		struct ftrace_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		ret = trace_seq_printf(s, "%x %x\n",
  -					field->ip,
  -					field->parent_ip);
 ++	if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
 ++		ret = trace_seq_printf(s, "%d %d %llu ",
 ++			entry->pid, iter->cpu, iter->ts);
 + 		if (!ret)
 + 			return TRACE_TYPE_PARTIAL_LINE;
  -		break;
 + 	}
  -	case TRACE_CTX:
  -	case TRACE_WAKE: {
  -		struct ctx_switch_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		T = task_state_char(field->next_state);
  -		S = entry->type == TRACE_WAKE ? '+' :
  -			task_state_char(field->prev_state);
  -		ret = trace_seq_printf(s, "%d %d %c %d %d %d %c\n",
  -				       field->prev_pid,
  -				       field->prev_prio,
  -				       S,
  -				       field->next_cpu,
  -				       field->next_pid,
  -				       field->next_prio,
  -				       T);
  -		if (!ret)
  -			return TRACE_TYPE_PARTIAL_LINE;
  -		break;
  -	}
  -	case TRACE_SPECIAL:
  -	case TRACE_USER_STACK:
  -	case TRACE_STACK: {
  -		struct special_entry *field;
   
  -		trace_assign_type(field, entry);
  -
  -		ret = trace_seq_printf(s, "# %ld %ld %ld\n",
  -				 field->arg1,
  -				 field->arg2,
  -				 field->arg3);
  -		if (!ret)
  -			return TRACE_TYPE_PARTIAL_LINE;
  -		break;
  +	event = ftrace_find_event(entry->type);
  +	if (event && event->raw) {
 - 		ret = event->raw(s, entry, 0);
 ++		ret = event->raw(iter, 0);
  +		if (ret)
  +			return ret;
  +		return TRACE_TYPE_HANDLED;
   	}
  -	case TRACE_PRINT: {
  -		struct print_entry *field;
  -
  -		trace_assign_type(field, entry);
  +	ret = trace_seq_printf(s, "%d ?\n", entry->type);
  +	if (!ret)
  +		return TRACE_TYPE_PARTIAL_LINE;
   
  -		trace_seq_printf(s, "# %lx %s", field->ip, field->buf);
  -		if (entry->flags & TRACE_FLAG_CONT)
  -			trace_seq_print_cont(s, iter);
  -		break;
  -	}
  -	}
   	return TRACE_TYPE_HANDLED;
   }
   
@@@@ -1470,16 -1580,14 -2216,54 +1497,16 @@@@ static enum print_line_t print_hex_fmt(
   
   	entry = iter->ent;
   
  -	if (entry->type == TRACE_CONT)
  -		return TRACE_TYPE_HANDLED;
  -
 --	SEQ_PUT_HEX_FIELD_RET(s, entry->pid);
 --	SEQ_PUT_HEX_FIELD_RET(s, iter->cpu);
 --	SEQ_PUT_HEX_FIELD_RET(s, iter->ts);
  -
  -	switch (entry->type) {
  -	case TRACE_FN: {
  -		struct ftrace_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		SEQ_PUT_HEX_FIELD_RET(s, field->ip);
  -		SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
  -		break;
  -	}
  -	case TRACE_CTX:
  -	case TRACE_WAKE: {
  -		struct ctx_switch_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		T = task_state_char(field->next_state);
  -		S = entry->type == TRACE_WAKE ? '+' :
  -			task_state_char(field->prev_state);
  -		SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
  -		SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
  -		SEQ_PUT_HEX_FIELD_RET(s, S);
  -		SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
  -		SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
  -		SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
  -		SEQ_PUT_HEX_FIELD_RET(s, T);
  -		break;
 ++	if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
 ++		SEQ_PUT_HEX_FIELD_RET(s, entry->pid);
 ++		SEQ_PUT_HEX_FIELD_RET(s, iter->cpu);
 ++		SEQ_PUT_HEX_FIELD_RET(s, iter->ts);
 + 	}
  -	case TRACE_SPECIAL:
  -	case TRACE_USER_STACK:
  -	case TRACE_STACK: {
  -		struct special_entry *field;
   
  -		trace_assign_type(field, entry);
  +	event = ftrace_find_event(entry->type);
  +	if (event && event->hex)
 - 		event->hex(s, entry, 0);
 ++		event->hex(iter, 0);
   
  -		SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
  -		SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
  -		SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
  -		break;
  -	}
  -	}
   	SEQ_PUT_FIELD_RET(s, newline);
   
   	return TRACE_TYPE_HANDLED;
@@@@ -1509,17 -1617,15 -2295,50 +1536,17 @@@@ static enum print_line_t print_bin_fmt(
   
   	entry = iter->ent;
   
  -	if (entry->type == TRACE_CONT)
  -		return TRACE_TYPE_HANDLED;
  -
 --	SEQ_PUT_FIELD_RET(s, entry->pid);
 --	SEQ_PUT_FIELD_RET(s, entry->cpu);
 --	SEQ_PUT_FIELD_RET(s, iter->ts);
  -
  -	switch (entry->type) {
  -	case TRACE_FN: {
  -		struct ftrace_entry *field;
  -
  -		trace_assign_type(field, entry);
  -
  -		SEQ_PUT_FIELD_RET(s, field->ip);
  -		SEQ_PUT_FIELD_RET(s, field->parent_ip);
  -		break;
 ++	if (trace_flags & TRACE_ITER_CONTEXT_INFO) {
 ++		SEQ_PUT_FIELD_RET(s, entry->pid);
 ++		SEQ_PUT_FIELD_RET(s, entry->cpu);
 ++		SEQ_PUT_FIELD_RET(s, iter->ts);
 + 	}
  -	case TRACE_CTX: {
  -		struct ctx_switch_entry *field;
   
  -		trace_assign_type(field, entry);
  -
  -		SEQ_PUT_FIELD_RET(s, field->prev_pid);
  -		SEQ_PUT_FIELD_RET(s, field->prev_prio);
  -		SEQ_PUT_FIELD_RET(s, field->prev_state);
  -		SEQ_PUT_FIELD_RET(s, field->next_pid);
  -		SEQ_PUT_FIELD_RET(s, field->next_prio);
  -		SEQ_PUT_FIELD_RET(s, field->next_state);
  -		break;
  -	}
  -	case TRACE_SPECIAL:
  -	case TRACE_USER_STACK:
  -	case TRACE_STACK: {
  -		struct special_entry *field;
  +	event = ftrace_find_event(entry->type);
  +	if (event && event->binary)
 - 		event->binary(s, entry, 0);
 ++		event->binary(iter, 0);
   
  -		trace_assign_type(field, entry);
  -
  -		SEQ_PUT_FIELD_RET(s, field->arg1);
  -		SEQ_PUT_FIELD_RET(s, field->arg2);
  -		SEQ_PUT_FIELD_RET(s, field->arg3);
  -		break;
  -	}
  -	}
  -	return 1;
  +	return TRACE_TYPE_HANDLED;
   }
   
   static int trace_empty(struct trace_iterator *iter)
@@@@ -3061,13 -3167,10 -3871,14 +3088,10 @@@@ __init static int tracer_alloc_buffers(
   	trace_init_cmdlines();
   
   	register_tracer(&nop_trace);
+ +	current_trace = &nop_trace;
   #ifdef CONFIG_BOOT_TRACER
   	register_tracer(&boot_tracer);
- -	current_trace = &boot_tracer;
- -	current_trace->init(&global_trace);
- -#else
- -	current_trace = &nop_trace;
   #endif
  -
   	/* All seems OK, enable tracing */
   	tracing_disabled = 0;
   

commit bb960a1e42042e82447a5bc0941b3ab6d614bac3
Merge: 858770619deb 06fc732c33a7
Author: Ingo Molnar <mingo@elte.hu>
Date:   Wed Feb 4 14:54:56 2009 +0100

    Merge branch 'core/xen' into x86/urgent

commit 063f8913afb48842b9329e195d90d2c28e58aacc
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Feb 3 18:02:36 2009 +0100

    x86: document 64-bit and 32-bit function call convention ABI
    
    - also clean up the calling.h file a tiny bit
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/arch/x86/include/asm/calling.h b/arch/x86/include/asm/calling.h
index 2bc162e0ec6e..0e63c9a2a8d0 100644
--- a/arch/x86/include/asm/calling.h
+++ b/arch/x86/include/asm/calling.h
@@ -1,5 +1,55 @@
 /*
- * Some macros to handle stack frames in assembly.
+
+ x86 function call convention, 64-bit:
+ -------------------------------------
+  arguments           |  callee-saved      | extra caller-saved | return
+ [callee-clobbered]   |                    | [callee-clobbered] |
+ ---------------------------------------------------------------------------
+ rdi rsi rdx rcx r8-9 | rbx rbp [*] r12-15 | r10-11             | rax, rdx [**]
+
+ ( rsp is obviously invariant across normal function calls. (gcc can 'merge'
+   functions when it sees tail-call optimization possibilities) rflags is
+   clobbered. Leftover arguments are passed over the stack frame.)
+
+ [*]  In the frame-pointers case rbp is fixed to the stack frame.
+
+ [**] for struct return values wider than 64 bits the return convention is a
+      bit more complex: up to 128 bits width we return small structures
+      straight in rax, rdx. For structures larger than that (3 words or
+      larger) the caller puts a pointer to an on-stack return struct
+      [allocated in the caller's stack frame] into the first argument - i.e.
+      into rdi. All other arguments shift up by one in this case.
+      Fortunately this case is rare in the kernel.
+
+For 32-bit we have the following conventions - kernel is built with
+-mregparm=3 and -freg-struct-return:
+
+ x86 function calling convention, 32-bit:
+ ----------------------------------------
+  arguments         | callee-saved        | extra caller-saved | return
+ [callee-clobbered] |                     | [callee-clobbered] |
+ -------------------------------------------------------------------------
+ eax edx ecx        | ebx edi esi ebp [*] | <none>             | eax, edx [**]
+
+ ( here too esp is obviously invariant across normal function calls. eflags
+   is clobbered. Leftover arguments are passed over the stack frame. )
+
+ [*]  In the frame-pointers case ebp is fixed to the stack frame.
+
+ [**] We build with -freg-struct-return, which on 32-bit means similar
+      semantics as on 64-bit: edx can be used for a second return value
+      (i.e. covering integer and structure sizes up to 64 bits) - after that
+      it gets more complex and more expensive: 3-word or larger struct returns
+      get done in the caller's frame and the pointer to the return struct goes
+      into regparm0, i.e. eax - the other arguments shift up and the
+      function's register parameters degenerate to regparm=2 in essence.
+
+*/
+
+
+/*
+ * 64-bit system call stack frame layout defines and helpers,
+ * for assembly code:
  */
 
 #define R15		  0
@@ -9,7 +59,7 @@
 #define RBP		 32
 #define RBX		 40
 
-/* arguments: interrupts/non tracing syscalls only save upto here*/
+/* arguments: interrupts/non tracing syscalls only save up to here: */
 #define R11		 48
 #define R10		 56
 #define R9		 64
@@ -22,7 +72,7 @@
 #define ORIG_RAX	120       /* + error_code */
 /* end of arguments */
 
-/* cpu exception frame or undefined in case of fast syscall. */
+/* cpu exception frame or undefined in case of fast syscall: */
 #define RIP		128
 #define CS		136
 #define EFLAGS		144

commit 0b86a4e34d885e734a4c4e46293376f3f1c639eb
Merge: 87fe85133fa7 750e1c182513
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Feb 3 16:13:37 2009 +0100

    Merge branch 'core/header-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jaswinder/linux-2.6-tip into core/header-fixes

commit 87fe85133fa7f33c2bc9882826666a7f117c62bd
Merge: 1ff8f739c7cc 15c554439fae
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Feb 3 13:55:06 2009 +0100

    Merge branch 'core/header-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jaswinder/linux-2.6-tipclean into core/header-fixes

commit dc573f9b20c8710105ac35c08ed0fe1da5160ecd
Merge: b3a8c34886d0 ecf441b593ac b1792e367053
Author: Ingo Molnar <mingo@elte.hu>
Date:   Tue Feb 3 06:25:38 2009 +0100

    Merge branches 'tracing/ftrace', 'tracing/kmemtrace' and 'linus' into tracing/core

commit 9f84653bbfba4f6c1bc7c0de914319bad55f17a4
Merge: 3ac6cffea4aa da2c0b021cde
Author: Ingo Molnar <mingo@elte.hu>
Date:   Sat Jan 31 14:27:28 2009 +0100

    Merge branch 'tj-percpu' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc into core/percpu

commit d8106d2e24d54497233ca9cd97fa9bec807de458
Author: Ingo Molnar <mingo@elte.hu>
Date:   Sat Jan 31 03:06:17 2009 +0100

    x86, vm86: clean up invalid_vm86_irq()
    
    Signed-off-by: Ingo Molnar <mingo@elte.hu>

diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 41e2450e13bd..b07278c55e9e 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -124,7 +124,13 @@
 
 #define	FIRST_VM86_IRQ			   3
 #define LAST_VM86_IRQ			  15
-#define invalid_vm86_irq(irq)		((irq) < 3 || (irq) > 15)
+
+#ifndef __ASSEMBLY__
+static inline int invalid_vm86_irq(int irq)
+{
+	return irq < 3 || irq > 15;
+}
+#endif
 
 /*
  * Size the maximum number of interrupts.