summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPhil Carmody <ext-phil.2.carmody@nokia.com>2010-04-28 12:09:16 -0500
committerRobert Richter <robert.richter@amd.com>2010-05-03 23:02:39 +0200
commit9414e99672271adcc661f3c160a30b374179b92f (patch)
treeda2052d48666552400b3204f15bb18b58156065f /drivers
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>
Diffstat (limited to 'drivers')
-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,
void oprofile_add_sample(struct pt_regs * const regs, unsigned long event)
{
- int is_kernel = !user_mode(regs);
- unsigned long pc = profile_pc(regs);
+ int is_kernel;
+ unsigned long pc;
+
+ if (likely(regs)) {
+ is_kernel = !user_mode(regs);
+ pc = profile_pc(regs);
+ } else {
+ is_kernel = 0; /* This value will not be used */
+ pc = ESCAPE_CODE; /* as this causes an early return. */
+ }
__oprofile_add_ext_sample(pc, regs, event, is_kernel);
}