From 0456679ed9444d153c60e41dfc556b7ca4d6277f Mon Sep 17 00:00:00 2001
From: Sheng Yang <[EMAIL PROTECTED]>
Date: Wed, 25 Jun 2008 16:40:56 +0800
Subject: [PATCH] kvm: user: Add event mask support in kvmtrace.

Signed-off-by: Feng (Eric) Liu <[EMAIL PROTECTED]>
---
 user/kvmtrace.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/user/kvmtrace.c b/user/kvmtrace.c
index 876ac27..a7b2071 100644
--- a/user/kvmtrace.c
+++ b/user/kvmtrace.c
@@ -54,7 +54,7 @@ static char kvmtrace_version[] = "0.1";

 #define max(a, b)      ((a) > (b) ? (a) : (b))

-#define S_OPTS "r:o:w:?Vb:n:D:"
+#define S_OPTS "r:o:w:?Vb:n:D:e:"
 static struct option l_opts[] = {
        {
                .name = "relay",
@@ -99,6 +99,12 @@ static struct option l_opts[] = {
                .val = 'D'
        },
        {
+               .name = "event_mask",
+               .has_arg = required_argument,
+               .flag = NULL,
+               .val = 'e'
+       },
+       {
                .name = NULL,
        }
 };
@@ -154,6 +160,8 @@ static char *output_dir;
 static int stop_watch;
 static unsigned long buf_size = BUF_SIZE;
 static unsigned long buf_nr = BUF_NR;
+static int cat_mask = ~0u;
+static unsigned long long act_bitmap[16];
 static unsigned int page_size;

 #define for_each_cpu_online(cpu) \
@@ -175,6 +183,13 @@ static void handle_sigint(__attribute__((__unused__)) int 
sig)
        done = 1;
 }

