From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936561AbcIGLOe (ORCPT ); Wed, 7 Sep 2016 07:14:34 -0400 Received: from mail-pf0-f177.google.com ([209.85.192.177]:32876 "EHLO mail-pf0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S936137AbcIGLO0 (ORCPT ); Wed, 7 Sep 2016 07:14:26 -0400 From: Binoy Jayan To: "Steven Rostedt (Red Hat)" Cc: Ingo Molnar , Daniel Wagner , Arnd Bergmann , linux-kernel@vger.kernel.org, Masami , Thomas Gleixner Subject: [PATCH v6 2/4] tracing: Add hist trigger support for generic fields Date: Wed, 7 Sep 2016 16:43:53 +0530 Message-Id: <1473246835-30075-3-git-send-email-binoy.jayan@linaro.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1473246835-30075-1-git-send-email-binoy.jayan@linaro.org> References: <1473246835-30075-1-git-send-email-binoy.jayan@linaro.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Daniel Wagner Whenever a trace is printed the generic fields (CPU, COMM) are reconstructed (see trace_print_context()). CPU is taken from the trace_iterator and COMM is extracted from the savedcmd map (see __trace_find_cmdline()). We can't reconstruct this information for hist events. Therefore this information needs to be stored when a new event is added to the hist buffer. There is already support for extracting the COMM for the common_pid field. For this the tracing_map_ops infrasture is used. Unfortunately, we can't reuse it because it extends an existing hist_field. That means we first need to add a hist_field before we are able to make reuse of trace_map_ops. Furthermore, it is quite easy to extend the current code to support those two fields by adding hist_field_cpu() and hist_field_comm(). Signed-off-by: Daniel Wagner --- kernel/trace/trace_events.c | 13 +++++++------ kernel/trace/trace_events_hist.c | 36 ++++++++++++++++++++++++++++++------ 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 03c0a48..ea8da30 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -150,9 +150,10 @@ int trace_define_field(struct trace_event_call *call, const char *type, } EXPORT_SYMBOL_GPL(trace_define_field); -#define __generic_field(type, item, filter_type) \ +#define __generic_field(type, item, filter_type, size) \ ret = __trace_define_field(&ftrace_generic_fields, #type, \ - #item, 0, 0, is_signed_type(type), \ + #item, 0, size, \ + is_signed_type(type), \ filter_type); \ if (ret) \ return ret; @@ -170,10 +171,10 @@ static int trace_define_generic_fields(void) { int ret; - __generic_field(int, CPU, FILTER_CPU); - __generic_field(int, cpu, FILTER_CPU); - __generic_field(char *, COMM, FILTER_COMM); - __generic_field(char *, comm, FILTER_COMM); + __generic_field(int, CPU, FILTER_CPU, sizeof(int)); + __generic_field(int, cpu, FILTER_CPU, sizeof(int)); + __generic_field(char *, COMM, FILTER_COMM, TASK_COMM_LEN + 1); + __generic_field(char *, comm, FILTER_COMM, TASK_COMM_LEN + 1); return ret; } diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index f3a960e..42a1e36 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -75,6 +75,16 @@ static u64 hist_field_log2(struct hist_field *hist_field, void *event) return (u64) ilog2(roundup_pow_of_two(val)); } +static u64 hist_field_cpu(struct hist_field *hist_field, void *event) +{ + return (u64) smp_processor_id(); +} + +static u64 hist_field_comm(struct hist_field *hist_field, void *event) +{ + return (u64) current->comm; +} + #define DEFINE_HIST_FIELD_FN(type) \ static u64 hist_field_##type(struct hist_field *hist_field, void *event)\ { \ @@ -119,6 +129,8 @@ enum hist_field_flags { HIST_FIELD_FL_SYSCALL = 128, HIST_FIELD_FL_STACKTRACE = 256, HIST_FIELD_FL_LOG2 = 512, + HIST_FIELD_FL_CPU = 1024, + HIST_FIELD_FL_COMM = 2048, }; struct hist_trigger_attrs { @@ -374,7 +386,13 @@ static struct hist_field *create_hist_field(struct ftrace_event_field *field, if (WARN_ON_ONCE(!field)) goto out; - if (is_string_field(field)) { + if (field->filter_type == FILTER_CPU) { + flags |= HIST_FIELD_FL_CPU; + hist_field->fn = hist_field_cpu; + } else if (field->filter_type == FILTER_COMM) { + flags |= HIST_FIELD_FL_COMM; + hist_field->fn = hist_field_comm; + } else if (is_string_field(field)) { flags |= HIST_FIELD_FL_STRING; if (field->filter_type == FILTER_STATIC_STRING) @@ -748,7 +766,8 @@ static int create_tracing_map_fields(struct hist_trigger_data *hist_data) if (hist_field->flags & HIST_FIELD_FL_STACKTRACE) cmp_fn = tracing_map_cmp_none; - else if (is_string_field(field)) + else if (is_string_field(field) || + hist_field->flags & HIST_FIELD_FL_COMM) cmp_fn = tracing_map_cmp_string; else cmp_fn = tracing_map_cmp_num(field->size, @@ -856,11 +875,9 @@ static inline void add_to_key(char *compound_key, void *key, struct hist_field *key_field, void *rec) { size_t size = key_field->size; + struct ftrace_event_field *field = key_field->field; if (key_field->flags & HIST_FIELD_FL_STRING) { - struct ftrace_event_field *field; - - field = key_field->field; if (field->filter_type == FILTER_DYN_STRING) size = *(u32 *)(rec + field->offset) >> 16; else if (field->filter_type == FILTER_PTR_STRING) @@ -871,6 +888,8 @@ static inline void add_to_key(char *compound_key, void *key, /* ensure NULL-termination */ if (size > key_field->size - 1) size = key_field->size - 1; + } else if (field->filter_type == FILTER_STATIC_STRING) { + size = field->size; } memcpy(compound_key + key_field->offset, key, size); @@ -906,7 +925,8 @@ static void event_hist_trigger(struct event_trigger_data *data, void *rec) key = entries; } else { field_contents = key_field->fn(key_field, rec); - if (key_field->flags & HIST_FIELD_FL_STRING) { + if (key_field->flags & (HIST_FIELD_FL_STRING | + HIST_FIELD_FL_COMM)) { key = (void *)(unsigned long)field_contents; use_compound_key = true; } else @@ -1004,6 +1024,10 @@ hist_trigger_entry_print(struct seq_file *m, } else if (key_field->flags & HIST_FIELD_FL_STRING) { seq_printf(m, "%s: %-50s", key_field->field->name, (char *)(key + key_field->offset)); + } else if (key_field->flags & HIST_FIELD_FL_COMM) { + seq_printf(m, "%s: %-16s", + key_field->field->name, + (char *)(key + key_field->offset)); } else { uval = *(u64 *)(key + key_field->offset); seq_printf(m, "%s: %10llu", key_field->field->name, -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project