aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Carmody <ext-phil.2.carmody@nokia.com>2010-04-28 13:09:16 -0400
committerRobert Richter <robert.richter@amd.com>2010-05-03 17:02:39 -0400
commit9414e99672271adcc661f3c160a30b374179b92f (patch)
treeda2052d48666552400b3204f15bb18b58156065f
parentb971f06187d83b5c03d2b597cccdfef421c0ca91 (diff)
oprofile: protect from not being in an IRQ context
http://lkml.org/lkml/2010/4/27/285 Protect against dereferencing regs when it's NULL, and force a magic number into pc to prevent too deep processing. This approach permits the dropped samples to be tallied as invalid Instruction Pointer events. e.g. output from about 15mins at 10kHz sample rate: Nr. samples received: 2565380 Nr. samples lost invalid pc: 4 Signed-off-by: Phil Carmody <ext-phil.2.carmody@nokia.com> Signed-off-by: Robert Richter <robert.richter@amd.com>
-rw-r--r--drivers/oprofile/cpu_buffer.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index 0ac8b065ee02..219f79e2210a 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -319,8 +319,16 @@ void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs,
319 319
320void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) 320void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
321{ 321{
322 int is_kernel = !user_mode(regs); 322 int is_kernel;
323 unsigned long pc = profile_pc(regs); 323 unsigned long pc;
324
325 if (likely(regs)) {
326 is_kernel = !user_mode(regs);
327 pc = profile_pc(regs);
328 } else {
329 is_kernel = 0; /* This value will not be used */
330 pc = ESCAPE_CODE; /* as this causes an early return. */
331 }
324 332
325 __oprofile_add_ext_sample(pc, regs, event, is_kernel); 333 __oprofile_add_ext_sample(pc, regs, event, is_kernel);
326} 334}