direct-io.hg

changeset 4497:6a9598f401d9

bitkeeper revision 1.1281 (4254e7b2acr6cWtC_9EVDd2Q9Jfytw)

Merge firebug.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
into firebug.cl.cam.ac.uk:/local/scratch/kaf24/xen-unstable.bk
author kaf24@firebug.cl.cam.ac.uk
date Thu Apr 07 07:56:34 2005 +0000 (2005-04-07)
parents 4c5d6dc1eafe 5c90ed25ab58
children 3f2415a328b7
files tools/xentrace/formats tools/xentrace/xentrace.c xen/common/dom0_ops.c xen/common/schedule.c xen/common/trace.c xen/include/asm-x86/vmx.h xen/include/public/dom0_ops.h xen/include/public/trace.h xen/include/xen/trace.h
line diff
     1.1 --- a/tools/xentrace/formats	Wed Apr 06 22:35:34 2005 +0000
     1.2 +++ b/tools/xentrace/formats	Thu Apr 07 07:56:34 2005 +0000
     1.3 @@ -1,34 +1,17 @@
     1.4 -0x00010000	CPU%(cpu)d	%(tsc)d		sched_add_domain	[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
     1.5 -0x00010001	CPU%(cpu)d	%(tsc)d		sched_rem_domain	[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
     1.6 -0x00010002	CPU%(cpu)d	%(tsc)d		domain_sleep		[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
     1.7 -0x00010003	CPU%(cpu)d	%(tsc)d		domain_wake		[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
     1.8 -0x00010004	CPU%(cpu)d	%(tsc)d		do_yield		[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
     1.9 -0x00010005	CPU%(cpu)d	%(tsc)d		do_block		[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
    1.10 -0x00010006	CPU%(cpu)d	%(tsc)d		domain_shutdown		[ domid = 0x%(1)08x, edomid = 0x%(2)08x, reason = 0x%(3)08x ]
    1.11 -0x00010007	CPU%(cpu)d	%(tsc)d		sched_ctl
    1.12 -0x00010008	CPU%(cpu)d	%(tsc)d		sched_adjdom		[ domid = 0x%(1)08x ]
    1.13 -0x00010009	CPU%(cpu)d	%(tsc)d		__enter_scheduler	[ prev<domid:edomid> = 0x%(1)08x : 0x%(2)08x, next<domid:edomid> = 0x%(3)08x : 0x%(4)08x ]
    1.14 -0x0001000A	CPU%(cpu)d	%(tsc)d		s_timer_fn
    1.15 -0x0001000B	CPU%(cpu)d	%(tsc)d		t_timer_fn
    1.16 -0x0001000C	CPU%(cpu)d	%(tsc)d		dom_timer_fn
    1.17 -
    1.18 +0x00020001	CPU%(cpu)d	%(tsc)d		sched_add_domain	[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
    1.19 +0x00020002	CPU%(cpu)d	%(tsc)d		sched_rem_domain	[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
    1.20 +0x00020003	CPU%(cpu)d	%(tsc)d		domain_sleep		[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
    1.21 +0x00020004	CPU%(cpu)d	%(tsc)d		domain_wake		[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
    1.22 +0x00020005	CPU%(cpu)d	%(tsc)d		do_yield		[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
    1.23 +0x00020006	CPU%(cpu)d	%(tsc)d		do_block		[ domid = 0x%(1)08x, edomid = 0x%(2)08x ]
    1.24 +0x00020007	CPU%(cpu)d	%(tsc)d		domain_shutdown		[ domid = 0x%(1)08x, edomid = 0x%(2)08x, reason = 0x%(3)08x ]
    1.25 +0x00020008	CPU%(cpu)d	%(tsc)d		sched_ctl
    1.26 +0x00020009	CPU%(cpu)d	%(tsc)d		sched_adjdom		[ domid = 0x%(1)08x ]
    1.27 +0x0002000a	CPU%(cpu)d	%(tsc)d		__enter_scheduler	[ prev<domid:edomid> = 0x%(1)08x : 0x%(2)08x, next<domid:edomid> = 0x%(3)08x : 0x%(4)08x ]
    1.28 +0x0002000B	CPU%(cpu)d	%(tsc)d		s_timer_fn
    1.29 +0x0002000c	CPU%(cpu)d	%(tsc)d		t_timer_fn
    1.30 +0x0002000d	CPU%(cpu)d	%(tsc)d		dom_timer_fn
    1.31  
    1.32 -0x00020008	CPU%(cpu)d	%(tsc)d		enter: dom0_create_dom
    1.33 -0x00030008	CPU%(cpu)d	%(tsc)d		leave: dom0_create_dom
    1.34 -0x00020009	CPU%(cpu)d	%(tsc)d		enter: dom0_destroy_dom
    1.35 -0x00030009	CPU%(cpu)d	%(tsc)d		leave: dom0_destroy_dom
    1.36 -0x0002000A	CPU%(cpu)d	%(tsc)d		enter: dom0_start_dom
    1.37 -0x0003000A	CPU%(cpu)d	%(tsc)d		leave: dom0_start_dom
    1.38 -0x0002000B	CPU%(cpu)d	%(tsc)d		enter: dom0_stop_dom
    1.39 -0x0003000B	CPU%(cpu)d	%(tsc)d		leave: dom0_stop_dom
    1.40 -0x0002000C	CPU%(cpu)d	%(tsc)d		enter: dom0_getinfo
    1.41 -0x0003000C	CPU%(cpu)d	%(tsc)d		leave: dom0_getinfo
    1.42 -0x0002000D	CPU%(cpu)d	%(tsc)d		enter: dom0_build
    1.43 -0x0003000D	CPU%(cpu)d	%(tsc)d		leave: dom0_build
    1.44 -0x00020019	CPU%(cpu)d	%(tsc)d		enter: dom0_shadow_op
    1.45 -0x00030019	CPU%(cpu)d	%(tsc)d		leave: dom0_shadow_op
    1.46 -
    1.47 -
    1.48 -0x00040001	CPU%(cpu)d      %(tsc)d		VMX_VMEXIT		[ domid = 0x%(1)08x, eip = 0x%(2)08x, reason = 0x%(3)08x ]
    1.49 -0x00040002	CPU%(cpu)d      %(tsc)d		VMX_VECTOR		[ domid = 0x%(1)08x, eip = 0x%(2)08x, vector = 0x%(3)08x ]
    1.50 -0x00040003	CPU%(cpu)d      %(tsc)d		VMX_INT			[ domid = 0x%(1)08x, trap = 0x%(2)08x, va = 0x%(3)08x ]
    1.51 \ No newline at end of file
    1.52 +0x00080001	CPU%(cpu)d      %(tsc)d		VMX_VMEXIT		[ domid = 0x%(1)08x, eip = 0x%(2)08x, reason = 0x%(3)08x ]
    1.53 +0x00080002	CPU%(cpu)d      %(tsc)d		VMX_VECTOR		[ domid = 0x%(1)08x, eip = 0x%(2)08x, vector = 0x%(3)08x ]
    1.54 +0x00080003	CPU%(cpu)d      %(tsc)d		VMX_INT			[ domid = 0x%(1)08x, trap = 0x%(2)08x, va = 0x%(3)08x ]
     2.1 --- a/tools/xentrace/xentrace.c	Wed Apr 06 22:35:34 2005 +0000
     2.2 +++ b/tools/xentrace/xentrace.c	Thu Apr 07 07:56:34 2005 +0000
     2.3 @@ -11,10 +11,10 @@
     2.4  
     2.5  #include <time.h>
     2.6  #include <stdlib.h>
     2.7 +#include <stdio.h>
     2.8  #include <sys/mman.h>
     2.9 -#include <stdio.h>
    2.10 +#include <sys/stat.h>
    2.11  #include <sys/types.h>
    2.12 -#include <sys/stat.h>
    2.13  #include <fcntl.h>
    2.14  #include <unistd.h>
    2.15  #include <errno.h>
    2.16 @@ -101,8 +101,9 @@ void get_tbufs(unsigned long *mach_addr,
    2.17      dom0_op_t op;                        /* dom0 op we'll build             */
    2.18      int xc_handle = xc_interface_open(); /* for accessing control interface */
    2.19  
    2.20 -    op.cmd = DOM0_GETTBUFS;
    2.21 +    op.cmd = DOM0_TBUFCONTROL;
    2.22      op.interface_version = DOM0_INTERFACE_VERSION;
    2.23 +    op.u.tbufcontrol.op  = DOM0_TBUF_GET_INFO;
    2.24  
    2.25      ret = do_dom0_op(xc_handle, &op);
    2.26  
    2.27 @@ -114,8 +115,8 @@ void get_tbufs(unsigned long *mach_addr,
    2.28          exit(EXIT_FAILURE);
    2.29      }
    2.30  
    2.31 -    *mach_addr = op.u.gettbufs.mach_addr;
    2.32 -    *size      = op.u.gettbufs.size;
    2.33 +    *mach_addr = op.u.tbufcontrol.mach_addr;
    2.34 +    *size      = op.u.tbufcontrol.size;
    2.35  }
    2.36  
    2.37  /**
    2.38 @@ -141,8 +142,8 @@ struct t_buf *map_tbufs(unsigned long tb
    2.39      }
    2.40  
    2.41      tbufs_mapped = xc_map_foreign_range(xc_handle, 0 /* Dom 0 ID */,
    2.42 -					size * num, PROT_READ,
    2.43 -					tbufs_mach >> PAGE_SHIFT);
    2.44 +                                        size * num, PROT_READ,
    2.45 +                                        tbufs_mach >> PAGE_SHIFT);
    2.46  
    2.47      xc_interface_close(xc_handle);
    2.48  
    2.49 @@ -152,7 +153,7 @@ struct t_buf *map_tbufs(unsigned long tb
    2.50          exit(EXIT_FAILURE);
    2.51      }
    2.52  
    2.53 -    return (struct t_buf *)tbufs_mapped;
    2.54 +    return tbufs_mapped;
    2.55  }
    2.56  
    2.57  
    2.58 @@ -181,8 +182,7 @@ struct t_buf **init_bufs_ptrs(void *bufs
    2.59      /* initialise pointers to the trace buffers - given the size of a trace
    2.60       * buffer and the value of bufs_maped, we can easily calculate these */
    2.61      for ( i = 0; i<num; i++ )
    2.62 -        user_ptrs[i] = (struct t_buf *)(
    2.63 -            (unsigned long)bufs_mapped + size * i);
    2.64 +        user_ptrs[i] = (struct t_buf *)((unsigned long)bufs_mapped + size * i);
    2.65  
    2.66      return user_ptrs;
    2.67  }
    2.68 @@ -214,9 +214,9 @@ struct t_rec **init_rec_ptrs(unsigned lo
    2.69          exit(EXIT_FAILURE);
    2.70      }
    2.71  
    2.72 -    for ( i = 0; i<num; i++ )
    2.73 -        data[i] = (struct t_rec *)(meta[i]->data - tbufs_mach
    2.74 -				   + (unsigned long)tbufs_mapped);
    2.75 +    for ( i = 0; i < num; i++ )
    2.76 +        data[i] = (struct t_rec *)(meta[i]->rec_addr - tbufs_mach
    2.77 +                                   + (unsigned long)tbufs_mapped);
    2.78  
    2.79      return data;
    2.80  }
    2.81 @@ -242,7 +242,7 @@ unsigned long *init_tail_idxs(struct t_b
    2.82      }
    2.83      
    2.84      for ( i = 0; i<num; i++ )
    2.85 -        tails[i] = bufs[i]->head;
    2.86 +        tails[i] = atomic_read(&bufs[i]->rec_idx);
    2.87  
    2.88      return tails;
    2.89  }
    2.90 @@ -299,7 +299,7 @@ int monitor_tbufs(FILE *logfile)
    2.91      get_tbufs(&tbufs_mach, &size);
    2.92      tbufs_mapped = map_tbufs(tbufs_mach, num, size);
    2.93  
    2.94 -    size_in_recs = (size / sizeof(struct t_rec) )-1;
    2.95 +    size_in_recs = (size - sizeof(struct t_buf)) / sizeof(struct t_rec);
    2.96  
    2.97      /* build arrays of convenience ptrs */
    2.98      meta  = init_bufs_ptrs (tbufs_mapped, num, size);
    2.99 @@ -310,11 +310,11 @@ int monitor_tbufs(FILE *logfile)
   2.100      while ( !interrupted )
   2.101      {
   2.102          for ( i = 0; ( i < num ) && !interrupted; i++ )
   2.103 -	    while( cons[i] != meta[i]->head )
   2.104 -	    {
   2.105 -		write_rec(i, data[i] + (cons[i] % size_in_recs), logfile);
   2.106 -		cons[i]++;
   2.107 -	    }
   2.108 +            while( cons[i] != atomic_read(&meta[i]->rec_idx) )
   2.109 +            {
   2.110 +                write_rec(i, data[i] + cons[i], logfile);
   2.111 +                cons[i] = (cons[i] + 1) % size_in_recs;
   2.112 +            }
   2.113  
   2.114          nanosleep(&opts.poll_sleep, NULL);
   2.115      }
   2.116 @@ -445,9 +445,11 @@ int main(int argc, char **argv)
   2.117      
   2.118      /* ensure that if we get a signal, we'll do cleanup, then exit */
   2.119      act.sa_handler = close_handler;
   2.120 -    sigaction(SIGHUP,  &act, 0);
   2.121 -    sigaction(SIGTERM, &act, 0);
   2.122 -    sigaction(SIGINT,  &act, 0);
   2.123 +    act.sa_flags = 0;
   2.124 +    sigemptyset(&act.sa_mask);
   2.125 +    sigaction(SIGHUP,  &act, NULL);
   2.126 +    sigaction(SIGTERM, &act, NULL);
   2.127 +    sigaction(SIGINT,  &act, NULL);
   2.128  
   2.129      ret = monitor_tbufs(logfile);
   2.130  
     3.1 --- a/xen/common/dom0_ops.c	Wed Apr 06 22:35:34 2005 +0000
     3.2 +++ b/xen/common/dom0_ops.c	Thu Apr 07 07:56:34 2005 +0000
     3.3 @@ -19,9 +19,6 @@
     3.4  #include <xen/physdev.h>
     3.5  #include <public/sched_ctl.h>
     3.6  
     3.7 -#define TRC_DOM0OP_ENTER_BASE  0x00020000
     3.8 -#define TRC_DOM0OP_LEAVE_BASE  0x00030000
     3.9 -
    3.10  extern unsigned int alloc_new_dom_mem(struct domain *, unsigned int);
    3.11  extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op);
    3.12  extern void arch_getdomaininfo_ctxt(
    3.13 @@ -385,9 +382,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    3.14      break;
    3.15  
    3.16  #ifdef TRACE_BUFFER
    3.17 -    case DOM0_GETTBUFS:
    3.18 +    case DOM0_TBUFCONTROL:
    3.19      {
    3.20 -        ret = get_tb_info(&op->u.gettbufs);
    3.21 +        ret = tb_control(&op->u.tbufcontrol);
    3.22          copy_to_user(u_dom0_op, op, sizeof(*op));
    3.23      }
    3.24      break;
     4.1 --- a/xen/common/schedule.c	Wed Apr 06 22:35:34 2005 +0000
     4.2 +++ b/xen/common/schedule.c	Thu Apr 07 07:56:34 2005 +0000
     4.3 @@ -42,24 +42,6 @@ string_param("sched", opt_sched);
     4.4  
     4.5  #define TIME_SLOP      (s32)MICROSECS(50)     /* allow time to slip a bit */
     4.6  
     4.7 -/*
     4.8 - * TODO MAW pull trace-related #defines out of here and into an auto-generated
     4.9 - * header file later on!
    4.10 - */
    4.11 -#define TRC_SCHED_DOM_ADD             0x00010000
    4.12 -#define TRC_SCHED_DOM_REM             0x00010001
    4.13 -#define TRC_SCHED_SLEEP               0x00010002
    4.14 -#define TRC_SCHED_WAKE                0x00010003
    4.15 -#define TRC_SCHED_YIELD               0x00010004
    4.16 -#define TRC_SCHED_BLOCK               0x00010005
    4.17 -#define TRC_SCHED_SHUTDOWN            0x00010006
    4.18 -#define TRC_SCHED_CTL                 0x00010007
    4.19 -#define TRC_SCHED_ADJDOM              0x00010008
    4.20 -#define TRC_SCHED_SWITCH              0x00010009
    4.21 -#define TRC_SCHED_S_TIMER_FN          0x0001000A
    4.22 -#define TRC_SCHED_T_TIMER_FN          0x0001000B
    4.23 -#define TRC_SCHED_DOM_TIMER_FN        0x0001000C
    4.24 -
    4.25  /* Various timer handlers. */
    4.26  static void s_timer_fn(unsigned long unused);
    4.27  static void t_timer_fn(unsigned long unused);
     5.1 --- a/xen/common/trace.c	Wed Apr 06 22:35:34 2005 +0000
     5.2 +++ b/xen/common/trace.c	Thu Apr 07 07:56:34 2005 +0000
     5.3 @@ -8,6 +8,8 @@
     5.4   * Author: Mark Williamson, mark.a.williamson@intel.com
     5.5   * Date:   January 2004
     5.6   *
     5.7 + * Copyright (C) 2005 Bin Ren
     5.8 + *
     5.9   * The trace buffer code is designed to allow debugging traces of Xen to be
    5.10   * generated on UP / SMP machines.  Each trace entry is timestamped so that
    5.11   * it's possible to reconstruct a chronological record of trace events.
    5.12 @@ -39,6 +41,11 @@ struct t_buf *t_bufs[NR_CPUS];
    5.13  /* a flag recording whether initialisation has been done */
    5.14  int tb_init_done = 0;
    5.15  
    5.16 +/* which CPUs tracing is enabled on */
    5.17 +unsigned long tb_cpu_mask = (~0UL);
    5.18 +
    5.19 +/* which tracing events are enabled */
    5.20 +u32 tb_event_mask = TRC_ALL;
    5.21  /**
    5.22   * init_trace_bufs - performs initialisation of the per-cpu trace buffers.
    5.23   *
    5.24 @@ -69,25 +76,18 @@ void init_trace_bufs(void)
    5.25      }
    5.26  
    5.27      /* Share pages so that xentrace can map them. */
    5.28 -
    5.29      for ( i = 0; i < nr_pages; i++ )
    5.30 -        SHARE_PFN_WITH_DOMAIN(virt_to_page(rawbuf+(i*PAGE_SIZE)), dom0);
    5.31 +        SHARE_PFN_WITH_DOMAIN(virt_to_page(rawbuf + i * PAGE_SIZE), dom0);
    5.32      
    5.33      for ( i = 0; i < smp_num_cpus; i++ )
    5.34      {
    5.35          buf = t_bufs[i] = (struct t_buf *)&rawbuf[i*opt_tbuf_size*PAGE_SIZE];
    5.36          
    5.37 -        /* For use in Xen. */
    5.38 -        buf->vdata    = (struct t_rec *)(buf+1);
    5.39 -        buf->head_ptr = buf->vdata;
    5.40 -        
    5.41 -        /* For use in user space. */
    5.42 -        buf->data = __pa(buf->vdata);
    5.43 -        buf->head = 0;
    5.44 -
    5.45 -        /* For use in both. */
    5.46 -        buf->size = (opt_tbuf_size * PAGE_SIZE - sizeof(struct t_buf))
    5.47 -            / sizeof(struct t_rec);
    5.48 +        _atomic_set(buf->rec_idx, 0);
    5.49 +        buf->rec_num  = (opt_tbuf_size * PAGE_SIZE - sizeof(struct t_buf))
    5.50 +                        / sizeof(struct t_rec);
    5.51 +        buf->rec      = (struct t_rec *)(buf + 1);
    5.52 +        buf->rec_addr = __pa(buf->rec);
    5.53      }
    5.54  
    5.55      printk("Xen trace buffers: initialised\n");
    5.56 @@ -98,27 +98,40 @@ void init_trace_bufs(void)
    5.57  }
    5.58  
    5.59  /**
    5.60 - * get_tb_info - get trace buffer details
    5.61 - * @st: a pointer to a dom0_gettbufs_t to be filled out
    5.62 - *
    5.63 - * Called by the %DOM0_GETTBUFS dom0 op to fetch the machine address of the
    5.64 - * trace buffers.
    5.65 + * tb_control - DOM0 operations on trace buffers.
    5.66 + * @tbc: a pointer to a dom0_tbufcontrol_t to be filled out
    5.67   */
    5.68 -int get_tb_info(dom0_gettbufs_t *st)
    5.69 +int tb_control(dom0_tbufcontrol_t *tbc)
    5.70  {
    5.71 -    if ( tb_init_done )
    5.72 +    static spinlock_t lock = SPIN_LOCK_UNLOCKED;
    5.73 +    int rc = 0;
    5.74 +
    5.75 +    if ( !tb_init_done )
    5.76 +        return -EINVAL;
    5.77 +
    5.78 +    spin_lock(&lock);
    5.79 +
    5.80 +    switch ( tbc->op)
    5.81      {
    5.82 -        st->mach_addr = __pa(t_bufs[0]);
    5.83 -        st->size      = opt_tbuf_size * PAGE_SIZE;
    5.84 -        
    5.85 -        return 0;
    5.86 +    case DOM0_TBUF_GET_INFO:
    5.87 +        tbc->cpu_mask  = tb_cpu_mask;
    5.88 +        tbc->evt_mask  = tb_event_mask;
    5.89 +        tbc->mach_addr = __pa(t_bufs[0]);
    5.90 +        tbc->size      = opt_tbuf_size * PAGE_SIZE;
    5.91 +        break;
    5.92 +    case DOM0_TBUF_SET_CPU_MASK:
    5.93 +        tb_cpu_mask = tbc->cpu_mask;
    5.94 +        break;
    5.95 +    case DOM0_TBUF_SET_EVT_MASK:
    5.96 +        tb_event_mask = tbc->evt_mask;
    5.97 +        break;
    5.98 +    default:
    5.99 +        rc = -EINVAL;
   5.100      }
   5.101 -    else
   5.102 -    {
   5.103 -        st->mach_addr = 0;
   5.104 -        st->size      = 0;
   5.105 -        return -ENODATA;
   5.106 -    }
   5.107 +
   5.108 +    spin_unlock(&lock);
   5.109 +
   5.110 +    return rc;
   5.111  }
   5.112  
   5.113  /*
     6.1 --- a/xen/include/asm-x86/vmx.h	Wed Apr 06 22:35:34 2005 +0000
     6.2 +++ b/xen/include/asm-x86/vmx.h	Thu Apr 07 07:56:34 2005 +0000
     6.3 @@ -249,8 +249,4 @@ static inline int __vmxon (u64 addr)
     6.4      return 0;
     6.5  }
     6.6  
     6.7 -#define TRC_VMX_VMEXIT 0x00040001
     6.8 -#define TRC_VMX_VECTOR 0x00040002
     6.9 -#define TRC_VMX_INT    0x00040003
    6.10 -
    6.11  #endif /* __ASM_X86_VMX_H__ */
     7.1 --- a/xen/include/public/dom0_ops.h	Wed Apr 06 22:35:34 2005 +0000
     7.2 +++ b/xen/include/public/dom0_ops.h	Thu Apr 07 07:56:34 2005 +0000
     7.3 @@ -185,12 +185,20 @@ typedef struct {
     7.4  } dom0_pincpudomain_t;
     7.5  
     7.6  /* Get trace buffers machine base address */
     7.7 -#define DOM0_GETTBUFS         21
     7.8 +#define DOM0_TBUFCONTROL       21
     7.9  typedef struct {
    7.10 +    /* IN variables */
    7.11 +#define DOM0_TBUF_GET_INFO     0
    7.12 +#define DOM0_TBUF_SET_CPU_MASK 1
    7.13 +#define DOM0_TBUF_SET_EVT_MASK 2
    7.14 +    u8 op;
    7.15 +    /* IN/OUT variables */
    7.16 +    unsigned long cpu_mask;
    7.17 +    u32           evt_mask;
    7.18      /* OUT variables */
    7.19      memory_t mach_addr;
    7.20      u32      size;
    7.21 -} dom0_gettbufs_t;
    7.22 +} dom0_tbufcontrol_t;
    7.23  
    7.24  /*
    7.25   * Get physical information about the host machine
    7.26 @@ -374,9 +382,9 @@ typedef struct {
    7.27          dom0_msr_t               msr;
    7.28          dom0_debug_t             debug;
    7.29          dom0_settime_t           settime;
    7.30 -        dom0_readconsole_t	 readconsole;
    7.31 +        dom0_readconsole_t       readconsole;
    7.32          dom0_pincpudomain_t      pincpudomain;
    7.33 -        dom0_gettbufs_t          gettbufs;
    7.34 +        dom0_tbufcontrol_t       tbufcontrol;
    7.35          dom0_physinfo_t          physinfo;
    7.36          dom0_pcidev_access_t     pcidev_access;
    7.37          dom0_sched_id_t          sched_id;
     8.1 --- a/xen/include/public/trace.h	Wed Apr 06 22:35:34 2005 +0000
     8.2 +++ b/xen/include/public/trace.h	Thu Apr 07 07:56:34 2005 +0000
     8.3 @@ -1,17 +1,47 @@
     8.4  /******************************************************************************
     8.5 - * trace.h
     8.6 + * include/public/trace.h
     8.7   * 
     8.8   * Mark Williamson, (C) 2004 Intel Research Cambridge
     8.9 + * Copyright (C) 2005 Bin Ren
    8.10   */
    8.11  
    8.12  #ifndef __XEN_PUBLIC_TRACE_H__
    8.13  #define __XEN_PUBLIC_TRACE_H__
    8.14  
    8.15 +#include <asm/atomic.h>
    8.16 +
    8.17 +/* Trace classes */
    8.18 +#define TRC_GEN     0x00010000    /* General trace            */
    8.19 +#define TRC_SCHED   0x00020000    /* Xen Scheduler trace      */
    8.20 +#define TRC_DOM0OP  0x00040000    /* Xen DOM0 operation trace */
    8.21 +#define TRC_VMX     0x00080000    /* Xen VMX trace            */
    8.22 +#define TRC_ALL     0xffff0000
    8.23 +
    8.24 +/* Trace events per class */
    8.25 +
    8.26 +#define TRC_SCHED_DOM_ADD       (TRC_SCHED +  1)
    8.27 +#define TRC_SCHED_DOM_REM       (TRC_SCHED +  2)
    8.28 +#define TRC_SCHED_SLEEP         (TRC_SCHED +  3)
    8.29 +#define TRC_SCHED_WAKE          (TRC_SCHED +  4)
    8.30 +#define TRC_SCHED_YIELD         (TRC_SCHED +  5)
    8.31 +#define TRC_SCHED_BLOCK         (TRC_SCHED +  6)
    8.32 +#define TRC_SCHED_SHUTDOWN      (TRC_SCHED +  7)
    8.33 +#define TRC_SCHED_CTL           (TRC_SCHED +  8)
    8.34 +#define TRC_SCHED_ADJDOM        (TRC_SCHED +  9)
    8.35 +#define TRC_SCHED_SWITCH        (TRC_SCHED + 10)
    8.36 +#define TRC_SCHED_S_TIMER_FN    (TRC_SCHED + 11)
    8.37 +#define TRC_SCHED_T_TIMER_FN    (TRC_SCHED + 12)
    8.38 +#define TRC_SCHED_DOM_TIMER_FN  (TRC_SCHED + 13)
    8.39 +
    8.40 +#define TRC_VMX_VMEXIT          (TRC_VMX + 1)
    8.41 +#define TRC_VMX_VECTOR          (TRC_VMX + 2)
    8.42 +#define TRC_VMX_INT             (TRC_VMX + 3)
    8.43 +
    8.44  /* This structure represents a single trace buffer record. */
    8.45  struct t_rec {
    8.46 -    u64 cycles;               /* 64 bit cycle counter timestamp */
    8.47 -    u32 event;                /* 32 bit event ID                */
    8.48 -    u32 d1, d2, d3, d4, d5;   /* event data items               */
    8.49 +    u64 cycles;               /* cycle counter timestamp */
    8.50 +    u32 event;                /* event ID                */
    8.51 +    unsigned long data[5];    /* event data items        */
    8.52  };
    8.53  
    8.54  /*
    8.55 @@ -19,15 +49,13 @@ struct t_rec {
    8.56   * field, indexes into an array of struct t_rec's.
    8.57   */
    8.58  struct t_buf {
    8.59 -    unsigned long data;      /* pointer to data area.  machine address
    8.60 -                              * for convenience in user space code           */
    8.61 -
    8.62 -    unsigned long size;      /* size of the data area, in t_recs             */
    8.63 -    unsigned long head;      /* array index of the most recent record        */
    8.64 -
    8.65 -    /* Xen-private elements follow... */
    8.66 -    struct t_rec *head_ptr; /* pointer to the head record                    */
    8.67 -    struct t_rec *vdata;    /* virtual address pointer to data               */
    8.68 +    /* Used by both Xen and user space. */
    8.69 +    atomic_t      rec_idx;   /* the next record to save to */
    8.70 +    unsigned int  rec_num;   /* number of records in this trace buffer  */
    8.71 +    /* Used by Xen only. */
    8.72 +    struct t_rec  *rec;      /* start of records */
    8.73 +    /* Used by user space only. */
    8.74 +    unsigned long rec_addr;  /* machine address of the start of records */
    8.75  };
    8.76  
    8.77  #endif /* __XEN_PUBLIC_TRACE_H__ */
     9.1 --- a/xen/include/xen/trace.h	Wed Apr 06 22:35:34 2005 +0000
     9.2 +++ b/xen/include/xen/trace.h	Thu Apr 07 07:56:34 2005 +0000
     9.3 @@ -8,6 +8,8 @@
     9.4   * Author: Mark Williamson, mark.a.williamson@intel.com
     9.5   * Date:   January 2004
     9.6   *
     9.7 + * Copyright (C) 2005 Bin Ren
     9.8 + *
     9.9   * The trace buffer code is designed to allow debugging traces of Xen to be
    9.10   * generated on UP / SMP machines.  Each trace entry is timestamped so that
    9.11   * it's possible to reconstruct a chronological record of trace events.
    9.12 @@ -25,7 +27,6 @@
    9.13  
    9.14  #ifdef TRACE_BUFFER
    9.15  
    9.16 -#include <xen/spinlock.h>
    9.17  #include <asm/page.h>
    9.18  #include <xen/types.h>
    9.19  #include <xen/sched.h>
    9.20 @@ -34,11 +35,16 @@
    9.21  #include <asm/msr.h>
    9.22  #include <public/dom0_ops.h>
    9.23  
    9.24 +extern struct t_buf *t_bufs[];
    9.25 +extern int tb_init_done;
    9.26 +extern unsigned long tb_cpu_mask;
    9.27 +extern u32 tb_event_mask;
    9.28 +
    9.29  /* Used to initialise trace buffer functionality */
    9.30  void init_trace_bufs(void);
    9.31  
    9.32  /* used to retrieve the physical address of the trace buffers */
    9.33 -int get_tb_info(dom0_gettbufs_t *st);
    9.34 +int tb_control(dom0_tbufcontrol_t *tbc);
    9.35  
    9.36  /**
    9.37   * trace - Enters a trace tuple into the trace buffer for the current CPU.
    9.38 @@ -49,42 +55,43 @@ int get_tb_info(dom0_gettbufs_t *st);
    9.39   * failure, otherwise 0.  Failure occurs only if the trace buffers are not yet
    9.40   * initialised.
    9.41   */
    9.42 -static inline int trace(u32 event, u32 d1, u32 d2, u32 d3, u32 d4, u32 d5)
    9.43 +static inline int trace(u32 event, unsigned long d1, unsigned long d2,
    9.44 +                        unsigned long d3, unsigned long d4, unsigned long d5)
    9.45  {
    9.46 -    extern struct t_buf *t_bufs[];      /* global array of pointers to bufs */
    9.47 -    extern int tb_init_done;            /* set when buffers are initialised */
    9.48 -    unsigned long flags;                /* for saving interrupt flags       */
    9.49 -    struct t_buf *buf;                  /* the buffer we're working on      */
    9.50 -    struct t_rec *rec;                  /* next record to fill out          */
    9.51 -
    9.52 +    atomic_t old, new, seen;
    9.53 +    struct t_buf *buf;
    9.54 +    struct t_rec *rec;
    9.55  
    9.56      if ( !tb_init_done )
    9.57          return -1;
    9.58  
    9.59 +    if ( (tb_event_mask & event) == 0 )
    9.60 +        return 0;
    9.61 +
    9.62 +    if ( (tb_cpu_mask & (1UL << smp_processor_id())) == 0 )
    9.63 +        return 0;
    9.64  
    9.65      buf = t_bufs[smp_processor_id()];
    9.66  
    9.67 -    local_irq_save(flags);
    9.68 +    do
    9.69 +    {
    9.70 +        old = buf->rec_idx;
    9.71 +        _atomic_set(new, (_atomic_read(old) + 1) % buf->rec_num);
    9.72 +        seen = atomic_compareandswap(old, new, &buf->rec_idx);
    9.73 +    }
    9.74 +    while ( unlikely(_atomic_read(seen) != _atomic_read(old)) );
    9.75  
    9.76 -    rec = buf->head_ptr;
    9.77 +    wmb();
    9.78  
    9.79 +    rec = &buf->rec[_atomic_read(old)];
    9.80      rdtscll(rec->cycles);
    9.81 -    rec->event = event;
    9.82 -    rec->d1 = d1;
    9.83 -    rec->d2 = d2;
    9.84 -    rec->d3 = d3;
    9.85 -    rec->d4 = d4;
    9.86 -    rec->d5 = d5;
    9.87 +    rec->event   = event;
    9.88 +    rec->data[0] = d1;
    9.89 +    rec->data[1] = d2;
    9.90 +    rec->data[2] = d3;
    9.91 +    rec->data[3] = d4;
    9.92 +    rec->data[4] = d5;
    9.93  
    9.94 -    wmb(); /* above must be visible before reader sees index updated */
    9.95 -
    9.96 -    buf->head_ptr++;
    9.97 -    buf->head++;
    9.98 -    if ( buf->head_ptr == (buf->vdata + buf->size) )
    9.99 -        buf->head_ptr = buf->vdata;
   9.100 -
   9.101 -    local_irq_restore(flags);
   9.102 -    
   9.103      return 0;
   9.104  }
   9.105