* [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit}
@ 2009-02-05 18:14 Arnaldo Carvalho de Melo
2009-02-05 22:58 ` Frederic Weisbecker
2009-02-06 0:02 ` Ingo Molnar
0 siblings, 2 replies; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2009-02-05 18:14 UTC (permalink / raw)
To: Steven Rostedt
Cc: Ingo Molnar, Frédéric Weisbecker, Jens Axboe,
Linux Kernel Mailing List
Impact: new API
These new functions do what previously was being open coded, reducing
the number of details ftrace plugin writers have to worry about.
It also standardizes the handling of stacktrace, userstacktrace and
other trace options we may introduce in the future.
With this patch, for instance, the blk tracer (and some others already
in the tree) can use the "userstacktrace" /d/tracing/trace_options
facility.
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Jens Axboe <jens.axboe@oracle.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
block/blktrace.c | 21 ++------
kernel/trace/kmemtrace.c | 19 ++-----
kernel/trace/trace.c | 94 +++++++++++++++++++++----------------
kernel/trace/trace.h | 11 ++++
kernel/trace/trace_boot.c | 20 ++------
kernel/trace/trace_branch.c | 7 +--
kernel/trace/trace_hw_branches.c | 7 +--
kernel/trace/trace_mmiotrace.c | 20 +++-----
kernel/trace/trace_power.c | 20 ++------
9 files changed, 102 insertions(+), 117 deletions(-)
$ codiff /tmp/vmlinux.before /tmp/vmlinux.after
linux-2.6-tip/kernel/trace/trace.c:
trace_vprintk | -5
trace_graph_return | -22
trace_graph_entry | -26
trace_function | -45
__ftrace_trace_stack | -27
ftrace_trace_userstack | -29
tracing_sched_switch_trace | -66
tracing_stop | +1
trace_seq_to_user | -1
ftrace_trace_special | -63
ftrace_special | +1
tracing_sched_wakeup_trace | -70
tracing_reset_online_cpus | -1
13 functions changed, 2 bytes added, 355 bytes removed, diff: -353
linux-2.6-tip/block/blktrace.c:
__blk_add_trace | -58
1 function changed, 58 bytes removed, diff: -58
linux-2.6-tip/kernel/trace/trace.c:
trace_buffer_lock_reserve | +88
trace_buffer_unlock_commit | +86
2 functions changed, 174 bytes added, diff: +174
/tmp/vmlinux.after:
16 functions changed, 176 bytes added, 413 bytes removed, diff: -237
diff --git a/block/blktrace.c b/block/blktrace.c
index 8e52f24..834cd84 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -187,19 +187,15 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
cpu = raw_smp_processor_id();
if (blk_tr) {
- struct trace_entry *ent;
tracing_record_cmdline(current);
- event = ring_buffer_lock_reserve(blk_tr->buffer,
- sizeof(*t) + pdu_len);
+ pc = preempt_count();
+ event = trace_buffer_lock_reserve(blk_tr, TRACE_BLK,
+ sizeof(*t) + pdu_len,
+ 0, pc);
if (!event)
return;
-
- ent = ring_buffer_event_data(event);
- t = (struct blk_io_trace *)ent;
- pc = preempt_count();
- tracing_generic_entry_update(ent, 0, pc);
- ent->type = TRACE_BLK;
+ t = ring_buffer_event_data(event);
goto record_it;
}
@@ -241,12 +237,7 @@ record_it:
memcpy((void *) t + sizeof(*t), pdu_data, pdu_len);
if (blk_tr) {
- ring_buffer_unlock_commit(blk_tr->buffer, event);
- if (pid != 0 &&
- !(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC) &&
- (trace_flags & TRACE_ITER_STACKTRACE) != 0)
- __trace_stack(blk_tr, 0, 5, pc);
- trace_wake_up();
+ trace_buffer_unlock_commit(blk_tr, event, 0, pc);
return;
}
}
diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c
index 256749d..ae201b3 100644
--- a/kernel/trace/kmemtrace.c
+++ b/kernel/trace/kmemtrace.c
@@ -276,13 +276,12 @@ void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id,
if (!kmem_tracing_enabled)
return;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_KMEM_ALLOC,
+ sizeof(*entry), 0, 0);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, 0);
- entry->ent.type = TRACE_KMEM_ALLOC;
entry->call_site = call_site;
entry->ptr = ptr;
entry->bytes_req = bytes_req;
@@ -290,9 +289,7 @@ void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id,
entry->gfp_flags = gfp_flags;
entry->node = node;
- ring_buffer_unlock_commit(tr->buffer, event);
-
- trace_wake_up();
+ trace_buffer_unlock_commit(tr, event, 0, 0);
}
EXPORT_SYMBOL(kmemtrace_mark_alloc_node);
@@ -307,20 +304,16 @@ void kmemtrace_mark_free(enum kmemtrace_type_id type_id,
if (!kmem_tracing_enabled)
return;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_KMEM_FREE,
+ sizeof(*entry), 0, 0);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, 0);
-
- entry->ent.type = TRACE_KMEM_FREE;
entry->type_id = type_id;
entry->call_site = call_site;
entry->ptr = ptr;
- ring_buffer_unlock_commit(tr->buffer, event);
-
- trace_wake_up();
+ trace_buffer_unlock_commit(tr, event, 0, 0);
}
EXPORT_SYMBOL(kmemtrace_mark_free);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index eb453a2..8fad377 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -776,6 +776,39 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
(need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
}
+struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
+ unsigned char type,
+ unsigned long len,
+ unsigned long flags, int pc)
+{
+ struct ring_buffer_event *event;
+
+ event = ring_buffer_lock_reserve(tr->buffer, len);
+ if (event != NULL) {
+ struct trace_entry *ent = ring_buffer_event_data(event);
+
+ tracing_generic_entry_update(ent, flags, pc);
+ ent->type = type;
+ }
+
+ return event;
+}
+static void ftrace_trace_stack(struct trace_array *tr,
+ unsigned long flags, int skip, int pc);
+static void ftrace_trace_userstack(struct trace_array *tr,
+ unsigned long flags, int pc);
+
+void trace_buffer_unlock_commit(struct trace_array *tr,
+ struct ring_buffer_event *event,
+ unsigned long flags, int pc)
+{
+ ring_buffer_unlock_commit(tr->buffer, event);
+
+ ftrace_trace_stack(tr, flags, 6, pc);
+ ftrace_trace_userstack(tr, flags, pc);
+ trace_wake_up();
+}
+
void
trace_function(struct trace_array *tr,
unsigned long ip, unsigned long parent_ip, unsigned long flags,
@@ -788,12 +821,11 @@ trace_function(struct trace_array *tr,
if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
return;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_FN, sizeof(*entry),
+ flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_FN;
entry->ip = ip;
entry->parent_ip = parent_ip;
ring_buffer_unlock_commit(tr->buffer, event);
@@ -811,12 +843,11 @@ static void __trace_graph_entry(struct trace_array *tr,
if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
return;
- event = ring_buffer_lock_reserve(global_trace.buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_ENT,
+ sizeof(*entry), flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_GRAPH_ENT;
entry->graph_ent = *trace;
ring_buffer_unlock_commit(global_trace.buffer, event);
}
@@ -832,12 +863,11 @@ static void __trace_graph_return(struct trace_array *tr,
if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
return;
- event = ring_buffer_lock_reserve(global_trace.buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_RET,
+ sizeof(*entry), flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_GRAPH_RET;
entry->ret = *trace;
ring_buffer_unlock_commit(global_trace.buffer, event);
}
@@ -861,13 +891,11 @@ static void __ftrace_trace_stack(struct trace_array *tr,
struct stack_entry *entry;
struct stack_trace trace;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_STACK,
+ sizeof(*entry), flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_STACK;
-
memset(&entry->caller, 0, sizeof(entry->caller));
trace.nr_entries = 0;
@@ -908,12 +936,11 @@ static void ftrace_trace_userstack(struct trace_array *tr,
if (!(trace_flags & TRACE_ITER_USERSTACKTRACE))
return;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_USER_STACK,
+ sizeof(*entry), flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_USER_STACK;
memset(&entry->caller, 0, sizeof(entry->caller));
@@ -941,20 +968,15 @@ ftrace_trace_special(void *__tr,
struct trace_array *tr = __tr;
struct special_entry *entry;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_SPECIAL,
+ sizeof(*entry), 0, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, pc);
- entry->ent.type = TRACE_SPECIAL;
entry->arg1 = arg1;
entry->arg2 = arg2;
entry->arg3 = arg3;
- ring_buffer_unlock_commit(tr->buffer, event);
- ftrace_trace_stack(tr, 0, 4, pc);
- ftrace_trace_userstack(tr, 0, pc);
-
- trace_wake_up();
+ trace_buffer_unlock_commit(tr, event, 0, pc);
}
void
@@ -973,12 +995,11 @@ tracing_sched_switch_trace(struct trace_array *tr,
struct ring_buffer_event *event;
struct ctx_switch_entry *entry;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_CTX,
+ sizeof(*entry), flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_CTX;
entry->prev_pid = prev->pid;
entry->prev_prio = prev->prio;
entry->prev_state = prev->state;
@@ -986,9 +1007,7 @@ tracing_sched_switch_trace(struct trace_array *tr,
entry->next_prio = next->prio;
entry->next_state = next->state;
entry->next_cpu = task_cpu(next);
- ring_buffer_unlock_commit(tr->buffer, event);
- ftrace_trace_stack(tr, flags, 5, pc);
- ftrace_trace_userstack(tr, flags, pc);
+ trace_buffer_unlock_commit(tr, event, flags, pc);
}
void
@@ -1000,12 +1019,11 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
struct ring_buffer_event *event;
struct ctx_switch_entry *entry;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_WAKE,
+ sizeof(*entry), flags, pc);
if (!event)
return;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_WAKE;
entry->prev_pid = curr->pid;
entry->prev_prio = curr->prio;
entry->prev_state = curr->state;
@@ -1013,11 +1031,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
entry->next_prio = wakee->prio;
entry->next_state = wakee->state;
entry->next_cpu = task_cpu(wakee);
- ring_buffer_unlock_commit(tr->buffer, event);
- ftrace_trace_stack(tr, flags, 6, pc);
- ftrace_trace_userstack(tr, flags, pc);
-
- trace_wake_up();
+ trace_buffer_unlock_commit(tr, event, flags, pc);
}
void
@@ -2825,12 +2839,10 @@ int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args)
trace_buf[len] = 0;
size = sizeof(*entry) + len + 1;
- event = ring_buffer_lock_reserve(tr->buffer, size);
+ event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, irq_flags, pc);
if (!event)
goto out_unlock;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, irq_flags, pc);
- entry->ent.type = TRACE_PRINT;
entry->ip = ip;
entry->depth = depth;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index df627a9..e03f157 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -403,6 +403,17 @@ int tracing_open_generic(struct inode *inode, struct file *filp);
struct dentry *tracing_init_dentry(void);
void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
+struct ring_buffer_event;
+
+struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
+ unsigned char type,
+ unsigned long len,
+ unsigned long flags,
+ int pc);
+void trace_buffer_unlock_commit(struct trace_array *tr,
+ struct ring_buffer_event *event,
+ unsigned long flags, int pc);
+
struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
struct trace_array_cpu *data);
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
index 4e08deb..7a30fc4 100644
--- a/kernel/trace/trace_boot.c
+++ b/kernel/trace/trace_boot.c
@@ -143,17 +143,13 @@ void trace_boot_call(struct boot_trace_call *bt, initcall_t fn)
sprint_symbol(bt->func, (unsigned long)fn);
preempt_disable();
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_BOOT_CALL,
+ sizeof(*entry), 0, 0);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, 0);
- entry->ent.type = TRACE_BOOT_CALL;
entry->boot_call = *bt;
- ring_buffer_unlock_commit(tr->buffer, event);
-
- trace_wake_up();
-
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
preempt_enable();
}
@@ -170,17 +166,13 @@ void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn)
sprint_symbol(bt->func, (unsigned long)fn);
preempt_disable();
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_BOOT_RET,
+ sizeof(*entry), 0, 0);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, 0);
- entry->ent.type = TRACE_BOOT_RET;
entry->boot_ret = *bt;
- ring_buffer_unlock_commit(tr->buffer, event);
-
- trace_wake_up();
-
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
preempt_enable();
}
diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
index 770e52a..48b2196 100644
--- a/kernel/trace/trace_branch.c
+++ b/kernel/trace/trace_branch.c
@@ -52,14 +52,13 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
goto out;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ pc = preempt_count();
+ event = trace_buffer_lock_reserve(tr, TRACE_BRANCH,
+ sizeof(*entry), flags, pc);
if (!event)
goto out;
- pc = preempt_count();
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, flags, pc);
- entry->ent.type = TRACE_BRANCH;
/* Strip off the path, only save the file */
p = f->file + strlen(f->file);
diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
index e720c00..2aa1c9f 100644
--- a/kernel/trace/trace_hw_branches.c
+++ b/kernel/trace/trace_hw_branches.c
@@ -189,16 +189,15 @@ void trace_hw_branch(u64 from, u64 to)
if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
goto out;
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_HW_BRANCHES,
+ sizeof(*entry), 0, 0);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, from);
- entry->ent.type = TRACE_HW_BRANCHES;
entry->ent.cpu = cpu;
entry->from = from;
entry->to = to;
- ring_buffer_unlock_commit(tr->buffer, event);
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
atomic_dec(&tr->data[cpu]->disabled);
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 104ddeb..c401b90 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -307,19 +307,17 @@ static void __trace_mmiotrace_rw(struct trace_array *tr,
{
struct ring_buffer_event *event;
struct trace_mmiotrace_rw *entry;
+ int pc = preempt_count();
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_MMIO_RW,
+ sizeof(*entry), 0, pc);
if (!event) {
atomic_inc(&dropped_count);
return;
}
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, preempt_count());
- entry->ent.type = TRACE_MMIO_RW;
entry->rw = *rw;
- ring_buffer_unlock_commit(tr->buffer, event);
-
- trace_wake_up();
+ trace_buffer_unlock_commit(tr, event, 0, pc);
}
void mmio_trace_rw(struct mmiotrace_rw *rw)
@@ -335,19 +333,17 @@ static void __trace_mmiotrace_map(struct trace_array *tr,
{
struct ring_buffer_event *event;
struct trace_mmiotrace_map *entry;
+ int pc = preempt_count();
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_MMIO_MAP,
+ sizeof(*entry), 0, pc);
if (!event) {
atomic_inc(&dropped_count);
return;
}
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, preempt_count());
- entry->ent.type = TRACE_MMIO_MAP;
entry->map = *map;
- ring_buffer_unlock_commit(tr->buffer, event);
-
- trace_wake_up();
+ trace_buffer_unlock_commit(tr, event, 0, pc);
}
void mmio_trace_mapping(struct mmiotrace_map *map)
diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c
index 3b1a292..bfc21f8 100644
--- a/kernel/trace/trace_power.c
+++ b/kernel/trace/trace_power.c
@@ -124,17 +124,13 @@ void trace_power_end(struct power_trace *it)
it->end = ktime_get();
data = tr->data[smp_processor_id()];
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_POWER,
+ sizeof(*entry), 0, 0);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, 0);
- entry->ent.type = TRACE_POWER;
entry->state_data = *it;
- ring_buffer_unlock_commit(tr->buffer, event);
-
- trace_wake_up();
-
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
preempt_enable();
}
@@ -159,17 +155,13 @@ void trace_power_mark(struct power_trace *it, unsigned int type,
it->end = it->stamp;
data = tr->data[smp_processor_id()];
- event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
+ event = trace_buffer_lock_reserve(tr, TRACE_POWER,
+ sizeof(*entry), 0, 0);
if (!event)
goto out;
entry = ring_buffer_event_data(event);
- tracing_generic_entry_update(&entry->ent, 0, 0);
- entry->ent.type = TRACE_POWER;
entry->state_data = *it;
- ring_buffer_unlock_commit(tr->buffer, event);
-
- trace_wake_up();
-
+ trace_buffer_unlock_commit(tr, event, 0, 0);
out:
preempt_enable();
}
--
1.6.0.6
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit}
2009-02-05 18:14 [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit} Arnaldo Carvalho de Melo
@ 2009-02-05 22:58 ` Frederic Weisbecker
2009-02-06 1:54 ` Arnaldo Carvalho de Melo
2009-02-06 0:02 ` Ingo Molnar
1 sibling, 1 reply; 8+ messages in thread
From: Frederic Weisbecker @ 2009-02-05 22:58 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Steven Rostedt, Ingo Molnar, Jens Axboe,
Linux Kernel Mailing List
On Thu, Feb 05, 2009 at 04:14:13PM -0200, Arnaldo Carvalho de Melo wrote:
> Impact: new API
>
> These new functions do what previously was being open coded, reducing
> the number of details ftrace plugin writers have to worry about.
>
> It also standardizes the handling of stacktrace, userstacktrace and
> other trace options we may introduce in the future.
>
> With this patch, for instance, the blk tracer (and some others already
> in the tree) can use the "userstacktrace" /d/tracing/trace_options
> facility.
>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Frédéric Weisbecker <fweisbec@gmail.com>
> Cc: Jens Axboe <jens.axboe@oracle.com>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
> block/blktrace.c | 21 ++------
> kernel/trace/kmemtrace.c | 19 ++-----
> kernel/trace/trace.c | 94 +++++++++++++++++++++----------------
> kernel/trace/trace.h | 11 ++++
> kernel/trace/trace_boot.c | 20 ++------
> kernel/trace/trace_branch.c | 7 +--
> kernel/trace/trace_hw_branches.c | 7 +--
> kernel/trace/trace_mmiotrace.c | 20 +++-----
> kernel/trace/trace_power.c | 20 ++------
> 9 files changed, 102 insertions(+), 117 deletions(-)
>
> $ codiff /tmp/vmlinux.before /tmp/vmlinux.after
> linux-2.6-tip/kernel/trace/trace.c:
> trace_vprintk | -5
> trace_graph_return | -22
> trace_graph_entry | -26
> trace_function | -45
> __ftrace_trace_stack | -27
> ftrace_trace_userstack | -29
> tracing_sched_switch_trace | -66
> tracing_stop | +1
> trace_seq_to_user | -1
> ftrace_trace_special | -63
> ftrace_special | +1
> tracing_sched_wakeup_trace | -70
> tracing_reset_online_cpus | -1
> 13 functions changed, 2 bytes added, 355 bytes removed, diff: -353
>
> linux-2.6-tip/block/blktrace.c:
> __blk_add_trace | -58
> 1 function changed, 58 bytes removed, diff: -58
>
> linux-2.6-tip/kernel/trace/trace.c:
> trace_buffer_lock_reserve | +88
> trace_buffer_unlock_commit | +86
> 2 functions changed, 174 bytes added, diff: +174
>
> /tmp/vmlinux.after:
> 16 functions changed, 176 bytes added, 413 bytes removed, diff: -237
>
> diff --git a/block/blktrace.c b/block/blktrace.c
> index 8e52f24..834cd84 100644
> --- a/block/blktrace.c
> +++ b/block/blktrace.c
> @@ -187,19 +187,15 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
> cpu = raw_smp_processor_id();
>
> if (blk_tr) {
> - struct trace_entry *ent;
> tracing_record_cmdline(current);
>
> - event = ring_buffer_lock_reserve(blk_tr->buffer,
> - sizeof(*t) + pdu_len);
> + pc = preempt_count();
> + event = trace_buffer_lock_reserve(blk_tr, TRACE_BLK,
> + sizeof(*t) + pdu_len,
> + 0, pc);
Oh that's a good idea. That makes it more simple and abstract more the ring buffer
from tracing.
> if (!event)
> return;
> -
> - ent = ring_buffer_event_data(event);
> - t = (struct blk_io_trace *)ent;
> - pc = preempt_count();
> - tracing_generic_entry_update(ent, 0, pc);
> - ent->type = TRACE_BLK;
> + t = ring_buffer_event_data(event);
> goto record_it;
> }
>
> @@ -241,12 +237,7 @@ record_it:
> memcpy((void *) t + sizeof(*t), pdu_data, pdu_len);
>
> if (blk_tr) {
> - ring_buffer_unlock_commit(blk_tr->buffer, event);
> - if (pid != 0 &&
> - !(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC) &&
> - (trace_flags & TRACE_ITER_STACKTRACE) != 0)
> - __trace_stack(blk_tr, 0, 5, pc);
> - trace_wake_up();
> + trace_buffer_unlock_commit(blk_tr, event, 0, pc);
> return;
> }
> }
> diff --git a/kernel/trace/kmemtrace.c b/kernel/trace/kmemtrace.c
> index 256749d..ae201b3 100644
> --- a/kernel/trace/kmemtrace.c
> +++ b/kernel/trace/kmemtrace.c
> @@ -276,13 +276,12 @@ void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id,
> if (!kmem_tracing_enabled)
> return;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_KMEM_ALLOC,
> + sizeof(*entry), 0, 0);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, 0);
>
> - entry->ent.type = TRACE_KMEM_ALLOC;
> entry->call_site = call_site;
> entry->ptr = ptr;
> entry->bytes_req = bytes_req;
> @@ -290,9 +289,7 @@ void kmemtrace_mark_alloc_node(enum kmemtrace_type_id type_id,
> entry->gfp_flags = gfp_flags;
> entry->node = node;
>
> - ring_buffer_unlock_commit(tr->buffer, event);
> -
> - trace_wake_up();
> + trace_buffer_unlock_commit(tr, event, 0, 0);
> }
> EXPORT_SYMBOL(kmemtrace_mark_alloc_node);
>
> @@ -307,20 +304,16 @@ void kmemtrace_mark_free(enum kmemtrace_type_id type_id,
> if (!kmem_tracing_enabled)
> return;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_KMEM_FREE,
> + sizeof(*entry), 0, 0);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, 0);
> -
> - entry->ent.type = TRACE_KMEM_FREE;
> entry->type_id = type_id;
> entry->call_site = call_site;
> entry->ptr = ptr;
>
> - ring_buffer_unlock_commit(tr->buffer, event);
> -
> - trace_wake_up();
> + trace_buffer_unlock_commit(tr, event, 0, 0);
> }
> EXPORT_SYMBOL(kmemtrace_mark_free);
>
> diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
> index eb453a2..8fad377 100644
> --- a/kernel/trace/trace.c
> +++ b/kernel/trace/trace.c
> @@ -776,6 +776,39 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
> (need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
> }
>
> +struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
> + unsigned char type,
> + unsigned long len,
> + unsigned long flags, int pc)
> +{
> + struct ring_buffer_event *event;
> +
> + event = ring_buffer_lock_reserve(tr->buffer, len);
> + if (event != NULL) {
> + struct trace_entry *ent = ring_buffer_event_data(event);
> +
> + tracing_generic_entry_update(ent, flags, pc);
> + ent->type = type;
> + }
> +
> + return event;
> +}
> +static void ftrace_trace_stack(struct trace_array *tr,
> + unsigned long flags, int skip, int pc);
> +static void ftrace_trace_userstack(struct trace_array *tr,
> + unsigned long flags, int pc);
> +
> +void trace_buffer_unlock_commit(struct trace_array *tr,
> + struct ring_buffer_event *event,
> + unsigned long flags, int pc)
> +{
> + ring_buffer_unlock_commit(tr->buffer, event);
> +
> + ftrace_trace_stack(tr, flags, 6, pc);
> + ftrace_trace_userstack(tr, flags, pc);
> + trace_wake_up();
> +}
I have mitigate feelings about this part. The name of this function could
have some sense if _most_ of the tracers were using the stack traces. But that's
not the case.
We have now this couple:
_ trace_buffer_lock_reserve() -> handles the ring-buffer reservation, the context info, and the type
_ trace_buffer_unlock_commit() -> unlock, commit, wake and... stacktraces?
In my opinion, the latter doesn't follow the logic meaning of the first.
And the result is a mixup of (trace_buffer | ring_buffer)(lock/unlock/reserve/commit).
You are sometimes using trace_buffer_lock_reserve followed by ring_buffer_unlock_commit.
That looks a bit weird: we are using a high level function followed by its conclusion
on the form of the low lovel function.
I think the primary role of this new couple should be to simplify the low level ring buffer
bits as it does. But the stack things should stay separated.
> +
> void
> trace_function(struct trace_array *tr,
> unsigned long ip, unsigned long parent_ip, unsigned long flags,
> @@ -788,12 +821,11 @@ trace_function(struct trace_array *tr,
> if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
> return;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_FN, sizeof(*entry),
> + flags, pc);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, flags, pc);
> - entry->ent.type = TRACE_FN;
> entry->ip = ip;
> entry->parent_ip = parent_ip;
> ring_buffer_unlock_commit(tr->buffer, event);
> @@ -811,12 +843,11 @@ static void __trace_graph_entry(struct trace_array *tr,
> if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
> return;
>
> - event = ring_buffer_lock_reserve(global_trace.buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_ENT,
> + sizeof(*entry), flags, pc);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, flags, pc);
> - entry->ent.type = TRACE_GRAPH_ENT;
> entry->graph_ent = *trace;
> ring_buffer_unlock_commit(global_trace.buffer, event);
> }
> @@ -832,12 +863,11 @@ static void __trace_graph_return(struct trace_array *tr,
> if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
> return;
>
> - event = ring_buffer_lock_reserve(global_trace.buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(&global_trace, TRACE_GRAPH_RET,
> + sizeof(*entry), flags, pc);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, flags, pc);
> - entry->ent.type = TRACE_GRAPH_RET;
> entry->ret = *trace;
> ring_buffer_unlock_commit(global_trace.buffer, event);
> }
> @@ -861,13 +891,11 @@ static void __ftrace_trace_stack(struct trace_array *tr,
> struct stack_entry *entry;
> struct stack_trace trace;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_STACK,
> + sizeof(*entry), flags, pc);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, flags, pc);
> - entry->ent.type = TRACE_STACK;
> -
> memset(&entry->caller, 0, sizeof(entry->caller));
>
> trace.nr_entries = 0;
> @@ -908,12 +936,11 @@ static void ftrace_trace_userstack(struct trace_array *tr,
> if (!(trace_flags & TRACE_ITER_USERSTACKTRACE))
> return;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_USER_STACK,
> + sizeof(*entry), flags, pc);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, flags, pc);
> - entry->ent.type = TRACE_USER_STACK;
>
> memset(&entry->caller, 0, sizeof(entry->caller));
>
> @@ -941,20 +968,15 @@ ftrace_trace_special(void *__tr,
> struct trace_array *tr = __tr;
> struct special_entry *entry;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_SPECIAL,
> + sizeof(*entry), 0, pc);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, pc);
> - entry->ent.type = TRACE_SPECIAL;
> entry->arg1 = arg1;
> entry->arg2 = arg2;
> entry->arg3 = arg3;
> - ring_buffer_unlock_commit(tr->buffer, event);
> - ftrace_trace_stack(tr, 0, 4, pc);
> - ftrace_trace_userstack(tr, 0, pc);
> -
> - trace_wake_up();
> + trace_buffer_unlock_commit(tr, event, 0, pc);
> }
>
> void
> @@ -973,12 +995,11 @@ tracing_sched_switch_trace(struct trace_array *tr,
> struct ring_buffer_event *event;
> struct ctx_switch_entry *entry;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_CTX,
> + sizeof(*entry), flags, pc);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, flags, pc);
> - entry->ent.type = TRACE_CTX;
> entry->prev_pid = prev->pid;
> entry->prev_prio = prev->prio;
> entry->prev_state = prev->state;
> @@ -986,9 +1007,7 @@ tracing_sched_switch_trace(struct trace_array *tr,
> entry->next_prio = next->prio;
> entry->next_state = next->state;
> entry->next_cpu = task_cpu(next);
> - ring_buffer_unlock_commit(tr->buffer, event);
> - ftrace_trace_stack(tr, flags, 5, pc);
> - ftrace_trace_userstack(tr, flags, pc);
> + trace_buffer_unlock_commit(tr, event, flags, pc);
> }
>
> void
> @@ -1000,12 +1019,11 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
> struct ring_buffer_event *event;
> struct ctx_switch_entry *entry;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_WAKE,
> + sizeof(*entry), flags, pc);
> if (!event)
> return;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, flags, pc);
> - entry->ent.type = TRACE_WAKE;
> entry->prev_pid = curr->pid;
> entry->prev_prio = curr->prio;
> entry->prev_state = curr->state;
> @@ -1013,11 +1031,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
> entry->next_prio = wakee->prio;
> entry->next_state = wakee->state;
> entry->next_cpu = task_cpu(wakee);
> - ring_buffer_unlock_commit(tr->buffer, event);
> - ftrace_trace_stack(tr, flags, 6, pc);
> - ftrace_trace_userstack(tr, flags, pc);
> -
> - trace_wake_up();
> + trace_buffer_unlock_commit(tr, event, flags, pc);
> }
>
> void
> @@ -2825,12 +2839,10 @@ int trace_vprintk(unsigned long ip, int depth, const char *fmt, va_list args)
> trace_buf[len] = 0;
>
> size = sizeof(*entry) + len + 1;
> - event = ring_buffer_lock_reserve(tr->buffer, size);
> + event = trace_buffer_lock_reserve(tr, TRACE_PRINT, size, irq_flags, pc);
> if (!event)
> goto out_unlock;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, irq_flags, pc);
> - entry->ent.type = TRACE_PRINT;
> entry->ip = ip;
> entry->depth = depth;
>
> diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
> index df627a9..e03f157 100644
> --- a/kernel/trace/trace.h
> +++ b/kernel/trace/trace.h
> @@ -403,6 +403,17 @@ int tracing_open_generic(struct inode *inode, struct file *filp);
> struct dentry *tracing_init_dentry(void);
> void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
>
> +struct ring_buffer_event;
> +
> +struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
> + unsigned char type,
> + unsigned long len,
> + unsigned long flags,
> + int pc);
> +void trace_buffer_unlock_commit(struct trace_array *tr,
> + struct ring_buffer_event *event,
> + unsigned long flags, int pc);
> +
> struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
> struct trace_array_cpu *data);
>
> diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
> index 4e08deb..7a30fc4 100644
> --- a/kernel/trace/trace_boot.c
> +++ b/kernel/trace/trace_boot.c
> @@ -143,17 +143,13 @@ void trace_boot_call(struct boot_trace_call *bt, initcall_t fn)
> sprint_symbol(bt->func, (unsigned long)fn);
> preempt_disable();
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_BOOT_CALL,
> + sizeof(*entry), 0, 0);
> if (!event)
> goto out;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, 0);
> - entry->ent.type = TRACE_BOOT_CALL;
> entry->boot_call = *bt;
> - ring_buffer_unlock_commit(tr->buffer, event);
> -
> - trace_wake_up();
> -
> + trace_buffer_unlock_commit(tr, event, 0, 0);
> out:
> preempt_enable();
> }
> @@ -170,17 +166,13 @@ void trace_boot_ret(struct boot_trace_ret *bt, initcall_t fn)
> sprint_symbol(bt->func, (unsigned long)fn);
> preempt_disable();
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_BOOT_RET,
> + sizeof(*entry), 0, 0);
> if (!event)
> goto out;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, 0);
> - entry->ent.type = TRACE_BOOT_RET;
> entry->boot_ret = *bt;
> - ring_buffer_unlock_commit(tr->buffer, event);
> -
> - trace_wake_up();
> -
> + trace_buffer_unlock_commit(tr, event, 0, 0);
> out:
> preempt_enable();
> }
> diff --git a/kernel/trace/trace_branch.c b/kernel/trace/trace_branch.c
> index 770e52a..48b2196 100644
> --- a/kernel/trace/trace_branch.c
> +++ b/kernel/trace/trace_branch.c
> @@ -52,14 +52,13 @@ probe_likely_condition(struct ftrace_branch_data *f, int val, int expect)
> if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
> goto out;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + pc = preempt_count();
> + event = trace_buffer_lock_reserve(tr, TRACE_BRANCH,
> + sizeof(*entry), flags, pc);
> if (!event)
> goto out;
>
> - pc = preempt_count();
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, flags, pc);
> - entry->ent.type = TRACE_BRANCH;
>
> /* Strip off the path, only save the file */
> p = f->file + strlen(f->file);
> diff --git a/kernel/trace/trace_hw_branches.c b/kernel/trace/trace_hw_branches.c
> index e720c00..2aa1c9f 100644
> --- a/kernel/trace/trace_hw_branches.c
> +++ b/kernel/trace/trace_hw_branches.c
> @@ -189,16 +189,15 @@ void trace_hw_branch(u64 from, u64 to)
> if (atomic_inc_return(&tr->data[cpu]->disabled) != 1)
> goto out;
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_HW_BRANCHES,
> + sizeof(*entry), 0, 0);
> if (!event)
> goto out;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, from);
> - entry->ent.type = TRACE_HW_BRANCHES;
> entry->ent.cpu = cpu;
> entry->from = from;
> entry->to = to;
> - ring_buffer_unlock_commit(tr->buffer, event);
> + trace_buffer_unlock_commit(tr, event, 0, 0);
>
> out:
> atomic_dec(&tr->data[cpu]->disabled);
> diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
> index 104ddeb..c401b90 100644
> --- a/kernel/trace/trace_mmiotrace.c
> +++ b/kernel/trace/trace_mmiotrace.c
> @@ -307,19 +307,17 @@ static void __trace_mmiotrace_rw(struct trace_array *tr,
> {
> struct ring_buffer_event *event;
> struct trace_mmiotrace_rw *entry;
> + int pc = preempt_count();
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_MMIO_RW,
> + sizeof(*entry), 0, pc);
> if (!event) {
> atomic_inc(&dropped_count);
> return;
> }
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, preempt_count());
> - entry->ent.type = TRACE_MMIO_RW;
> entry->rw = *rw;
> - ring_buffer_unlock_commit(tr->buffer, event);
> -
> - trace_wake_up();
> + trace_buffer_unlock_commit(tr, event, 0, pc);
> }
>
> void mmio_trace_rw(struct mmiotrace_rw *rw)
> @@ -335,19 +333,17 @@ static void __trace_mmiotrace_map(struct trace_array *tr,
> {
> struct ring_buffer_event *event;
> struct trace_mmiotrace_map *entry;
> + int pc = preempt_count();
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_MMIO_MAP,
> + sizeof(*entry), 0, pc);
> if (!event) {
> atomic_inc(&dropped_count);
> return;
> }
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, preempt_count());
> - entry->ent.type = TRACE_MMIO_MAP;
> entry->map = *map;
> - ring_buffer_unlock_commit(tr->buffer, event);
> -
> - trace_wake_up();
> + trace_buffer_unlock_commit(tr, event, 0, pc);
> }
>
> void mmio_trace_mapping(struct mmiotrace_map *map)
> diff --git a/kernel/trace/trace_power.c b/kernel/trace/trace_power.c
> index 3b1a292..bfc21f8 100644
> --- a/kernel/trace/trace_power.c
> +++ b/kernel/trace/trace_power.c
> @@ -124,17 +124,13 @@ void trace_power_end(struct power_trace *it)
> it->end = ktime_get();
> data = tr->data[smp_processor_id()];
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_POWER,
> + sizeof(*entry), 0, 0);
> if (!event)
> goto out;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, 0);
> - entry->ent.type = TRACE_POWER;
> entry->state_data = *it;
> - ring_buffer_unlock_commit(tr->buffer, event);
> -
> - trace_wake_up();
> -
> + trace_buffer_unlock_commit(tr, event, 0, 0);
> out:
> preempt_enable();
> }
> @@ -159,17 +155,13 @@ void trace_power_mark(struct power_trace *it, unsigned int type,
> it->end = it->stamp;
> data = tr->data[smp_processor_id()];
>
> - event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry));
> + event = trace_buffer_lock_reserve(tr, TRACE_POWER,
> + sizeof(*entry), 0, 0);
> if (!event)
> goto out;
> entry = ring_buffer_event_data(event);
> - tracing_generic_entry_update(&entry->ent, 0, 0);
> - entry->ent.type = TRACE_POWER;
> entry->state_data = *it;
> - ring_buffer_unlock_commit(tr->buffer, event);
> -
> - trace_wake_up();
> -
> + trace_buffer_unlock_commit(tr, event, 0, 0);
> out:
> preempt_enable();
> }
> --
> 1.6.0.6
>
Other than what I said above, I find it a very valuable cleanup.
Thanks.
Frederic.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit}
2009-02-05 18:14 [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit} Arnaldo Carvalho de Melo
2009-02-05 22:58 ` Frederic Weisbecker
@ 2009-02-06 0:02 ` Ingo Molnar
1 sibling, 0 replies; 8+ messages in thread
From: Ingo Molnar @ 2009-02-06 0:02 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Steven Rostedt, Frédéric Weisbecker, Jens Axboe,
Linux Kernel Mailing List
* Arnaldo Carvalho de Melo <acme@redhat.com> wrote:
> Impact: new API
>
> These new functions do what previously was being open coded, reducing
> the number of details ftrace plugin writers have to worry about.
>
> It also standardizes the handling of stacktrace, userstacktrace and
> other trace options we may introduce in the future.
>
> With this patch, for instance, the blk tracer (and some others already
> in the tree) can use the "userstacktrace" /d/tracing/trace_options
> facility.
>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Frédéric Weisbecker <fweisbec@gmail.com>
> Cc: Jens Axboe <jens.axboe@oracle.com>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---
> block/blktrace.c | 21 ++------
> kernel/trace/kmemtrace.c | 19 ++-----
> kernel/trace/trace.c | 94 +++++++++++++++++++++----------------
> kernel/trace/trace.h | 11 ++++
> kernel/trace/trace_boot.c | 20 ++------
> kernel/trace/trace_branch.c | 7 +--
> kernel/trace/trace_hw_branches.c | 7 +--
> kernel/trace/trace_mmiotrace.c | 20 +++-----
> kernel/trace/trace_power.c | 20 ++------
> 9 files changed, 102 insertions(+), 117 deletions(-)
Applied to tip:tracing/ftrace, thanks!
Ingo
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit}
2009-02-05 22:58 ` Frederic Weisbecker
@ 2009-02-06 1:54 ` Arnaldo Carvalho de Melo
2009-02-06 2:39 ` Frederic Weisbecker
0 siblings, 1 reply; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2009-02-06 1:54 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: Steven Rostedt, Ingo Molnar, Jens Axboe,
Linux Kernel Mailing List
Em Thu, Feb 05, 2009 at 11:58:37PM +0100, Frederic Weisbecker escreveu:
> > +void trace_buffer_unlock_commit(struct trace_array *tr,
> > + struct ring_buffer_event *event,
> > + unsigned long flags, int pc)
> > +{
> > + ring_buffer_unlock_commit(tr->buffer, event);
> > +
> > + ftrace_trace_stack(tr, flags, 6, pc);
> > + ftrace_trace_userstack(tr, flags, pc);
> > + trace_wake_up();
> > +}
>
>
> I have mitigate feelings about this part. The name of this function could
> have some sense if _most_ of the tracers were using the stack traces. But that's
> not the case.
>
> We have now this couple:
>
> _ trace_buffer_lock_reserve() -> handles the ring-buffer reservation, the context info, and the type
> _ trace_buffer_unlock_commit() -> unlock, commit, wake and... stacktraces?
>
> In my opinion, the latter doesn't follow the logic meaning of the first.
> And the result is a mixup of (trace_buffer | ring_buffer)(lock/unlock/reserve/commit).
>
> You are sometimes using trace_buffer_lock_reserve followed by ring_buffer_unlock_commit.
> That looks a bit weird: we are using a high level function followed by its conclusion
> on the form of the low lovel function.
>
> I think the primary role of this new couple should be to simplify the low level ring buffer
> bits as it does. But the stack things should stay separated.
Well, the whole reason for this cset was to provide a way to check for
things like stacktrace while reducing the number of explicit calls the
poor driver, oops, ftrace plugin writers had to keep in mind.
So it may well be the case for a better name, but frankly I think that
this is something better left _hidden_, a magic that the plugin writers
doesn't have to deal with.
But... if they feel lucky and smart, they can just call
ring_buffer_unlock_commit(tr->buffer, event) and do any other things in
a open coded way, as was done in other cases where
trace_buffer_lock_reserve was paired with ring_buffer_unlock_commit.
- Arnaldo
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit}
2009-02-06 1:54 ` Arnaldo Carvalho de Melo
@ 2009-02-06 2:39 ` Frederic Weisbecker
2009-02-06 3:10 ` Arnaldo Carvalho de Melo
0 siblings, 1 reply; 8+ messages in thread
From: Frederic Weisbecker @ 2009-02-06 2:39 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Steven Rostedt, Ingo Molnar, Jens Axboe,
Linux Kernel Mailing List
On Thu, Feb 05, 2009 at 11:54:16PM -0200, Arnaldo Carvalho de Melo wrote:
> Em Thu, Feb 05, 2009 at 11:58:37PM +0100, Frederic Weisbecker escreveu:
> > > +void trace_buffer_unlock_commit(struct trace_array *tr,
> > > + struct ring_buffer_event *event,
> > > + unsigned long flags, int pc)
> > > +{
> > > + ring_buffer_unlock_commit(tr->buffer, event);
> > > +
> > > + ftrace_trace_stack(tr, flags, 6, pc);
> > > + ftrace_trace_userstack(tr, flags, pc);
> > > + trace_wake_up();
> > > +}
> >
> >
> > I have mitigate feelings about this part. The name of this function could
> > have some sense if _most_ of the tracers were using the stack traces. But that's
> > not the case.
> >
> > We have now this couple:
> >
> > _ trace_buffer_lock_reserve() -> handles the ring-buffer reservation, the context info, and the type
> > _ trace_buffer_unlock_commit() -> unlock, commit, wake and... stacktraces?
> >
> > In my opinion, the latter doesn't follow the logic meaning of the first.
> > And the result is a mixup of (trace_buffer | ring_buffer)(lock/unlock/reserve/commit).
> >
> > You are sometimes using trace_buffer_lock_reserve followed by ring_buffer_unlock_commit.
> > That looks a bit weird: we are using a high level function followed by its conclusion
> > on the form of the low lovel function.
> >
> > I think the primary role of this new couple should be to simplify the low level ring buffer
> > bits as it does. But the stack things should stay separated.
>
> Well, the whole reason for this cset was to provide a way to check for
> things like stacktrace while reducing the number of explicit calls the
> poor driver, oops, ftrace plugin writers had to keep in mind.
I agree, but that forces those who don't need stacktraces to use
a paired trace_buffer_lock_reserve() / ring_buffer_unlock_commit()
The poor newcomers will become dizzy with these different namespaces...
And it's like managing a file with fopen() and then close() ... :-)
> So it may well be the case for a better name, but frankly I think that
> this is something better left _hidden_, a magic that the plugin writers
> doesn't have to deal with.
I agree with you, the stacktraces are used by several tracers, and then
it deserves some code factoring.
What I would suggest is to have two different trace_buffer_unlock_commit()
Thinking about the name of these functions, since they are in a higher layer
than the ring buffer which performs some things with locking and buffers, we could
let this latter do his tricky low level work and simply offer some magic functions
with magic names:
_ trace_reserve()
_ trace_commit()
_ trace_commit_stacktrace()
Even if the stack traces layer can be somewhat hidden to the user, we can still
let him decide what he really wants but in an easier way.
Hm?
>
> But... if they feel lucky and smart, they can just call
> ring_buffer_unlock_commit(tr->buffer, event) and do any other things in
> a open coded way, as was done in other cases where
> trace_buffer_lock_reserve was paired with ring_buffer_unlock_commit.
Right! And with our three above functions, the new magic way can
be completely performed without beeing harassed by some bits from the
...lucky way :-)
Frederic.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit}
2009-02-06 2:39 ` Frederic Weisbecker
@ 2009-02-06 3:10 ` Arnaldo Carvalho de Melo
2009-02-08 13:04 ` Frederic Weisbecker
0 siblings, 1 reply; 8+ messages in thread
From: Arnaldo Carvalho de Melo @ 2009-02-06 3:10 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: Steven Rostedt, Ingo Molnar, Jens Axboe,
Linux Kernel Mailing List
Em Fri, Feb 06, 2009 at 03:39:45AM +0100, Frederic Weisbecker escreveu:
> On Thu, Feb 05, 2009 at 11:54:16PM -0200, Arnaldo Carvalho de Melo wrote:
> > Em Thu, Feb 05, 2009 at 11:58:37PM +0100, Frederic Weisbecker escreveu:
> > > > +void trace_buffer_unlock_commit(struct trace_array *tr,
> > > > + struct ring_buffer_event *event,
> > > > + unsigned long flags, int pc)
> > > > +{
> > > > + ring_buffer_unlock_commit(tr->buffer, event);
> > > > +
> > > > + ftrace_trace_stack(tr, flags, 6, pc);
> > > > + ftrace_trace_userstack(tr, flags, pc);
> > > > + trace_wake_up();
> > > > +}
> > >
> > >
> > > I have mitigate feelings about this part. The name of this function could
> > > have some sense if _most_ of the tracers were using the stack traces. But that's
> > > not the case.
> > >
> > > We have now this couple:
> > >
> > > _ trace_buffer_lock_reserve() -> handles the ring-buffer reservation, the context info, and the type
> > > _ trace_buffer_unlock_commit() -> unlock, commit, wake and... stacktraces?
> > >
> > > In my opinion, the latter doesn't follow the logic meaning of the first.
> > > And the result is a mixup of (trace_buffer | ring_buffer)(lock/unlock/reserve/commit).
> > >
> > > You are sometimes using trace_buffer_lock_reserve followed by ring_buffer_unlock_commit.
> > > That looks a bit weird: we are using a high level function followed by its conclusion
> > > on the form of the low lovel function.
> > >
> > > I think the primary role of this new couple should be to simplify the low level ring buffer
> > > bits as it does. But the stack things should stay separated.
> >
> > Well, the whole reason for this cset was to provide a way to check for
> > things like stacktrace while reducing the number of explicit calls the
> > poor driver, oops, ftrace plugin writers had to keep in mind.
>
>
> I agree, but that forces those who don't need stacktraces to use
> a paired trace_buffer_lock_reserve() / ring_buffer_unlock_commit()
> The poor newcomers will become dizzy with these different namespaces...
> And it's like managing a file with fopen() and then close() ... :-)
>
>
> > So it may well be the case for a better name, but frankly I think that
> > this is something better left _hidden_, a magic that the plugin writers
> > doesn't have to deal with.
>
> I agree with you, the stacktraces are used by several tracers, and then
> it deserves some code factoring.
> What I would suggest is to have two different trace_buffer_unlock_commit()
>
> Thinking about the name of these functions, since they are in a higher layer
> than the ring buffer which performs some things with locking and buffers, we could
> let this latter do his tricky low level work and simply offer some magic functions
> with magic names:
>
> _ trace_reserve()
> _ trace_commit()
> _ trace_commit_stacktrace()
The point I was trying to make is that the magic is not just
stacktraces, it may well be some other whizbangfoobar that I don't know
right now.
So perhaps, we indeed need some per tracer flags where the driver writer
can state which kind of magic it _doesn't_ want performed.
The default would be: magic is in the air... I.e. do whatever magic you
may find interesting, as I can't foretell.
- Arnaldo
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit}
2009-02-06 3:10 ` Arnaldo Carvalho de Melo
@ 2009-02-08 13:04 ` Frederic Weisbecker
2009-02-08 15:17 ` Steven Rostedt
0 siblings, 1 reply; 8+ messages in thread
From: Frederic Weisbecker @ 2009-02-08 13:04 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Steven Rostedt, Ingo Molnar, Jens Axboe,
Linux Kernel Mailing List
On Fri, Feb 06, 2009 at 01:10:15AM -0200, Arnaldo Carvalho de Melo wrote:
> Em Fri, Feb 06, 2009 at 03:39:45AM +0100, Frederic Weisbecker escreveu:
> > On Thu, Feb 05, 2009 at 11:54:16PM -0200, Arnaldo Carvalho de Melo wrote:
> > > Em Thu, Feb 05, 2009 at 11:58:37PM +0100, Frederic Weisbecker escreveu:
> > > > > +void trace_buffer_unlock_commit(struct trace_array *tr,
> > > > > + struct ring_buffer_event *event,
> > > > > + unsigned long flags, int pc)
> > > > > +{
> > > > > + ring_buffer_unlock_commit(tr->buffer, event);
> > > > > +
> > > > > + ftrace_trace_stack(tr, flags, 6, pc);
> > > > > + ftrace_trace_userstack(tr, flags, pc);
> > > > > + trace_wake_up();
> > > > > +}
> > > >
> > > >
> > > > I have mitigate feelings about this part. The name of this function could
> > > > have some sense if _most_ of the tracers were using the stack traces. But that's
> > > > not the case.
> > > >
> > > > We have now this couple:
> > > >
> > > > _ trace_buffer_lock_reserve() -> handles the ring-buffer reservation, the context info, and the type
> > > > _ trace_buffer_unlock_commit() -> unlock, commit, wake and... stacktraces?
> > > >
> > > > In my opinion, the latter doesn't follow the logic meaning of the first.
> > > > And the result is a mixup of (trace_buffer | ring_buffer)(lock/unlock/reserve/commit).
> > > >
> > > > You are sometimes using trace_buffer_lock_reserve followed by ring_buffer_unlock_commit.
> > > > That looks a bit weird: we are using a high level function followed by its conclusion
> > > > on the form of the low lovel function.
> > > >
> > > > I think the primary role of this new couple should be to simplify the low level ring buffer
> > > > bits as it does. But the stack things should stay separated.
> > >
> > > Well, the whole reason for this cset was to provide a way to check for
> > > things like stacktrace while reducing the number of explicit calls the
> > > poor driver, oops, ftrace plugin writers had to keep in mind.
> >
> >
> > I agree, but that forces those who don't need stacktraces to use
> > a paired trace_buffer_lock_reserve() / ring_buffer_unlock_commit()
> > The poor newcomers will become dizzy with these different namespaces...
> > And it's like managing a file with fopen() and then close() ... :-)
> >
> >
> > > So it may well be the case for a better name, but frankly I think that
> > > this is something better left _hidden_, a magic that the plugin writers
> > > doesn't have to deal with.
> >
> > I agree with you, the stacktraces are used by several tracers, and then
> > it deserves some code factoring.
> > What I would suggest is to have two different trace_buffer_unlock_commit()
> >
> > Thinking about the name of these functions, since they are in a higher layer
> > than the ring buffer which performs some things with locking and buffers, we could
> > let this latter do his tricky low level work and simply offer some magic functions
> > with magic names:
> >
> > _ trace_reserve()
> > _ trace_commit()
> > _ trace_commit_stacktrace()
>
> The point I was trying to make is that the magic is not just
> stacktraces, it may well be some other whizbangfoobar that I don't know
> right now.
>
> So perhaps, we indeed need some per tracer flags where the driver writer
> can state which kind of magic it _doesn't_ want performed.
>
> The default would be: magic is in the air... I.e. do whatever magic you
> may find interesting, as I can't foretell.
>
> - Arnaldo
Ok, yes by making the flags per tracer, it will goes well.
Just one thing, the insertion of an event is sometimes a hot path
like with the functions tracer. And such facility adds some unused function calls
and branch checking.
But on such cases, we can use directly the ring buffer functions :-)
Frederic.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit}
2009-02-08 13:04 ` Frederic Weisbecker
@ 2009-02-08 15:17 ` Steven Rostedt
0 siblings, 0 replies; 8+ messages in thread
From: Steven Rostedt @ 2009-02-08 15:17 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: Arnaldo Carvalho de Melo, Ingo Molnar, Jens Axboe,
Linux Kernel Mailing List
On Sun, 8 Feb 2009, Frederic Weisbecker wrote:
>
>
> Ok, yes by making the flags per tracer, it will goes well.
> Just one thing, the insertion of an event is sometimes a hot path
> like with the functions tracer. And such facility adds some unused function calls
> and branch checking.
> But on such cases, we can use directly the ring buffer functions :-)
Yes, please keep the direct calls to the ring buffer on the function
tracer. The function tracer is also special, in that if we have dynamic
tracing turned on, we can simply point to a different function that does
different things depending on trace settings.
Thanks,
-- Steve
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-02-08 15:17 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-05 18:14 [PATCH tip 2/2] tracing: Introduce trace_buffer_{lock_reserve,unlock_commit} Arnaldo Carvalho de Melo
2009-02-05 22:58 ` Frederic Weisbecker
2009-02-06 1:54 ` Arnaldo Carvalho de Melo
2009-02-06 2:39 ` Frederic Weisbecker
2009-02-06 3:10 ` Arnaldo Carvalho de Melo
2009-02-08 13:04 ` Frederic Weisbecker
2009-02-08 15:17 ` Steven Rostedt
2009-02-06 0:02 ` Ingo Molnar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox