Skip to content

Commit

Permalink
tracing: Merge irqflags + preempt counter.
Browse files Browse the repository at this point in the history
The state of the interrupts (irqflags) and the preemption counter are
both passed down to tracing_generic_entry_update(). Only one bit of
irqflags is actually required: The on/off state. The complete 32bit
of the preemption counter isn't needed. Just whether of the upper bits
(softirq, hardirq and NMI) are set and the preemption depth is needed.

The irqflags and the preemption counter could be evaluated early and the
information stored in an integer `trace_ctx'.
tracing_generic_entry_update() would use the upper bits as the
TRACE_FLAG_* and the lower 8bit as the disabled-preemption depth
(considering that one must be substracted from the counter in one
special cases).

The actual preemption value is not used except for the tracing record.
The `irqflags' variable is mostly used only for the tracing record. An
exception here is for instance wakeup_tracer_call() or
probe_wakeup_sched_switch() which explicilty disable interrupts and use
that `irqflags' to save (and restore) the IRQ state and to record the
state.

Struct trace_event_buffer has also the `pc' and flags' members which can
be replaced with `trace_ctx' since their actual value is not used
outside of trace recording.

This will reduce tracing_generic_entry_update() to simply assign values
to struct trace_entry. The evaluation of the TRACE_FLAG_* bits is moved
to _tracing_gen_ctx_flags() which replaces preempt_count() and
local_save_flags() invocations.

As an example, ftrace_syscall_enter() may invoke:
- trace_buffer_lock_reserve() -> … -> tracing_generic_entry_update()
- event_trigger_unlock_commit()
  -> ftrace_trace_stack() -> … -> tracing_generic_entry_update()
  -> ftrace_trace_userstack() -> … -> tracing_generic_entry_update()

In this case the TRACE_FLAG_* bits were evaluated three times. By using
the `trace_ctx' they are evaluated once and assigned three times.

A build with all tracers enabled on x86-64 with and without the patch:

    text     data      bss      dec      hex    filename
21970669 17084168  7639260 46694097  2c87ed1 vmlinux.old
21970293 17084168  7639260 46693721  2c87d59 vmlinux.new

text shrank by 379 bytes, data remained constant.

Link: https://lkml.kernel.org/r/20210125194511.3924915-2-bigeasy@linutronix.de

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
  • Loading branch information
Sebastian Andrzej Siewior authored and Steven Rostedt (VMware) committed Feb 2, 2021
1 parent c6358ba commit 36590c5
Show file tree
Hide file tree
Showing 17 changed files with 287 additions and 308 deletions.
25 changes: 18 additions & 7 deletions include/linux/trace_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,29 @@ enum print_line_t {

enum print_line_t trace_handle_return(struct trace_seq *s);

void tracing_generic_entry_update(struct trace_entry *entry,
unsigned short type,
unsigned long flags,
int pc);
static inline void tracing_generic_entry_update(struct trace_entry *entry,
unsigned short type,
unsigned int trace_ctx)
{
struct task_struct *tsk = current;

entry->preempt_count = trace_ctx & 0xff;
entry->pid = (tsk) ? tsk->pid : 0;
entry->type = type;
entry->flags = trace_ctx >> 16;
}

unsigned int tracing_gen_ctx_flags(unsigned long irqflags);
unsigned int tracing_gen_ctx(void);
unsigned int tracing_gen_ctx_dec(void);

struct trace_event_file;

struct ring_buffer_event *
trace_event_buffer_lock_reserve(struct trace_buffer **current_buffer,
struct trace_event_file *trace_file,
int type, unsigned long len,
unsigned long flags, int pc);
unsigned int trace_ctx);

#define TRACE_RECORD_CMDLINE BIT(0)
#define TRACE_RECORD_TGID BIT(1)
Expand Down Expand Up @@ -232,8 +244,7 @@ struct trace_event_buffer {
struct ring_buffer_event *event;
struct trace_event_file *trace_file;
void *entry;
unsigned long flags;
int pc;
unsigned int trace_ctx;
struct pt_regs *regs;
};

Expand Down
17 changes: 9 additions & 8 deletions kernel/trace/blktrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,17 @@ static void trace_note(struct blk_trace *bt, pid_t pid, int action,
struct blk_io_trace *t;
struct ring_buffer_event *event = NULL;
struct trace_buffer *buffer = NULL;
int pc = 0;
unsigned int trace_ctx = 0;
int cpu = smp_processor_id();
bool blk_tracer = blk_tracer_enabled;
ssize_t cgid_len = cgid ? sizeof(cgid) : 0;

if (blk_tracer) {
buffer = blk_tr->array_buffer.buffer;
pc = preempt_count();
trace_ctx = tracing_gen_ctx_flags(0);
event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
sizeof(*t) + len + cgid_len,
0, pc);
trace_ctx);
if (!event)
return;
t = ring_buffer_event_data(event);
Expand All @@ -107,7 +107,7 @@ static void trace_note(struct blk_trace *bt, pid_t pid, int action,
memcpy((void *) t + sizeof(*t) + cgid_len, data, len);

if (blk_tracer)
trace_buffer_unlock_commit(blk_tr, buffer, event, 0, pc);
trace_buffer_unlock_commit(blk_tr, buffer, event, trace_ctx);
}
}

Expand Down Expand Up @@ -222,8 +222,9 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
struct blk_io_trace *t;
unsigned long flags = 0;
unsigned long *sequence;
unsigned int trace_ctx = 0;
pid_t pid;
int cpu, pc = 0;
int cpu;
bool blk_tracer = blk_tracer_enabled;
ssize_t cgid_len = cgid ? sizeof(cgid) : 0;

Expand Down Expand Up @@ -252,10 +253,10 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
tracing_record_cmdline(current);

buffer = blk_tr->array_buffer.buffer;
pc = preempt_count();
trace_ctx = tracing_gen_ctx_flags(0);
event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
sizeof(*t) + pdu_len + cgid_len,
0, pc);
trace_ctx);
if (!event)
return;
t = ring_buffer_event_data(event);
Expand Down Expand Up @@ -301,7 +302,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
memcpy((void *)t + sizeof(*t) + cgid_len, pdu_data, pdu_len);

if (blk_tracer) {
trace_buffer_unlock_commit(blk_tr, buffer, event, 0, pc);
trace_buffer_unlock_commit(blk_tr, buffer, event, trace_ctx);
return;
}
}
Expand Down
Loading

0 comments on commit 36590c5

Please sign in to comment.