WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 3 of 4] Improve xentrace to use VIRQ_TBUF interrupts

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 3 of 4] Improve xentrace to use VIRQ_TBUF interrupts as well as a user-specified
From: Michael.Fetterman@xxxxxxxxxxxx
Date: Sat, 09 Feb 2008 21:22:29 +0000
Delivery-date: Sat, 09 Feb 2008 13:29:39 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1202592146@xxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Michael.Fetterman@xxxxxxxxxxxx
# Date 1202591471 0
# Node ID f904468403b4d47dbebc54c76473c28b24066681
# Parent  9ff80e7b54528e06c8e0dc0ad8d8da09afca7f16
Improve xentrace to use VIRQ_TBUF interrupts as well as a user-specified
polling interval in order to determine when to empty the trace buffers.
Removed the old and unused/unimplemented new_data_threshold logic.

Signed-off-by: Michael A Fetterman <Michael.Fetterman@xxxxxxxxxxxx>

diff -r 9ff80e7b5452 -r f904468403b4 tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Sat Feb 09 21:11:09 2008 +0000
+++ b/tools/xentrace/xentrace.c Sat Feb 09 21:11:11 2008 +0000
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <getopt.h>
 #include <assert.h>
+#include <sys/poll.h>
 
 #include <xen/xen.h>
 #include <xen/trace.h>
