Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.27-rc5 216 lines 3.7 kB view raw
1/** 2 * @file oprof.c 3 * 4 * @remark Copyright 2002 OProfile authors 5 * @remark Read the file COPYING 6 * 7 * @author John Levon <levon@movementarian.org> 8 */ 9 10#include <linux/kernel.h> 11#include <linux/module.h> 12#include <linux/init.h> 13#include <linux/oprofile.h> 14#include <linux/moduleparam.h> 15#include <asm/mutex.h> 16 17#include "oprof.h" 18#include "event_buffer.h" 19#include "cpu_buffer.h" 20#include "buffer_sync.h" 21#include "oprofile_stats.h" 22 23struct oprofile_operations oprofile_ops; 24 25unsigned long oprofile_started; 26unsigned long backtrace_depth; 27static unsigned long is_setup; 28static DEFINE_MUTEX(start_mutex); 29 30/* timer 31 0 - use performance monitoring hardware if available 32 1 - use the timer int mechanism regardless 33 */ 34static int timer = 0; 35 36int oprofile_setup(void) 37{ 38 int err; 39 40 mutex_lock(&start_mutex); 41 42 if ((err = alloc_cpu_buffers())) 43 goto out; 44 45 if ((err = alloc_event_buffer())) 46 goto out1; 47 48 if (oprofile_ops.setup && (err = oprofile_ops.setup())) 49 goto out2; 50 51 /* Note even though this starts part of the 52 * profiling overhead, it's necessary to prevent 53 * us missing task deaths and eventually oopsing 54 * when trying to process the event buffer. 55 */ 56 if (oprofile_ops.sync_start) { 57 int sync_ret = oprofile_ops.sync_start(); 58 switch (sync_ret) { 59 case 0: 60 goto post_sync; 61 case 1: 62 goto do_generic; 63 case -1: 64 goto out3; 65 default: 66 goto out3; 67 } 68 } 69do_generic: 70 if ((err = sync_start())) 71 goto out3; 72 73post_sync: 74 is_setup = 1; 75 mutex_unlock(&start_mutex); 76 return 0; 77 78out3: 79 if (oprofile_ops.shutdown) 80 oprofile_ops.shutdown(); 81out2: 82 free_event_buffer(); 83out1: 84 free_cpu_buffers(); 85out: 86 mutex_unlock(&start_mutex); 87 return err; 88} 89 90 91/* Actually start profiling (echo 1>/dev/oprofile/enable) */ 92int oprofile_start(void) 93{ 94 int err = -EINVAL; 95 96 mutex_lock(&start_mutex); 97 98 if (!is_setup) 99 goto out; 100 101 err = 0; 102 103 if (oprofile_started) 104 goto out; 105 106 oprofile_reset_stats(); 107 108 if ((err = oprofile_ops.start())) 109 goto out; 110 111 oprofile_started = 1; 112out: 113 mutex_unlock(&start_mutex); 114 return err; 115} 116 117 118/* echo 0>/dev/oprofile/enable */ 119void oprofile_stop(void) 120{ 121 mutex_lock(&start_mutex); 122 if (!oprofile_started) 123 goto out; 124 oprofile_ops.stop(); 125 oprofile_started = 0; 126 /* wake up the daemon to read what remains */ 127 wake_up_buffer_waiter(); 128out: 129 mutex_unlock(&start_mutex); 130} 131 132 133void oprofile_shutdown(void) 134{ 135 mutex_lock(&start_mutex); 136 if (oprofile_ops.sync_stop) { 137 int sync_ret = oprofile_ops.sync_stop(); 138 switch (sync_ret) { 139 case 0: 140 goto post_sync; 141 case 1: 142 goto do_generic; 143 default: 144 goto post_sync; 145 } 146 } 147do_generic: 148 sync_stop(); 149post_sync: 150 if (oprofile_ops.shutdown) 151 oprofile_ops.shutdown(); 152 is_setup = 0; 153 free_event_buffer(); 154 free_cpu_buffers(); 155 mutex_unlock(&start_mutex); 156} 157 158 159int oprofile_set_backtrace(unsigned long val) 160{ 161 int err = 0; 162 163 mutex_lock(&start_mutex); 164 165 if (oprofile_started) { 166 err = -EBUSY; 167 goto out; 168 } 169 170 if (!oprofile_ops.backtrace) { 171 err = -EINVAL; 172 goto out; 173 } 174 175 backtrace_depth = val; 176 177out: 178 mutex_unlock(&start_mutex); 179 return err; 180} 181 182static int __init oprofile_init(void) 183{ 184 int err; 185 186 err = oprofile_arch_init(&oprofile_ops); 187 188 if (err < 0 || timer) { 189 printk(KERN_INFO "oprofile: using timer interrupt.\n"); 190 oprofile_timer_init(&oprofile_ops); 191 } 192 193 err = oprofilefs_register(); 194 if (err) 195 oprofile_arch_exit(); 196 197 return err; 198} 199 200 201static void __exit oprofile_exit(void) 202{ 203 oprofilefs_unregister(); 204 oprofile_arch_exit(); 205} 206 207 208module_init(oprofile_init); 209module_exit(oprofile_exit); 210 211module_param_named(timer, timer, int, 0644); 212MODULE_PARM_DESC(timer, "force use of timer interrupt"); 213 214MODULE_LICENSE("GPL"); 215MODULE_AUTHOR("John Levon <levon@movementarian.org>"); 216MODULE_DESCRIPTION("OProfile system profiler");