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