ia64/linux-2.6.18-xen.hg

diff drivers/oprofile/buffer_sync.c @ 15:132f24200f4c

Imported patch xenoprof-generic.patch from xen-unstable.hg 15200:bd3d6b4c52ec
author Ian Campbell <ian.campbell@xensource.com>
date Mon Jun 04 10:05:24 2007 +0100 (2007-06-04)
parents 831230e53067
children
line diff
     1.1 --- a/drivers/oprofile/buffer_sync.c	Mon Jun 04 10:05:24 2007 +0100
     1.2 +++ b/drivers/oprofile/buffer_sync.c	Mon Jun 04 10:05:24 2007 +0100
     1.3 @@ -6,6 +6,10 @@
     1.4   *
     1.5   * @author John Levon <levon@movementarian.org>
     1.6   *
     1.7 + * Modified by Aravind Menon for Xen
     1.8 + * These modifications are:
     1.9 + * Copyright (C) 2005 Hewlett-Packard Co.
    1.10 + *
    1.11   * This is the core of the buffer management. Each
    1.12   * CPU buffer is processed and entered into the
    1.13   * global event buffer. Such processing is necessary
    1.14 @@ -38,6 +42,7 @@ static cpumask_t marked_cpus = CPU_MASK_
    1.15  static DEFINE_SPINLOCK(task_mortuary);
    1.16  static void process_task_mortuary(void);
    1.17  
    1.18 +static int cpu_current_domain[NR_CPUS];
    1.19  
    1.20  /* Take ownership of the task struct and place it on the
    1.21   * list for processing. Only after two full buffer syncs
    1.22 @@ -146,6 +151,11 @@ static void end_sync(void)
    1.23  int sync_start(void)
    1.24  {
    1.25  	int err;
    1.26 +	int i;
    1.27 +
    1.28 +	for (i = 0; i < NR_CPUS; i++) {
    1.29 +		cpu_current_domain[i] = COORDINATOR_DOMAIN;
    1.30 +	}
    1.31  
    1.32  	start_cpu_work();
    1.33  
    1.34 @@ -275,15 +285,31 @@ static void add_cpu_switch(int i)
    1.35  	last_cookie = INVALID_COOKIE;
    1.36  }
    1.37  
    1.38 -static void add_kernel_ctx_switch(unsigned int in_kernel)
    1.39 +static void add_cpu_mode_switch(unsigned int cpu_mode)
    1.40  {
    1.41  	add_event_entry(ESCAPE_CODE);
    1.42 -	if (in_kernel)
    1.43 -		add_event_entry(KERNEL_ENTER_SWITCH_CODE); 
    1.44 -	else
    1.45 -		add_event_entry(KERNEL_EXIT_SWITCH_CODE); 
    1.46 +	switch (cpu_mode) {
    1.47 +	case CPU_MODE_USER:
    1.48 +		add_event_entry(USER_ENTER_SWITCH_CODE);
    1.49 +		break;
    1.50 +	case CPU_MODE_KERNEL:
    1.51 +		add_event_entry(KERNEL_ENTER_SWITCH_CODE);
    1.52 +		break;
    1.53 +	case CPU_MODE_XEN:
    1.54 +		add_event_entry(XEN_ENTER_SWITCH_CODE);
    1.55 +	  	break;
    1.56 +	default:
    1.57 +		break;
    1.58 +	}
    1.59  }
    1.60 - 
    1.61 +
    1.62 +static void add_domain_switch(unsigned long domain_id)
    1.63 +{
    1.64 +	add_event_entry(ESCAPE_CODE);
    1.65 +	add_event_entry(DOMAIN_SWITCH_CODE);
    1.66 +	add_event_entry(domain_id);
    1.67 +}
    1.68 +
    1.69  static void
    1.70  add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
    1.71  {
    1.72 @@ -348,9 +374,9 @@ static int add_us_sample(struct mm_struc
    1.73   * for later lookup from userspace.
    1.74   */
    1.75  static int
    1.76 -add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
    1.77 +add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
    1.78  {
    1.79 -	if (in_kernel) {
    1.80 +	if (cpu_mode >= CPU_MODE_KERNEL) {
    1.81  		add_sample_entry(s->eip, s->event);
    1.82  		return 1;
    1.83  	} else if (mm) {
    1.84 @@ -496,15 +522,21 @@ void sync_buffer(int cpu)
    1.85  	struct mm_struct *mm = NULL;
    1.86  	struct task_struct * new;
    1.87  	unsigned long cookie = 0;
    1.88 -	int in_kernel = 1;
    1.89 +	int cpu_mode = 1;
    1.90  	unsigned int i;
    1.91  	sync_buffer_state state = sb_buffer_start;
    1.92  	unsigned long available;
    1.93 +	int domain_switch = 0;
    1.94  
    1.95  	mutex_lock(&buffer_mutex);
    1.96   
    1.97  	add_cpu_switch(cpu);
    1.98  
    1.99 +	/* We need to assign the first samples in this CPU buffer to the
   1.100 +	   same domain that we were processing at the last sync_buffer */
   1.101 +	if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
   1.102 +		add_domain_switch(cpu_current_domain[cpu]);
   1.103 +	}
   1.104  	/* Remember, only we can modify tail_pos */
   1.105  
   1.106  	available = get_slots(cpu_buf);
   1.107 @@ -512,16 +544,18 @@ void sync_buffer(int cpu)
   1.108  	for (i = 0; i < available; ++i) {
   1.109  		struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
   1.110   
   1.111 -		if (is_code(s->eip)) {
   1.112 -			if (s->event <= CPU_IS_KERNEL) {
   1.113 -				/* kernel/userspace switch */
   1.114 -				in_kernel = s->event;
   1.115 +		if (is_code(s->eip) && !domain_switch) {
   1.116 +			if (s->event <= CPU_MODE_XEN) {
   1.117 +				/* xen/kernel/userspace switch */
   1.118 +				cpu_mode = s->event;
   1.119  				if (state == sb_buffer_start)
   1.120  					state = sb_sample_start;
   1.121 -				add_kernel_ctx_switch(s->event);
   1.122 +				add_cpu_mode_switch(s->event);
   1.123  			} else if (s->event == CPU_TRACE_BEGIN) {
   1.124  				state = sb_bt_start;
   1.125  				add_trace_begin();
   1.126 +			} else if (s->event == CPU_DOMAIN_SWITCH) {
   1.127 +					domain_switch = 1;				
   1.128  			} else {
   1.129  				struct mm_struct * oldmm = mm;
   1.130  
   1.131 @@ -535,11 +569,21 @@ void sync_buffer(int cpu)
   1.132  				add_user_ctx_switch(new, cookie);
   1.133  			}
   1.134  		} else {
   1.135 -			if (state >= sb_bt_start &&
   1.136 -			    !add_sample(mm, s, in_kernel)) {
   1.137 -				if (state == sb_bt_start) {
   1.138 -					state = sb_bt_ignore;
   1.139 -					atomic_inc(&oprofile_stats.bt_lost_no_mapping);
   1.140 +			if (domain_switch) {
   1.141 +				cpu_current_domain[cpu] = s->eip;
   1.142 +				add_domain_switch(s->eip);
   1.143 +				domain_switch = 0;
   1.144 +			} else {
   1.145 +				if (cpu_current_domain[cpu] !=
   1.146 +				    COORDINATOR_DOMAIN) {
   1.147 +					add_sample_entry(s->eip, s->event);
   1.148 +				}
   1.149 +				else  if (state >= sb_bt_start &&
   1.150 +				    !add_sample(mm, s, cpu_mode)) {
   1.151 +					if (state == sb_bt_start) {
   1.152 +						state = sb_bt_ignore;
   1.153 +						atomic_inc(&oprofile_stats.bt_lost_no_mapping);
   1.154 +					}
   1.155  				}
   1.156  			}
   1.157  		}
   1.158 @@ -548,6 +592,11 @@ void sync_buffer(int cpu)
   1.159  	}
   1.160  	release_mm(mm);
   1.161  
   1.162 +	/* We reset domain to COORDINATOR at each CPU switch */
   1.163 +	if (cpu_current_domain[cpu] != COORDINATOR_DOMAIN) {
   1.164 +		add_domain_switch(COORDINATOR_DOMAIN);
   1.165 +	}
   1.166 +
   1.167  	mark_done(cpu);
   1.168  
   1.169  	mutex_unlock(&buffer_mutex);