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.