ia64/xen-unstable

changeset 3958:5da9d0d86aef

bitkeeper revision 1.1236.1.41 (4224ab34YunoDc0_FV3T0OZPcJ0Pcw)

Performance counters for hypercalls and exceptions. Perfctr histograms
for pagetable updates.
Signed-off-by: Rolf Neugebauer <rolf.neugebauer@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@cl.cam.ac.uk>
author kaf24@scramble.cl.cam.ac.uk
date Tue Mar 01 17:49:40 2005 +0000 (2005-03-01)
parents 31829289d0a1
children da3bec7765d1
files xen/arch/x86/mm.c xen/arch/x86/x86_32/asm-offsets.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_64/asm-offsets.c xen/arch/x86/x86_64/entry.S xen/common/perfc.c xen/include/asm-x86/x86_32/asm_defns.h xen/include/asm-x86/x86_64/asm_defns.h xen/include/xen/perfc.h xen/include/xen/perfc_defn.h
line diff
     1.1 --- a/xen/arch/x86/mm.c	Tue Mar 01 17:41:05 2005 +0000
     1.2 +++ b/xen/arch/x86/mm.c	Tue Mar 01 17:49:40 2005 +0000
     1.3 @@ -1687,6 +1687,7 @@ int do_mmu_update(
     1.4  
     1.5      perfc_incrc(calls_to_mmu_update); 
     1.6      perfc_addc(num_page_updates, count);
     1.7 +    perfc_incr_histo(bpt_updates, count, PT_UPDATES);
     1.8  
     1.9      if ( unlikely(!array_access_ok(VERIFY_READ, ureqs, count, sizeof(req))) )
    1.10      {
    1.11 @@ -2234,6 +2235,9 @@ void ptwr_flush(const int which)
    1.12      int            i, cpu = smp_processor_id();
    1.13      struct exec_domain *ed = current;
    1.14      struct domain *d = ed->domain;
    1.15 +#ifdef PERF_COUNTERS
    1.16 +    unsigned int   modified = 0;
    1.17 +#endif
    1.18  
    1.19      l1va = ptwr_info[cpu].ptinfo[which].l1va;
    1.20      ptep = (unsigned long *)&linear_pg_table[l1_linear_offset(l1va)];
    1.21 @@ -2302,6 +2306,11 @@ void ptwr_flush(const int which)
    1.22          if ( likely(l1_pgentry_val(ol1e) == l1_pgentry_val(nl1e)) )
    1.23              continue;
    1.24  
    1.25 +#ifdef PERF_COUNTERS
    1.26 +        /* Update number of entries modified. */
    1.27 +        modified++;
    1.28 +#endif
    1.29 +
    1.30          /*
    1.31           * Fast path for PTEs that have merely been write-protected
    1.32           * (e.g., during a Unix fork()). A strict reduction in privilege.
    1.33 @@ -2343,6 +2352,8 @@ void ptwr_flush(const int which)
    1.34      }
    1.35      unmap_domain_mem(pl1e);
    1.36  
    1.37 +    perfc_incr_histo(wpt_updates, modified, PT_UPDATES);
    1.38 +
    1.39      /*
    1.40       * STEP 3. Reattach the L1 p.t. page into the current address space.
    1.41       */
     2.1 --- a/xen/arch/x86/x86_32/asm-offsets.c	Tue Mar 01 17:41:05 2005 +0000
     2.2 +++ b/xen/arch/x86/x86_32/asm-offsets.c	Tue Mar 01 17:49:40 2005 +0000
     2.3 @@ -4,6 +4,7 @@
     2.4   * to extract and format the required data.
     2.5   */
     2.6  
     2.7 +#include <xen/config.h>
     2.8  #include <xen/sched.h>
     2.9  
    2.10  #define DEFINE(_sym, _val) \
    2.11 @@ -58,6 +59,12 @@ void __dummy__(void)
    2.12      OFFSET(TRAPBOUNCE_eip, struct trap_bounce, eip);
    2.13      BLANK();
    2.14  
    2.15 +#if PERF_COUNTERS
    2.16 +    OFFSET(PERFC_hypercalls, struct perfcounter, hypercalls);
    2.17 +    OFFSET(PERFC_exceptions, struct perfcounter, exceptions);
    2.18 +    BLANK();
    2.19 +#endif
    2.20 +
    2.21      OFFSET(MULTICALL_op, multicall_entry_t, op);
    2.22      OFFSET(MULTICALL_arg0, multicall_entry_t, args[0]);
    2.23      OFFSET(MULTICALL_arg1, multicall_entry_t, args[1]);
     3.1 --- a/xen/arch/x86/x86_32/entry.S	Tue Mar 01 17:41:05 2005 +0000
     3.2 +++ b/xen/arch/x86/x86_32/entry.S	Tue Mar 01 17:49:40 2005 +0000
     3.3 @@ -280,8 +280,9 @@ ENTRY(hypercall)
     3.4  	SAVE_ALL(b)
     3.5          sti
     3.6          GET_CURRENT(%ebx)
     3.7 -	andl $(NR_hypercalls-1),%eax
     3.8 -	call *SYMBOL_NAME(hypercall_table)(,%eax,4)
     3.9 +        andl $(NR_hypercalls-1),%eax
    3.10 +        PERFC_INCR(PERFC_hypercalls, %eax)
    3.11 +        call *SYMBOL_NAME(hypercall_table)(,%eax,4)
    3.12          movl %eax,XREGS_eax(%esp)       # save the return value
    3.13  
    3.14  test_all_events:
    3.15 @@ -468,6 +469,7 @@ 1:      sti                             
    3.16          movl  %esp,%edx
    3.17  	pushl %edx			# push the xen_regs pointer
    3.18  	GET_CURRENT(%ebx)
    3.19 +        PERFC_INCR(PERFC_exceptions, %eax)
    3.20  	call  *SYMBOL_NAME(exception_table)(,%eax,4)
    3.21          addl  $4,%esp
    3.22          movl  XREGS_eflags(%esp),%eax
     4.1 --- a/xen/arch/x86/x86_64/asm-offsets.c	Tue Mar 01 17:41:05 2005 +0000
     4.2 +++ b/xen/arch/x86/x86_64/asm-offsets.c	Tue Mar 01 17:49:40 2005 +0000
     4.3 @@ -4,6 +4,7 @@
     4.4   * to extract and format the required data.
     4.5   */
     4.6  
     4.7 +#include <xen/config.h>
     4.8  #include <xen/sched.h>
     4.9  
    4.10  #define DEFINE(_sym, _val) \
    4.11 @@ -62,6 +63,12 @@ void __dummy__(void)
    4.12      OFFSET(TRAPBOUNCE_eip, struct trap_bounce, eip);
    4.13      BLANK();
    4.14  
    4.15 +#if PERF_COUNTERS
    4.16 +    OFFSET(PERFC_hypercalls, struct perfcounter, hypercalls);
    4.17 +    OFFSET(PERFC_exceptions, struct perfcounter, exceptions);
    4.18 +    BLANK();
    4.19 +#endif
    4.20 +
    4.21      OFFSET(MULTICALL_op, multicall_entry_t, op);
    4.22      OFFSET(MULTICALL_arg0, multicall_entry_t, args[0]);
    4.23      OFFSET(MULTICALL_arg1, multicall_entry_t, args[1]);
     5.1 --- a/xen/arch/x86/x86_64/entry.S	Tue Mar 01 17:41:05 2005 +0000
     5.2 +++ b/xen/arch/x86/x86_64/entry.S	Tue Mar 01 17:49:40 2005 +0000
     5.3 @@ -141,6 +141,7 @@ hypercall:
     5.4          movq  %r10,%rcx
     5.5          andq  $(NR_hypercalls-1),%rax
     5.6          leaq  SYMBOL_NAME(hypercall_table)(%rip),%r10
     5.7 +        PERFC_INCR(PERFC_hypercalls, %rax)
     5.8          callq *(%r10,%rax,8)
     5.9          movq %rax,XREGS_rax(%rsp)       # save the return value
    5.10  
    5.11 @@ -297,6 +298,7 @@ 1:      sti
    5.12          movl  XREGS_entry_vector(%rsp),%eax
    5.13          leaq  SYMBOL_NAME(exception_table)(%rip),%rdx
    5.14          GET_CURRENT(%rbx)
    5.15 +        PERFC_INCR(PERFC_exceptions, %rax)
    5.16          callq *(%rdx,%rax,8)
    5.17          testb $3,XREGS_cs(%rsp)
    5.18          jz    restore_all_xen
     6.1 --- a/xen/common/perfc.c	Tue Mar 01 17:41:05 2005 +0000
     6.2 +++ b/xen/common/perfc.c	Tue Mar 01 17:49:40 2005 +0000
     6.3 @@ -67,7 +67,11 @@ void perfc_printall(unsigned char key)
     6.4                  sum += atomic_read(&counters[j]);
     6.5              printk("TOTAL[%10d]  ", sum);
     6.6              for ( j = 0; j < perfc_info[i].nr_elements; j++ )
     6.7 +            {
     6.8 +                if ( (j != 0) && ((j % 4) == 0) )
     6.9 +                    printk("\n                   ");
    6.10                  printk("ARR%02d[%10d]  ", j, atomic_read(&counters[j]));
    6.11 +            }
    6.12              counters += j;
    6.13              break;
    6.14          }
     7.1 --- a/xen/include/asm-x86/x86_32/asm_defns.h	Tue Mar 01 17:41:05 2005 +0000
     7.2 +++ b/xen/include/asm-x86/x86_32/asm_defns.h	Tue Mar 01 17:49:40 2005 +0000
     7.3 @@ -76,6 +76,13 @@
     7.4          SET_XEN_SEGMENTS(_reg) \
     7.5          1:
     7.6  
     7.7 +#ifdef PERF_COUNTERS
     7.8 +#define PERFC_INCR(_name,_idx) \
     7.9 +    lock incl SYMBOL_NAME(perfcounters)+_name(,_idx,4)
    7.10 +#else
    7.11 +#define PERFC_INCR(_name,_idx)
    7.12 +#endif
    7.13 +
    7.14  #endif
    7.15  
    7.16  #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
     8.1 --- a/xen/include/asm-x86/x86_64/asm_defns.h	Tue Mar 01 17:41:05 2005 +0000
     8.2 +++ b/xen/include/asm-x86/x86_64/asm_defns.h	Tue Mar 01 17:49:40 2005 +0000
     8.3 @@ -76,6 +76,16 @@
     8.4          popq  %rsi; \
     8.5          popq  %rdi;
     8.6  
     8.7 +#ifdef PERF_COUNTERS
     8.8 +#define PERFC_INCR(_name,_idx) \
     8.9 +    pushq %rdx; \
    8.10 +    leaq SYMBOL_NAME(perfcounters)+_name(%rip),%rdx; \
    8.11 +    lock incl (%rdx,_idx,4); \
    8.12 +    popq %rdx;
    8.13 +#else
    8.14 +#define PERFC_INCR(_name,_idx)
    8.15 +#endif
    8.16 +
    8.17  #endif
    8.18  
    8.19  #define BUILD_SMP_INTERRUPT(x,v) XBUILD_SMP_INTERRUPT(x,v)
     9.1 --- a/xen/include/xen/perfc.h	Tue Mar 01 17:41:05 2005 +0000
     9.2 +++ b/xen/include/xen/perfc.h	Tue Mar 01 17:49:40 2005 +0000
     9.3 @@ -54,26 +54,51 @@ extern struct perfcounter perfcounters;
     9.4  
     9.5  #define perfc_value(x)    atomic_read(&perfcounters.x[0])
     9.6  #define perfc_valuec(x)   atomic_read(&perfcounters.x[smp_processor_id()])
     9.7 -#define perfc_valuea(x,y) \
     9.8 -  { if(y<(sizeof(perfcounters.x)/sizeof(*perfcounters.x))) \
     9.9 -    atomic_read(&perfcounters.x[y]); }
    9.10 +#define perfc_valuea(x,y)                                               \
    9.11 +    do {                                                                \
    9.12 +        if ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ) \
    9.13 +            atomic_read(&perfcounters.x[y]);                            \
    9.14 +    } while ( 0 )
    9.15  #define perfc_set(x,v)    atomic_set(&perfcounters.x[0], v)
    9.16  #define perfc_setc(x,v)   atomic_set(&perfcounters.x[smp_processor_id()], v)
    9.17 -#define perfc_seta(x,y,v) \
    9.18 -  { if(y<(sizeof(perfcounters.x)/sizeof(*perfcounters.x))) \
    9.19 -    atomic_set(&perfcounters.x[y], v); }
    9.20 +#define perfc_seta(x,y,v)                                               \
    9.21 +    do {                                                                \
    9.22 +        if ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ) \
    9.23 +            atomic_set(&perfcounters.x[y], v);                          \
    9.24 +    } while ( 0 )
    9.25  #define perfc_incr(x)     atomic_inc(&perfcounters.x[0])
    9.26  #define perfc_decr(x)     atomic_dec(&perfcounters.x[0])
    9.27  #define perfc_incrc(x)    atomic_inc(&perfcounters.x[smp_processor_id()])
    9.28 -#define perfc_incra(x,y)  \
    9.29 -  { if(y<(sizeof(perfcounters.x)/sizeof(*perfcounters.x))) \
    9.30 -    atomic_inc(&perfcounters.x[y]); }
    9.31 +#define perfc_incra(x,y)                                                \
    9.32 +    do {                                                                \
    9.33 +        if ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ) \
    9.34 +            atomic_inc(&perfcounters.x[y]);                             \
    9.35 +    } while ( 0 )
    9.36  #define perfc_add(x,y)    atomic_add((y), &perfcounters.x[0])
    9.37  #define perfc_addc(x,y)   atomic_add((y), &perfcounters.x[smp_processor_id()])
    9.38 -#define perfc_adda(x,y,z) \
    9.39 -  { if(y<(sizeof(perfcounters.x)/sizeof(*perfcounters.x))) \
    9.40 -    atomic_add((z), &perfcounters.x[y]); }
    9.41 +#define perfc_adda(x,y,z)                                               \
    9.42 +    do {                                                                \
    9.43 +        if ( (y) < (sizeof(perfcounters.x) / sizeof(*perfcounters.x)) ) \
    9.44 +            atomic_add((z), &perfcounters.x[y]);                        \
    9.45 +    } while ( 0 )
    9.46  
    9.47 +/*
    9.48 + * Histogram: special treatment for 0 and 1 count. After that equally spaced 
    9.49 + * with last bucket taking the rest.
    9.50 + */
    9.51 +#define perfc_incr_histo(_x,_v,_n)                                          \
    9.52 +    do {                                                                    \
    9.53 +        if ( (_v) == 0 )                                                    \
    9.54 +            perfc_incra(_x, 0);                                             \
    9.55 +        else if ( (_v) == 1 )                                               \
    9.56 +            perfc_incra(_x, 1);                                             \
    9.57 +        else if ( (((_v)-2) / PERFC_ ## _n ## _BUCKET_SIZE) <               \
    9.58 +                  (PERFC_MAX_ ## _n - 3) )                                  \
    9.59 +            perfc_incra(_x, (((_v)-2) / PERFC_ ## _n ## _BUCKET_SIZE) + 2); \
    9.60 +        else                                                                \
    9.61 +            perfc_incra(_x, PERFC_MAX_ ## _n - 1);                          \
    9.62 +    } while ( 0 )
    9.63 +    
    9.64  #else /* PERF_COUNTERS */
    9.65  
    9.66  #define perfc_value(x)    (0)
    9.67 @@ -89,6 +114,7 @@ extern struct perfcounter perfcounters;
    9.68  #define perfc_add(x,y)    ((void)0)
    9.69  #define perfc_addc(x,y)   ((void)0)
    9.70  #define perfc_adda(x,y,z) ((void)0)
    9.71 +#define perfc_incr_histo(x,y,z) ((void)0)
    9.72  
    9.73  #endif /* PERF_COUNTERS */
    9.74  
    10.1 --- a/xen/include/xen/perfc_defn.h	Tue Mar 01 17:41:05 2005 +0000
    10.2 +++ b/xen/include/xen/perfc_defn.h	Tue Mar 01 17:49:40 2005 +0000
    10.3 @@ -36,7 +36,15 @@ PERFSTATUS( hl2_table_pages, "current # 
    10.4  PERFCOUNTER_CPU( check_pagetable, "calls to check_pagetable" )
    10.5  PERFCOUNTER_CPU( check_all_pagetables, "calls to check_all_pagetables" )
    10.6  
    10.7 +#define PERFC_MAX_PT_UPDATES 64
    10.8 +#define PERFC_PT_UPDATES_BUCKET_SIZE 3
    10.9 +PERFCOUNTER_ARRAY( wpt_updates, "writable pt updates", PERFC_MAX_PT_UPDATES )
   10.10 +PERFCOUNTER_ARRAY( bpt_updates, "batched pt updates", PERFC_MAX_PT_UPDATES )
   10.11 +
   10.12 +PERFCOUNTER_ARRAY( hypercalls, "hypercalls", NR_hypercalls )
   10.13 +PERFCOUNTER_ARRAY( exceptions, "exceptions", 32 )
   10.14 +
   10.15  #define VMX_PERF_EXIT_REASON_SIZE 37
   10.16  #define VMX_PERF_VECTOR_SIZE 0x20
   10.17 -PERFCOUNTER_ARRAY(vmexits, "vmexits", VMX_PERF_EXIT_REASON_SIZE )
   10.18 -PERFCOUNTER_ARRAY(cause_vector, "cause vector", VMX_PERF_VECTOR_SIZE )
   10.19 +PERFCOUNTER_ARRAY( vmexits, "vmexits", VMX_PERF_EXIT_REASON_SIZE )
   10.20 +PERFCOUNTER_ARRAY( cause_vector, "cause vector", VMX_PERF_VECTOR_SIZE )