Skip to content
Permalink
Browse files
tracing: Merge irqflags + preemt counter, add RT bits
PREEMPT_RT never reported "serving softirq". I took a look to see if it
could be changed. The tracing infrastructure examinates the preemtion
counter for that. PREEMPT_RT does not change the preemption counter
while disabling the bottom half or serving the softirqs in order to
remain preemptible. The in_serving_softirq() macro and the SOFTIRQ_OFFSET
define are still working but not on the preempt-counter.
I started to look how to integrate the RT bits regarding softirq.

The state of the interrupts (irqflags) and the preemption counter are
passed down to tracing_generic_entry_update(). However only one bit of
irqflags is actually required: The on/off state.
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 16bit as the preemption counter (considering
that 1 must be substracted from the counter in some cases).

Whith this change the preemption counter is read in one place and the
relevant RT bits for softirq can be set there.

The actual preemption value is not used except for the tracing record.
The `irqflags' is also not used except for the _irqsave() locking in a
few spots.
As part of the patch I added __ to trace_event_buffer_commit() while
evaluating trace_event_buffer() for the struct trace_event_buffer usage
regarding the `pc' and `flags' members. It appears that those two can
also be merged into the `trace_ctx' integer.
With this change the callchain passes one argument less and evaluates
the flags early. A build with all tracers enabled on x86-64 with and
without the patch:

    text     data      bss      dec      hex    filename
24301717 22148594 13996284 60446595  39a5783 vmlinux.old
24301248 22148850 13996284 60446382  39a56ae vmlinux.new

data increased by 256 bytes, text shrank by 469 bytes.

Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
  • Loading branch information
Sebastian Andrzej Siewior authored and intel-lab-lkp committed Dec 16, 2020
1 parent 9317f94 commit afd5d9090ab105dae5830c2f050a30ec306d7201
Show file tree
Hide file tree
Showing 18 changed files with 293 additions and 272 deletions.
@@ -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_flags(void);
unsigned int tracing_gen_ctx_flags_dect(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)
@@ -232,16 +244,15 @@ 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;
};

void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
struct trace_event_file *trace_file,
unsigned long len);

void trace_event_buffer_commit(struct trace_event_buffer *fbuffer);
void trace_event_buffer_commit__(struct trace_event_buffer *fbuffer);

enum {
TRACE_EVENT_FL_FILTERED_BIT,
@@ -694,7 +694,7 @@ trace_event_raw_event_##call(void *__data, proto) \
\
{ assign; } \
\
trace_event_buffer_commit(&fbuffer); \
trace_event_buffer_commit__(&fbuffer); \
}
/*
* The ftrace_test_probe is compiled out, it is only here as a build time check
@@ -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);
@@ -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);
}
}

@@ -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;

@@ -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);
@@ -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;
}
}

0 comments on commit afd5d90

Please sign in to comment.