瀏覽代碼

tracing: Add hist trigger 'sym' and 'sym-offset' modifiers

Allow users to have address fields displayed as symbols in the output
by appending '.sym' or 'sym-offset' to field names:

   # echo hist:keys=aaa.sym,bbb.sym-offset ... \
              [ if filter] > event/trigger

Link: http://lkml.kernel.org/r/87d4935821491c0275513f0fbfb9bab8d3d3f079.1457029949.git.tom.zanussi@linux.intel.com

Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Tested-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Tom Zanussi 9 年之前
父節點
當前提交
c6afad49d1
共有 2 個文件被更改,包括 28 次插入5 次删除
  1. 3 1
      kernel/trace/trace.c
  2. 25 4
      kernel/trace/trace_events_hist.c

+ 3 - 1
kernel/trace/trace.c

@@ -3855,7 +3855,9 @@ static const char readme_msg[] =
 	"\t    table in its entirety to stdout.  The default format used to\n"
 	"\t    table in its entirety to stdout.  The default format used to\n"
 	"\t    display a given field can be modified by appending any of the\n"
 	"\t    display a given field can be modified by appending any of the\n"
 	"\t    following modifiers to the field name, as applicable:\n\n"
 	"\t    following modifiers to the field name, as applicable:\n\n"
-	"\t            .hex        display a number as a hex value\n\n"
+	"\t            .hex        display a number as a hex value\n"
+	"\t            .sym        display an address as a symbol\n"
+	"\t            .sym-offset display an address as a symbol and offset\n\n"
 	"\t    The 'pause' parameter can be used to pause an existing hist\n"
 	"\t    The 'pause' parameter can be used to pause an existing hist\n"
 	"\t    trigger or to start a hist trigger but not log any events\n"
 	"\t    trigger or to start a hist trigger but not log any events\n"
 	"\t    until told to do so.  'continue' can be used to start or\n"
 	"\t    until told to do so.  'continue' can be used to start or\n"

+ 25 - 4
kernel/trace/trace_events_hist.c

@@ -77,10 +77,12 @@ DEFINE_HIST_FIELD_FN(u8);
 #define HIST_KEY_SIZE_MAX	(MAX_FILTER_STR_VAL + sizeof(u64))
 #define HIST_KEY_SIZE_MAX	(MAX_FILTER_STR_VAL + sizeof(u64))
 
 
 enum hist_field_flags {
 enum hist_field_flags {
-	HIST_FIELD_FL_HITCOUNT	= 1,
-	HIST_FIELD_FL_KEY	= 2,
-	HIST_FIELD_FL_STRING	= 4,
-	HIST_FIELD_FL_HEX	= 8,
+	HIST_FIELD_FL_HITCOUNT		= 1,
+	HIST_FIELD_FL_KEY		= 2,
+	HIST_FIELD_FL_STRING		= 4,
+	HIST_FIELD_FL_HEX		= 8,
+	HIST_FIELD_FL_SYM		= 16,
+	HIST_FIELD_FL_SYM_OFFSET	= 32,
 };
 };
 
 
 struct hist_trigger_attrs {
 struct hist_trigger_attrs {
@@ -397,6 +399,10 @@ static int create_key_field(struct hist_trigger_data *hist_data,
 	if (field_str) {
 	if (field_str) {
 		if (strcmp(field_str, "hex") == 0)
 		if (strcmp(field_str, "hex") == 0)
 			flags |= HIST_FIELD_FL_HEX;
 			flags |= HIST_FIELD_FL_HEX;
+		else if (strcmp(field_str, "sym") == 0)
+			flags |= HIST_FIELD_FL_SYM;
+		else if (strcmp(field_str, "sym-offset") == 0)
+			flags |= HIST_FIELD_FL_SYM_OFFSET;
 		else {
 		else {
 			ret = -EINVAL;
 			ret = -EINVAL;
 			goto out;
 			goto out;
@@ -726,6 +732,7 @@ hist_trigger_entry_print(struct seq_file *m,
 			 struct tracing_map_elt *elt)
 			 struct tracing_map_elt *elt)
 {
 {
 	struct hist_field *key_field;
 	struct hist_field *key_field;
+	char str[KSYM_SYMBOL_LEN];
 	unsigned int i;
 	unsigned int i;
 	u64 uval;
 	u64 uval;
 
 
@@ -741,6 +748,16 @@ hist_trigger_entry_print(struct seq_file *m,
 			uval = *(u64 *)(key + key_field->offset);
 			uval = *(u64 *)(key + key_field->offset);
 			seq_printf(m, "%s: %llx",
 			seq_printf(m, "%s: %llx",
 				   key_field->field->name, uval);
 				   key_field->field->name, uval);
+		} else if (key_field->flags & HIST_FIELD_FL_SYM) {
+			uval = *(u64 *)(key + key_field->offset);
+			sprint_symbol_no_offset(str, uval);
+			seq_printf(m, "%s: [%llx] %-45s",
+				   key_field->field->name, uval, str);
+		} else if (key_field->flags & HIST_FIELD_FL_SYM_OFFSET) {
+			uval = *(u64 *)(key + key_field->offset);
+			sprint_symbol(str, uval);
+			seq_printf(m, "%s: [%llx] %-55s",
+				   key_field->field->name, uval, str);
 		} else if (key_field->flags & HIST_FIELD_FL_STRING) {
 		} else if (key_field->flags & HIST_FIELD_FL_STRING) {
 			seq_printf(m, "%s: %-50s", key_field->field->name,
 			seq_printf(m, "%s: %-50s", key_field->field->name,
 				   (char *)(key + key_field->offset));
 				   (char *)(key + key_field->offset));
@@ -856,6 +873,10 @@ static const char *get_hist_field_flags(struct hist_field *hist_field)
 
 
 	if (hist_field->flags & HIST_FIELD_FL_HEX)
 	if (hist_field->flags & HIST_FIELD_FL_HEX)
 		flags_str = "hex";
 		flags_str = "hex";
+	else if (hist_field->flags & HIST_FIELD_FL_SYM)
+		flags_str = "sym";
+	else if (hist_field->flags & HIST_FIELD_FL_SYM_OFFSET)
+		flags_str = "sym-offset";
 
 
 	return flags_str;
 	return flags_str;
 }
 }