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-changelog

[Xen-changelog] [xen-unstable] xentrace: Allow xentrace to handle >4G of

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] xentrace: Allow xentrace to handle >4G of trace data.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 11 Feb 2008 07:10:09 -0800
Delivery-date: Mon, 11 Feb 2008 07:10:17 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1202723181 0
# Node ID 98e9d5d4b309c82886d7740aa88c29c334a4fff9
# Parent  7d03c0b0750482ec96ec9fcf93c2b585f7740af5
xentrace: Allow xentrace to handle >4G of trace data.
It was previously assert'ing when it hit 4G.

Also, because the trace buffer is not a power of 2 in size,
using modulo arithmetic to address the buffer does not work
when the index wraps around 2^32.

This patch fixes both issues, and as a side effect, removes all
integer division from the hypervisor side of the trace mechanism.

Signed-off-by: Michael A Fetterman <Michael.Fetterman@xxxxxxxxxxxx>
---
 tools/xentrace/xentrace.c  |   15 +++++++--
 xen/common/trace.c         |   71 +++++++++++++++++++++++++++++++++------------
 xen/include/public/trace.h |    8 +++++
 3 files changed, 73 insertions(+), 21 deletions(-)

diff -r 7d03c0b07504 -r 98e9d5d4b309 tools/xentrace/xentrace.c
--- a/tools/xentrace/xentrace.c Mon Feb 11 09:45:36 2008 +0000
+++ b/tools/xentrace/xentrace.c Mon Feb 11 09:46:21 2008 +0000
@@ -362,9 +362,18 @@ int monitor_tbufs(int outfd)
             if ( cons == prod )
                 continue;
            
-            assert(prod > cons);
-
-            window_size = prod - cons;
+            assert(cons < 2*data_size);
+            assert(prod < 2*data_size);
+
+            // NB: if (prod<cons), then (prod-cons)%data_size will not yield
+            // the correct answer because data_size is not a power of 2.
+            if ( prod < cons )
+                window_size = (prod + 2*data_size) - cons;
+            else
+                window_size = prod - cons;
+            assert(window_size > 0);
+            assert(window_size <= data_size);
+
             start_offset = cons % data_size;
             end_offset = prod % data_size;
 
diff -r 7d03c0b07504 -r 98e9d5d4b309 xen/common/trace.c
--- a/xen/common/trace.c        Mon Feb 11 09:45:36 2008 +0000
+++ b/xen/common/trace.c        Mon Feb 11 09:46:21 2008 +0000
@@ -239,14 +239,46 @@ static inline int calc_rec_size(int cycl
     return rec_size;
 }
 