+static inline int valid_mask_opt(int x)
+{
+       return ((1 << KVM_TRC_SHIFT) <= x) &&
+              (x < (1 << (KVM_TRC_CAT_NR_BITS + KVM_TRC_SHIFT))) &&
+              (0 <= KVM_TRC_ACT(x)) && (KVM_TRC_ACT(x) < 64);
+}
+
 static int get_lost_records()
 {
        int fd;
@@ -473,6 +488,8 @@ static int start_trace(void)
        memset(&kuts, 0, sizeof(kuts));
        kuts.buf_size = trace_information.buf_size = buf_size;
        kuts.buf_nr = trace_information.buf_nr = buf_nr;
+       kuts.cat_mask = cat_mask;
+       memcpy(kuts.act_bitmap, act_bitmap, sizeof(act_bitmap));

        if (ioctl(trace_information.fd , KVM_TRACE_ENABLE, &kuts) < 0) {
                perror("KVM_TRACE_ENABLE");
@@ -587,13 +604,21 @@ static void show_stats(void)

 static char usage_str[] = \
        "[ -r debugfs path ] [ -D output dir ] [ -b buffer size ]\n" \
-       "[ -n number of buffers] [ -o <output file> ] [ -w time  ] [ -V ]\n\n" \
+       "[ -n number of buffers] [ -o <output file> ] [ -e event mask ]" \
+       "[ -w time ] [ -V ]\n\n" \
        "\t-r Path to mounted debugfs, defaults to /sys/kernel/debug\n" \
        "\t-o File(s) to send output to\n" \
        "\t-D Directory to prepend to output file names\n" \
        "\t-w Stop after defined time, in seconds\n" \
        "\t-b Sub buffer size in KiB\n" \
        "\t-n Number of sub buffers\n" \
+       "\t-e Only trace specified categories or actions.\n" \
+       "\t   kvmtrace defaults to collecting all events can be traced.\n" \
+       "\t   To limit the events being captured, you can specify filter.\n" \
+       "\t   if you want to trace all the actions of one category," \
+       " set action to zero. \n" \
+       "\t   eg: -e 0x00010000 -e 00020001 trace entryexit and PAGE_FAULT \n" \
+       "\t       -e 0x00020005 -e 00020006 trace IO_READ and IO_WRITE. \n" \
        "\t-V Print program version info\n\n";

 static void show_usage(char *prog)
@@ -604,7 +629,7 @@ static void show_usage(char *prog)

 void parse_args(int argc, char **argv)
 {
-       int c;
+       int c, cat_mask_tmp = 0;

        while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) >= 0) {
                switch (c) {
@@ -647,6 +672,26 @@ void parse_args(int argc, char **argv)
                case 'D':
                        output_dir = optarg;
                        break;
+               case 'e': {
+                       int index, mask;
+
+                       if ((sscanf(optarg, "%x", &mask) != 1) ||
+                                                       !valid_mask_opt(mask)) {
+                               fprintf(stderr,
+                                       "Invalid event mask (%u)\n", mask);
+                               exit(EXIT_FAILURE);
+                       }
+                       cat_mask_tmp |= KVM_TRC_CAT(mask);
+                       index = ffs(KVM_TRC_CAT(mask)) - 1;
+                       if (KVM_TRC_ACT(mask) == 0)
+                               act_bitmap[index] = ~0ull;
+                       else {
+                               if (act_bitmap[index] == ~0ull)
+                                       act_bitmap[index] = 0;
+                               act_bitmap[index] |= 1 << KVM_TRC_ACT(mask);
+                       }
+                       break;
+               }
                default:
                        show_usage(argv[0]);
                }
@@ -654,12 +699,17 @@ void parse_args(int argc, char **argv)

        if (optind < argc || output_name == NULL)
                show_usage(argv[0]);
+
+       if (cat_mask_tmp != 0)
+               cat_mask = cat_mask_tmp;
 }

 int main(int argc, char *argv[])
 {
        struct statfs st;

+       memset(act_bitmap, ~0u, sizeof(act_bitmap));
+
        parse_args(argc, argv);

        if (!debugfs_path)
--
1.5.5

From 0456679ed9444d153c60e41dfc556b7ca4d6277f Mon Sep 17 00:00:00 2001
From: Sheng Yang <[EMAIL PROTECTED]>
Date: Wed, 25 Jun 2008 16:40:56 +0800
Subject: [PATCH] kvm: user: Add event mask support in kvmtrace.

Signed-off-by: Feng (Eric) Liu <[EMAIL PROTECTED]>
---
 user/kvmtrace.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/user/kvmtrace.c b/user/kvmtrace.c
index 876ac27..a7b2071 100644
--- a/user/kvmtrace.c
+++ b/user/kvmtrace.c
@@ -54,7 +54,7 @@ static char kvmtrace_version[] = "0.1";
 
 #define max(a, b)	((a) > (b) ? (a) : (b))
 
-#define S_OPTS	"r:o:w:?Vb:n:D:"
+#define S_OPTS	"r:o:w:?Vb:n:D:e:"
 static struct option l_opts[] = {
 	{
 		.name = "relay",
@@ -99,6 +99,12 @@ static struct option l_opts[] = {
 		.val = 'D'
 	},
 	{
+		.name = "event_mask",
+		.has_arg = required_argument,
+		.flag = NULL,
+		.val = 'e'
+	},
+	{
 		.name = NULL,
 	}
 };
@@ -154,6 +160,8 @@ static char *output_dir;
 static int stop_watch;
 static unsigned long buf_size = BUF_SIZE;
 static unsigned long buf_nr = BUF_NR;
+static int cat_mask = ~0u;
+static unsigned long long act_bitmap[16];
 static unsigned int page_size;
 
 #define for_each_cpu_online(cpu) \
@@ -175,6 +183,13 @@ static void handle_sigint(__attribute__((__unused__)) int sig)
 	done = 1;
 }
 
+static inline int valid_mask_opt(int x)
+{
+	return ((1 << KVM_TRC_SHIFT) <= x) &&
+	       (x < (1 << (KVM_TRC_CAT_NR_BITS + KVM_TRC_SHIFT))) &&
+	       (0 <= KVM_TRC_ACT(x)) && (KVM_TRC_ACT(x) < 64);
+}
+
 static int get_lost_records()
 {
 	int fd;
@@ -473,6 +488,8 @@ static int start_trace(void)
 	memset(&kuts, 0, sizeof(kuts));
 	kuts.buf_size = trace_information.buf_size = buf_size;
 	kuts.buf_nr = trace_information.buf_nr = buf_nr;
+	kuts.cat_mask = cat_mask;
+	memcpy(kuts.act_bitmap, act_bitmap, sizeof(act_bitmap));
 
 	if (ioctl(trace_information.fd , KVM_TRACE_ENABLE, &kuts) < 0) {
 		perror("KVM_TRACE_ENABLE");
@@ -587,13 +604,21 @@ static void show_stats(void)
 
 static char usage_str[] = \
 	"[ -r debugfs path ] [ -D output dir ] [ -b buffer size ]\n" \
-	"[ -n number of buffers] [ -o <output file> ] [ -w time  ] [ -V ]\n\n" \
+	"[ -n number of buffers] [ -o <output file> ] [ -e event mask ]" \
+	"[ -w time ] [ -V ]\n\n" \
 	"\t-r Path to mounted debugfs, defaults to /sys/kernel/debug\n" \
 	"\t-o File(s) to send output to\n" \
 	"\t-D Directory to prepend to output file names\n" \
 	"\t-w Stop after defined time, in seconds\n" \
 	"\t-b Sub buffer size in KiB\n" \
 	"\t-n Number of sub buffers\n" \
+	"\t-e Only trace specified categories or actions.\n" \
+	"\t   kvmtrace defaults to collecting all events can be traced.\n" \
+	"\t   To limit the events being captured, you can specify filter.\n" \
+	"\t   if you want to trace all the actions of one category," \
+	" set action to zero. \n" \
+	"\t   eg: -e 0x00010000 -e 00020001 trace entryexit and PAGE_FAULT \n" \
+	"\t       -e 0x00020005 -e 00020006 trace IO_READ and IO_WRITE. \n" \
 	"\t-V Print program version info\n\n";
 
 static void show_usage(char *prog)
@@ -604,7 +629,7 @@ static void show_usage(char *prog)
 
 void parse_args(int argc, char **argv)
 {
-	int c;
+	int c, cat_mask_tmp = 0;
 
 	while ((c = getopt_long(argc, argv, S_OPTS, l_opts, NULL)) >= 0) {
 		switch (c) {
@@ -647,6 +672,26 @@ void parse_args(int argc, char **argv)
 		case 'D':
 			output_dir = optarg;
 			break;
+		case 'e': {
+			int index, mask;
+
+			if ((sscanf(optarg, "%x", &mask) != 1) ||
+							!valid_mask_opt(mask)) {
+				fprintf(stderr,
+					"Invalid event mask (%u)\n", mask);
+				exit(EXIT_FAILURE);
+			}
+			cat_mask_tmp |= KVM_TRC_CAT(mask);
+			index = ffs(KVM_TRC_CAT(mask)) - 1;
+			if (KVM_TRC_ACT(mask) == 0)
+				act_bitmap[index] = ~0ull;
+			else {
+				if (act_bitmap[index] == ~0ull)
+					act_bitmap[index] = 0;
+				act_bitmap[index] |= 1 << KVM_TRC_ACT(mask);
+			}
+			break;
+		}
 		default:
 			show_usage(argv[0]);
 		}
@@ -654,12 +699,17 @@ void parse_args(int argc, char **argv)
 
 	if (optind < argc || output_name == NULL)
 		show_usage(argv[0]);
+
+	if (cat_mask_tmp != 0)
+		cat_mask = cat_mask_tmp;
 }
 
 int main(int argc, char *argv[])
 {
 	struct statfs st;
 
+	memset(act_bitmap, ~0u, sizeof(act_bitmap));
+
 	parse_args(argc, argv);
 
 	if (!debugfs_path)
-- 
1.5.5

Reply via email to