diff options
Diffstat (limited to 'drivers/oprofile/cpu_buffer.c')
-rw-r--r-- | drivers/oprofile/cpu_buffer.c | 48 |
1 files changed, 15 insertions, 33 deletions
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c index e1bd5a937f6c..d6c68270b3da 100644 --- a/drivers/oprofile/cpu_buffer.c +++ b/drivers/oprofile/cpu_buffer.c | |||
@@ -257,21 +257,23 @@ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) | |||
257 | 257 | ||
258 | #ifdef CONFIG_OPROFILE_IBS | 258 | #ifdef CONFIG_OPROFILE_IBS |
259 | 259 | ||
260 | #define MAX_IBS_SAMPLE_SIZE 14 | 260 | #define MAX_IBS_SAMPLE_SIZE 14 |
261 | static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf, | 261 | |
262 | unsigned long pc, int is_kernel, unsigned int *ibs, int ibs_code) | 262 | void oprofile_add_ibs_sample(struct pt_regs *const regs, |
263 | unsigned int * const ibs_sample, int ibs_code) | ||
263 | { | 264 | { |
265 | int is_kernel = !user_mode(regs); | ||
266 | struct oprofile_cpu_buffer *cpu_buf = &__get_cpu_var(cpu_buffer); | ||
264 | struct task_struct *task; | 267 | struct task_struct *task; |
265 | 268 | ||
266 | cpu_buf->sample_received++; | 269 | cpu_buf->sample_received++; |
267 | 270 | ||
268 | if (nr_available_slots(cpu_buf) < MAX_IBS_SAMPLE_SIZE) { | 271 | if (nr_available_slots(cpu_buf) < MAX_IBS_SAMPLE_SIZE) { |
272 | /* we can't backtrace since we lost the source of this event */ | ||
269 | cpu_buf->sample_lost_overflow++; | 273 | cpu_buf->sample_lost_overflow++; |
270 | return 0; | 274 | return; |
271 | } | 275 | } |
272 | 276 | ||
273 | is_kernel = !!is_kernel; | ||
274 | |||
275 | /* notice a switch from user->kernel or vice versa */ | 277 | /* notice a switch from user->kernel or vice versa */ |
276 | if (cpu_buf->last_is_kernel != is_kernel) { | 278 | if (cpu_buf->last_is_kernel != is_kernel) { |
277 | cpu_buf->last_is_kernel = is_kernel; | 279 | cpu_buf->last_is_kernel = is_kernel; |
@@ -281,7 +283,6 @@ static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf, | |||
281 | /* notice a task switch */ | 283 | /* notice a task switch */ |
282 | if (!is_kernel) { | 284 | if (!is_kernel) { |
283 | task = current; | 285 | task = current; |
284 | |||
285 | if (cpu_buf->last_task != task) { | 286 | if (cpu_buf->last_task != task) { |
286 | cpu_buf->last_task = task; | 287 | cpu_buf->last_task = task; |
287 | add_code(cpu_buf, (unsigned long)task); | 288 | add_code(cpu_buf, (unsigned long)task); |
@@ -289,36 +290,17 @@ static int log_ibs_sample(struct oprofile_cpu_buffer *cpu_buf, | |||
289 | } | 290 | } |
290 | 291 | ||
291 | add_code(cpu_buf, ibs_code); | 292 | add_code(cpu_buf, ibs_code); |
292 | add_sample(cpu_buf, ibs[0], ibs[1]); | 293 | add_sample(cpu_buf, ibs_sample[0], ibs_sample[1]); |
293 | add_sample(cpu_buf, ibs[2], ibs[3]); | 294 | add_sample(cpu_buf, ibs_sample[2], ibs_sample[3]); |
294 | add_sample(cpu_buf, ibs[4], ibs[5]); | 295 | add_sample(cpu_buf, ibs_sample[4], ibs_sample[5]); |
295 | 296 | ||
296 | if (ibs_code == IBS_OP_BEGIN) { | 297 | if (ibs_code == IBS_OP_BEGIN) { |
297 | add_sample(cpu_buf, ibs[6], ibs[7]); | 298 | add_sample(cpu_buf, ibs_sample[6], ibs_sample[7]); |
298 | add_sample(cpu_buf, ibs[8], ibs[9]); | 299 | add_sample(cpu_buf, ibs_sample[8], ibs_sample[9]); |
299 | add_sample(cpu_buf, ibs[10], ibs[11]); | 300 | add_sample(cpu_buf, ibs_sample[10], ibs_sample[11]); |
300 | } | ||
301 | |||
302 | return 1; | ||
303 | } | ||
304 | |||
305 | void oprofile_add_ibs_sample(struct pt_regs *const regs, | ||
306 | unsigned int * const ibs_sample, u8 code) | ||
307 | { | ||
308 | int is_kernel = !user_mode(regs); | ||
309 | unsigned long pc = profile_pc(regs); | ||
310 | |||
311 | struct oprofile_cpu_buffer *cpu_buf = | ||
312 | &per_cpu(cpu_buffer, smp_processor_id()); | ||
313 | |||
314 | if (!backtrace_depth) { | ||
315 | log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code); | ||
316 | return; | ||
317 | } | 301 | } |
318 | 302 | ||
319 | /* if log_sample() fails we can't backtrace since we lost the source | 303 | if (backtrace_depth) |
320 | * of this event */ | ||
321 | if (log_ibs_sample(cpu_buf, pc, is_kernel, ibs_sample, code)) | ||
322 | oprofile_ops.backtrace(regs, backtrace_depth); | 304 | oprofile_ops.backtrace(regs, backtrace_depth); |
323 | } | 305 | } |
324 | 306 | ||