+static inline int calc_unconsumed_bytes(struct t_buf *buf)
+{
+    int x = buf->prod - buf->cons;
+    if ( x < 0 )
+        x += 2*data_size;
+
+    ASSERT(x >= 0);
+    ASSERT(x <= data_size);
+
+    return x;
+}
+
 static inline int calc_bytes_to_wrap(struct t_buf *buf)
 {
-    return data_size - (buf->prod % data_size);
-}
-
-static inline unsigned calc_bytes_avail(struct t_buf *buf)
-{
-    return data_size - (buf->prod - buf->cons);
+    int x = data_size - buf->prod;
+    if ( x <= 0 )
+        x += data_size;
+
+    ASSERT(x > 0);
+    ASSERT(x <= data_size);
+
+    return x;
+}
+
+static inline int calc_bytes_avail(struct t_buf *buf)
+{
+    return data_size - calc_unconsumed_bytes(buf);
+}
+
+static inline struct t_rec *
+next_record(struct t_buf *buf)
+{
+    int x = buf->prod;
+    if ( x >= data_size )
+        x -= data_size;
+
+    ASSERT(x >= 0);
+    ASSERT(x < data_size);
+
+    return (struct t_rec *)&this_cpu(t_data)[x];
 }
 
 static inline int __insert_record(struct t_buf *buf,
@@ -260,24 +292,25 @@ static inline int __insert_record(struct
     unsigned char *dst;
     unsigned long extra_word = extra/sizeof(u32);
     int local_rec_size = calc_rec_size(cycles, extra);
+    uint32_t next;
 
     BUG_ON(local_rec_size != rec_size);
+    BUG_ON(extra & 3);
 
     /* Double-check once more that we have enough space.
      * Don't bugcheck here, in case the userland tool is doing
      * something stupid. */
     if ( calc_bytes_avail(buf) < rec_size )
     {
-        printk("%s: %u bytes left (%u - (%u - %u)) recsize %u.\n",
+        printk("%s: %u bytes left (%u - ((%u - %u) %% %u) recsize %u.\n",
                __func__,
-               data_size - (buf->prod - buf->cons),
-               data_size,
-               buf->prod, buf->cons, rec_size);
+               calc_bytes_avail(buf),
+               data_size, buf->prod, buf->cons, data_size, rec_size);
         return 0;
     }
     rmb();
 
-    rec = (struct t_rec *)&this_cpu(t_data)[buf->prod % data_size];
+    rec = next_record(buf);
     rec->event = event;
     rec->extra_u32 = extra_word;
     dst = (unsigned char *)rec->u.nocycles.extra_u32;
@@ -293,7 +326,13 @@ static inline int __insert_record(struct
         memcpy(dst, extra_data, extra);
 
     wmb();
-    buf->prod += rec_size;
+
+    next = buf->prod + rec_size;
+    if ( next >= 2*data_size )
+        next -= 2*data_size;
+    ASSERT(next >= 0);
+    ASSERT(next < 2*data_size);
+    buf->prod = next;
 
     return rec_size;
 }
@@ -395,7 +434,7 @@ void __trace_var(u32 event, int cycles, 
 
     local_irq_save(flags);
 
-    started_below_highwater = ((buf->prod - buf->cons) < t_buf_highwater);
+    started_below_highwater = (calc_unconsumed_bytes(buf) < t_buf_highwater);
 
     /* Calculate the record size */
     rec_size = calc_rec_size(cycles, extra);
@@ -413,10 +452,6 @@ void __trace_var(u32 event, int cycles, 
     total_size = 0;
 
     /* First, check to see if we need to include a lost_record.
-     *
-     * calc_bytes_to_wrap() involves integer division, which we'd like to
-     * avoid if we can.  So do the math, check it in debug versions, and
-     * do a final check always if we happen to write a record.
      */
     if ( this_cpu(lost_records) )
     {
@@ -477,7 +512,7 @@ void __trace_var(u32 event, int cycles, 
 
     /* Notify trace buffer consumer that we've crossed the high water mark. */
     if ( started_below_highwater &&
-         ((buf->prod - buf->cons) >= t_buf_highwater) )
+         (calc_unconsumed_bytes(buf) >= t_buf_highwater) )
         raise_softirq(TRACE_SOFTIRQ);
 }
 
diff -r 7d03c0b07504 -r 98e9d5d4b309 xen/include/public/trace.h
--- a/xen/include/public/trace.h        Mon Feb 11 09:45:36 2008 +0000
+++ b/xen/include/public/trace.h        Mon Feb 11 09:46:21 2008 +0000
@@ -141,6 +141,14 @@ struct t_rec {
  * field, indexes into an array of struct t_rec's.
  */
 struct t_buf {
+    /* Assume the data buffer size is X.  X is generally not a power of 2.
+     * CONS and PROD are incremented modulo (2*X):
+     *     0 <= cons < 2*X
+     *     0 <= prod < 2*X
+     * This is done because addition modulo X breaks at 2^32 when X is not a
+     * power of 2:
+     *     (((2^32 - 1) % X) + 1) % X != (2^32) % X
+     */
     uint32_t cons;   /* Offset of next item to be consumed by control tools. */
     uint32_t prod;   /* Offset of next item to be produced by Xen.           */
     /*  Records follow immediately after the meta-data header.    */

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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] xentrace: Allow xentrace to handle >4G of trace data., Xen patchbot-unstable <=