Merge branch 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'tracing-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf_counter: Fix/complete ftrace event records sampling perf_counter, ftrace: Fix perf_counter integration tracing/filters: Always free pred on filter_add_subsystem_pred() failure tracing/filters: Don't use pred on alloc failure ring-buffer: Fix memleak in ring_buffer_free() tracing: Fix recordmcount.pl to handle sections with only weak functions ring-buffer: Fix advance of reader in rb_buffer_peek() tracing: do not use functions starting with .L in recordmcount.pl ring-buffer: do not disable ring buffer on oops_in_progress ring-buffer: fix check of try_to_discard result
This commit is contained in:
@@ -2646,6 +2646,7 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
|
||||
u64 counter;
|
||||
} group_entry;
|
||||
struct perf_callchain_entry *callchain = NULL;
|
||||
struct perf_tracepoint_record *tp;
|
||||
int callchain_size = 0;
|
||||
u64 time;
|
||||
struct {
|
||||
@@ -2714,6 +2715,11 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
|
||||
header.size += sizeof(u64);
|
||||
}
|
||||
|
||||
if (sample_type & PERF_SAMPLE_TP_RECORD) {
|
||||
tp = data->private;
|
||||
header.size += tp->size;
|
||||
}
|
||||
|
||||
ret = perf_output_begin(&handle, counter, header.size, nmi, 1);
|
||||
if (ret)
|
||||
return;
|
||||
@@ -2777,6 +2783,9 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
|
||||
}
|
||||
}
|
||||
|
||||
if (sample_type & PERF_SAMPLE_TP_RECORD)
|
||||
perf_output_copy(&handle, tp->record, tp->size);
|
||||
|
||||
perf_output_end(&handle);
|
||||
}
|
||||
|
||||
@@ -3703,17 +3712,24 @@ static const struct pmu perf_ops_task_clock = {
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EVENT_PROFILE
|
||||
void perf_tpcounter_event(int event_id)
|
||||
void perf_tpcounter_event(int event_id, u64 addr, u64 count, void *record,
|
||||
int entry_size)
|
||||
{
|
||||
struct perf_tracepoint_record tp = {
|
||||
.size = entry_size,
|
||||
.record = record,
|
||||
};
|
||||
|
||||
struct perf_sample_data data = {
|
||||
.regs = get_irq_regs(),
|
||||
.addr = 0,
|
||||
.addr = addr,
|
||||
.private = &tp,
|
||||
};
|
||||
|
||||
if (!data.regs)
|
||||
data.regs = task_pt_regs(current);
|
||||
|
||||
do_perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, 1, 1, &data);
|
||||
do_perf_swcounter_event(PERF_TYPE_TRACEPOINT, event_id, count, 1, &data);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(perf_tpcounter_event);
|
||||
|
||||
|
@@ -735,6 +735,7 @@ ring_buffer_free(struct ring_buffer *buffer)
|
||||
|
||||
put_online_cpus();
|
||||
|
||||
kfree(buffer->buffers);
|
||||
free_cpumask_var(buffer->cpumask);
|
||||
|
||||
kfree(buffer);
|
||||
@@ -1785,7 +1786,7 @@ void ring_buffer_discard_commit(struct ring_buffer *buffer,
|
||||
*/
|
||||
RB_WARN_ON(buffer, !local_read(&cpu_buffer->committing));
|
||||
|
||||
if (!rb_try_to_discard(cpu_buffer, event))
|
||||
if (rb_try_to_discard(cpu_buffer, event))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
@@ -2383,7 +2384,6 @@ rb_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
|
||||
* the box. Return the padding, and we will release
|
||||
* the current locks, and try again.
|
||||
*/
|
||||
rb_advance_reader(cpu_buffer);
|
||||
return event;
|
||||
|
||||
case RINGBUF_TYPE_TIME_EXTEND:
|
||||
@@ -2486,7 +2486,7 @@ static inline int rb_ok_to_lock(void)
|
||||
* buffer too. A one time deal is all you get from reading
|
||||
* the ring buffer from an NMI.
|
||||
*/
|
||||
if (likely(!in_nmi() && !oops_in_progress))
|
||||
if (likely(!in_nmi()))
|
||||
return 1;
|
||||
|
||||
tracing_off_permanent();
|
||||
@@ -2519,6 +2519,8 @@ ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
|
||||
if (dolock)
|
||||
spin_lock(&cpu_buffer->reader_lock);
|
||||
event = rb_buffer_peek(buffer, cpu, ts);
|
||||
if (event && event->type_len == RINGBUF_TYPE_PADDING)
|
||||
rb_advance_reader(cpu_buffer);
|
||||
if (dolock)
|
||||
spin_unlock(&cpu_buffer->reader_lock);
|
||||
local_irq_restore(flags);
|
||||
@@ -2590,12 +2592,9 @@ ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
|
||||
spin_lock(&cpu_buffer->reader_lock);
|
||||
|
||||
event = rb_buffer_peek(buffer, cpu, ts);
|
||||
if (!event)
|
||||
goto out_unlock;
|
||||
if (event)
|
||||
rb_advance_reader(cpu_buffer);
|
||||
|
||||
rb_advance_reader(cpu_buffer);
|
||||
|
||||
out_unlock:
|
||||
if (dolock)
|
||||
spin_unlock(&cpu_buffer->reader_lock);
|
||||
local_irq_restore(flags);
|
||||
|
@@ -848,6 +848,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
|
||||
((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
|
||||
(need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tracing_generic_entry_update);
|
||||
|
||||
struct ring_buffer_event *trace_buffer_lock_reserve(struct trace_array *tr,
|
||||
int type,
|
||||
|
@@ -438,10 +438,6 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
|
||||
struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
|
||||
int *ent_cpu, u64 *ent_ts);
|
||||
|
||||
void tracing_generic_entry_update(struct trace_entry *entry,
|
||||
unsigned long flags,
|
||||
int pc);
|
||||
|
||||
void default_wait_pipe(struct trace_iterator *iter);
|
||||
void poll_wait_pipe(struct trace_iterator *iter);
|
||||
|
||||
|
@@ -624,9 +624,6 @@ static int filter_add_subsystem_pred(struct filter_parse_state *ps,
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
filter->preds[filter->n_preds] = pred;
|
||||
filter->n_preds++;
|
||||
|
||||
list_for_each_entry(call, &ftrace_events, list) {
|
||||
|
||||
if (!call->define_fields)
|
||||
@@ -643,6 +640,9 @@ static int filter_add_subsystem_pred(struct filter_parse_state *ps,
|
||||
}
|
||||
replace_filter_string(call->filter, filter_string);
|
||||
}
|
||||
|
||||
filter->preds[filter->n_preds] = pred;
|
||||
filter->n_preds++;
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
@@ -1029,12 +1029,17 @@ static int replace_preds(struct event_subsystem *system,
|
||||
|
||||
if (elt->op == OP_AND || elt->op == OP_OR) {
|
||||
pred = create_logical_pred(elt->op);
|
||||
if (!pred)
|
||||
return -ENOMEM;
|
||||
if (call) {
|
||||
err = filter_add_pred(ps, call, pred);
|
||||
filter_free_pred(pred);
|
||||
} else
|
||||
} else {
|
||||
err = filter_add_subsystem_pred(ps, system,
|
||||
pred, filter_string);
|
||||
if (err)
|
||||
filter_free_pred(pred);
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1048,12 +1053,17 @@ static int replace_preds(struct event_subsystem *system,
|
||||
}
|
||||
|
||||
pred = create_pred(elt->op, operand1, operand2);
|
||||
if (!pred)
|
||||
return -ENOMEM;
|
||||
if (call) {
|
||||
err = filter_add_pred(ps, call, pred);
|
||||
filter_free_pred(pred);
|
||||
} else
|
||||
} else {
|
||||
err = filter_add_subsystem_pred(ps, system, pred,
|
||||
filter_string);
|
||||
if (err)
|
||||
filter_free_pred(pred);
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
Reference in New Issue
Block a user