@@ -40,9 +41,6 @@ do {                                    
 
 /***** Compile time configuration of defaults ********************************/
 
-/* when we've got more records than this waiting, we log it to the output */
-#define NEW_DATA_THRESH 1
-
 /* sleep for this long (milliseconds) between checking the trace buffers */
 #define POLL_SLEEP_MILLIS 100
 
@@ -51,8 +49,7 @@ do {                                    
 
 typedef struct settings_st {
     char *outfile;
-    struct timespec poll_sleep;
-    unsigned long new_data_thresh;
+    unsigned long poll_sleep; /* milliseconds to sleep between polls */
     uint32_t evt_mask;
     uint32_t cpu_mask;
     unsigned long tbuf_size;
@@ -63,23 +60,13 @@ settings_t opts;
 
 int interrupted = 0; /* gets set if we get a SIGHUP */
 
+static int xc_handle = -1;
+static int event_fd = -1;
+static int virq_port = -1;
+
 void close_handler(int signal)
 {
     interrupted = 1;
-}
-
-/**
- * millis_to_timespec - convert a time in milliseconds to a struct timespec
- * @millis:             time interval in milliseconds
- */
-struct timespec millis_to_timespec(unsigned long millis)
-{
-    struct timespec spec;
-    
-    spec.tv_sec = millis / 1000;
-    spec.tv_nsec = (millis % 1000) * 1000;
-
-    return spec;
 }
 
 /**
@@ -143,13 +130,7 @@ void write_buffer(unsigned int cpu, unsi
 
 static void get_tbufs(unsigned long *mfn, unsigned long *size)
 {
-    int xc_handle = xc_interface_open();
     int ret;
-
-    if ( xc_handle < 0 ) 
-    {
-        exit(EXIT_FAILURE);
-    }
 
     if(!opts.tbuf_size)
       opts.tbuf_size = DEFAULT_TBUF_SIZE;
@@ -161,8 +142,6 @@ static void get_tbufs(unsigned long *mfn
         perror("Couldn't enable trace buffers");
         exit(1);
     }
-
-    xc_interface_close(xc_handle);
 }
 
 /**
@@ -176,22 +155,12 @@ struct t_buf *map_tbufs(unsigned long tb
 struct t_buf *map_tbufs(unsigned long tbufs_mfn, unsigned int num,
                         unsigned long size)
 {
-    int xc_handle;
     struct t_buf *tbufs_mapped;
-
-    xc_handle = xc_interface_open();
-
-    if ( xc_handle < 0 ) 
-    {
-        exit(EXIT_FAILURE);
-    }
 
     tbufs_mapped = xc_map_foreign_range(xc_handle, DOMID_XEN,
                                         size * num, PROT_READ | PROT_WRITE,
                                         tbufs_mfn);
 
-    xc_interface_close(xc_handle);
-
     if ( tbufs_mapped == 0 ) 
     {
         PERROR("Failed to mmap trace buffers");
@@ -210,7 +179,6 @@ void set_mask(uint32_t mask, int type)
 void set_mask(uint32_t mask, int type)
 {
     int ret = 0;
-    int xc_handle = xc_interface_open(); /* for accessing control interface */
 
     if (type == 1) {
         ret = xc_tbuf_set_cpu_mask(xc_handle, mask);
@@ -220,8 +188,6 @@ void set_mask(uint32_t mask, int type)
         fprintf(stderr, "change evtmask to 0x%x\n", mask);
     }
 
-    xc_interface_close(xc_handle);
-
     if ( ret != 0 )
     {
         PERROR("Failure to get trace buffer pointer from Xen and set the new 
mask");
@@ -295,7 +261,6 @@ unsigned int get_num_cpus(void)
 unsigned int get_num_cpus(void)
 {
     xc_physinfo_t physinfo = { 0 };
-    int xc_handle = xc_interface_open();
     int ret;
     
     ret = xc_physinfo(xc_handle, &physinfo);
@@ -306,9 +271,68 @@ unsigned int get_num_cpus(void)
         exit(EXIT_FAILURE);
     }
 
-    xc_interface_close(xc_handle);
-
     return physinfo.nr_cpus;
+}
+
+/**
+ * event_init - setup to receive the VIRQ_TBUF event
+ */
+void event_init(void)
+{
+    int rc;
+
+    rc = xc_evtchn_open();
+    if (rc < 0) {
+        perror(xc_get_last_error()->message);
+        exit(EXIT_FAILURE);
+    }
+    event_fd = rc;
+
+    rc = xc_evtchn_bind_virq(event_fd, VIRQ_TBUF);
+    if (rc == -1) {
+        PERROR("failed to bind to VIRQ port");
+        exit(EXIT_FAILURE);
+    }
+    virq_port = rc;
+}
+
+/**
+ * wait_for_event_or_timeout - sleep for the specified number of milliseconds,
+ *                             or until an VIRQ_TBUF event occurs
+ */
+void wait_for_event_or_timeout(unsigned long milliseconds)
+{
+    int rc;
+    struct pollfd fd = { .fd = event_fd,
+                         .events = POLLIN | POLLERR };
+    int port;
+
+    rc = poll(&fd, 1, milliseconds);
+    if (rc == -1) {
+        if (errno == EINTR)
+            return;
+        PERROR("poll exitted with an error");
+        exit(EXIT_FAILURE);
+    }
+
+    if (rc == 1) {
+        port = xc_evtchn_pending(event_fd);
+        if (port == -1) {
+            PERROR("failed to read port from evtchn");
+            exit(EXIT_FAILURE);
+        }
+        if (port != virq_port) {
+            fprintf(stderr,
+                    "unexpected port returned from evtchn (got %d vs expected 
%d)\n",
+                    port, virq_port);
+            exit(EXIT_FAILURE);
+        }
+        rc = xc_evtchn_unmask(event_fd, port);
+        if (rc == -1) {
+            PERROR("failed to write port to evtchn");
+            exit(EXIT_FAILURE);
+        }
+    }
 }
 
 
@@ -329,6 +353,9 @@ int monitor_tbufs(int outfd)
     unsigned long size;          /* size of a single trace buffer            */
 
     unsigned long data_size;
+
+    /* prepare to listen for VIRQ_TBUF */
+    event_init();
 
     /* get number of logical CPUs (and therefore number of trace buffers) */
     num = get_num_cpus();
@@ -405,7 +432,7 @@ int monitor_tbufs(int outfd)
             meta[i]->cons = prod;
         }
 
-        nanosleep(&opts.poll_sleep, NULL);
+        wait_for_event_or_timeout(opts.poll_sleep);
     }
 
     /* cleanup */
@@ -425,7 +452,7 @@ int monitor_tbufs(int outfd)
 #define xstr(x) str(x)
 #define str(x) #x
 
-const char *program_version     = "xentrace v1.1";
+const char *program_version     = "xentrace v1.2";
 const char *program_bug_address = "<mark.a.williamson@xxxxxxxxx>";
 
 void usage(void)
@@ -444,9 +471,6 @@ void usage(void)
 "                          N.B. that the trace buffer cannot be resized.\n" \
 "                          if it has already been set this boot cycle,\n" \
 "                          this argument will be ignored.\n" \
-"  -t, --log-thresh=l      Set number, l, of new records required to\n" \
-"                          trigger a write to output (default " \
-                           xstr(NEW_DATA_THRESH) ").\n" \
 "  -?, --help              Show this message\n" \
 "  -V, --version           Print program version\n" \
 "\n" \
@@ -525,12 +549,8 @@ void parse_args(int argc, char **argv)
     {
         switch ( option )
         {
-        case 't': /* set new records threshold for logging */
-            opts.new_data_thresh = argtol(optarg, 0);
-            break;
-
         case 's': /* set sleep time (given in milliseconds) */
-            opts.poll_sleep = millis_to_timespec(argtol(optarg, 0));
+            opts.poll_sleep = argtol(optarg, 0);
             break;
 
         case 'c': /* set new cpu mask for filtering*/
@@ -574,13 +594,19 @@ int main(int argc, char **argv)
     struct sigaction act;
 
     opts.outfile = 0;
-    opts.poll_sleep = millis_to_timespec(POLL_SLEEP_MILLIS);
-    opts.new_data_thresh = NEW_DATA_THRESH;
+    opts.poll_sleep = POLL_SLEEP_MILLIS;
     opts.evt_mask = 0;
     opts.cpu_mask = 0;
 
     parse_args(argc, argv);
-    
+
+    xc_handle = xc_interface_open();
+    if ( xc_handle < 0 ) 
+    {
+        perror(xc_get_last_error()->message);
+        exit(EXIT_FAILURE);
+    }
+
     if ( opts.evt_mask != 0 )
         set_mask(opts.evt_mask, 0);
 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>