Blob Blame History Raw
From 6f10a5b14f5b7f43568d109633533a8ecc057fc6 Mon Sep 17 00:00:00 2001
From: Lars Friend <l.friend@f5.com>
Date: Tue, 15 Oct 2013 01:14:53 -0400
Subject: [PATCH] Allow events with extra flags to also set unit_mask

Older distributions may be running kernels that still use the
/dev/opcontrol interface.  On an Intel Ivy Bridge machine and similar
processors may want to do something like:

opcontrol --setup --no-vmlinux \
 --event CPU_CLK_UNHALTED:2000000:0:0:1 \
 --event uops_executed:2000000:stall_cycles:0:1

For the uops_executed event in the above example need to both set the
extra and the unit_mask bits.  The current code in opcontrol would
never set the unit_mask bits when the extra bits were set.  This
change allows both to be set when required.

Signed-off-by: William Cohen <wcohen@redhat.com>
---
 doc/ophelp.1.in |  4 ++++
 utils/opcontrol |  9 +++++++--
 utils/ophelp.c  | 27 ++++++++++++++++++++++++++-
 3 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/doc/ophelp.1.in b/doc/ophelp.1.in
index 083cc85..97383bf 100644
--- a/doc/ophelp.1.in
+++ b/doc/ophelp.1.in
@@ -49,6 +49,10 @@ Show the default unit mask for the given event.
 Show the default unit mask for the given event.
 .br
 .TP
+.BI "--symbolic-unit-mask / -U [event]"
+Show the numerical unit and extra mask for given event.
+.br
+.TP
 .BI "--extra-mask / -E [event]"
 Show the extra unit mask for given event.
 .br
diff --git a/utils/opcontrol b/utils/opcontrol
index 38bb1ac..a3a6a3c 100644
--- a/utils/opcontrol
+++ b/utils/opcontrol
@@ -1522,9 +1522,14 @@ do_param_setup()
 				set_ctr_param $CTR count $COUNT
 				set_ctr_param $CTR kernel $KERNEL
 				set_ctr_param $CTR user $USER
-				set_ctr_param $CTR unit_mask $UNIT_MASK
 
-				EXTRA=`$OPHELP --extra-mask $EVENT:$COUNT:$UNIT_MASK_NAMED`
+				# Resolve a [potentially] symbolic unit mask to a numeric
+				# unit mask and extra mask.
+				TMP_SYMBOLIC="`$OPHELP --symbolic-unit-mask $EVENT:$COUNT:$UNIT_MASK`"
+				UNIT_MASK_NUM=`echo $TMP_SYMBOLIC | awk '{print $1}'`
+				EXTRA=`echo $TMP_SYMBOLIC | awk '{print $2}'`
+				set_ctr_param $CTR unit_mask $UNIT_MASK_NUM
+
 				if test "$EXTRA" -ne 0 ; then
 				# A value >= 0x40000 returned by 'ophelp --extra-mask' (EXTRA_MIN_VAL) is interpreted
 				# as a valid extra value; otherwise we interpret as a simple unit mask value
diff --git a/utils/ophelp.c b/utils/ophelp.c
index 7543c6f..f77a19a 100644
--- a/utils/ophelp.c
+++ b/utils/ophelp.c
@@ -282,6 +282,22 @@ static void resolve_events(void)
 	free(counter_map);
 }
 
+static void resolve_symbolic_unit_mask(void)
+{
+	size_t count;
+	unsigned extra = 0;
+
+	count = parse_events(parsed_events, num_chosen_events, chosen_events,
+	                     ignore_count ? 0 : 1);
+	if (count > 1) {
+		fprintf(stderr, "More than one event specified.\n");
+                exit(EXIT_FAILURE);
+        }
+
+	op_resolve_unit_mask(parsed_events, &extra);
+
+	printf("%d %d\n", parsed_events[0].unit_mask, extra);
+}
 
 static void show_unit_mask(void)
 {
@@ -334,6 +349,7 @@ static int check_events;
 static int unit_mask;
 static int get_default_event;
 static int extra_mask;
+static int symbolic_unit_mask;
 
 static struct poptOption options[] = {
 	{ "cpu-type", 'c', POPT_ARG_STRING, &cpu_string, 0,
@@ -356,6 +372,9 @@ static struct poptOption options[] = {
 	   "list events as XML", NULL, },
 	{ "extra-mask", 'E', POPT_ARG_NONE, &extra_mask, 0,
 	  "print extra mask for event", NULL, },
+	{ "symbolic-unit-mask", 'U', POPT_ARG_NONE, &symbolic_unit_mask, 0,
+	  "resolve an event with symbolic unit mask into numeric unit "
+	  "and extra masks", NULL, },
 	POPT_AUTOHELP
 	{ NULL, 0, 0, NULL, 0, NULL, NULL, },
 };
@@ -457,11 +476,17 @@ int main(int argc, char const * argv[])
 
 	events = op_events(cpu_type);
 
-	if (!chosen_events && (unit_mask || check_events || extra_mask)) {
+	if (!chosen_events && (unit_mask || check_events || extra_mask ||
+			symbolic_unit_mask)) {
 		fprintf(stderr, "No events given.\n");
 		exit(EXIT_FAILURE);
 	}
 
+	if (symbolic_unit_mask) {
+		resolve_symbolic_unit_mask();
+		exit(EXIT_SUCCESS);
+	}
+
 	if (unit_mask) {
 		show_unit_mask();
 		exit(EXIT_SUCCESS);
-- 
1.8.3.1