When tracing with tracepoints events the IP and CPSR are set to 0,
preventing the perf code to resolve the symbols:
./perf record -e kmem:kmalloc cal
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.007 MB perf.data (~321 samples) ]
./perf report
Overhead Command Shared Object Symbol
........ ....... ............. ...........
40.78% cal [unknown] [.]00000000
31.6% cal [unknown] [.]00000000
The examination of the gathered samples (perf report -D) shows the IP
is set to 0 and that the samples are considered as user space samples,
while the IP should be set from the registers and the samples should be
considered as kernel samples.
The fix is to implement perf_arch_fetch_caller_regs for ARM, which
fills the necessary registers used for the callchain unwinding and
to determine the user/kernel space property of the samples: ip, sp, fp
and cpsr.
Tested with perf record and tracepoints filtering (-e <tracepoint>), with
unwinding using fp (--call-graph fp) and dwarf info (--call-graph dwarf).
Reported by Sneha Priya on linaro-dev, cf.
http://lists.linaro.org/pipermail/linaro-dev/2014-May/017151.html
Signed-off-by: Jean Pihet <jean.pihet(a)linaro.org>
Cc: Will Deacon <will.deacon(a)arm.com>
Reported-by: Sneha Priya <sneha.cse(a)hotmail.com>
---
arch/arm/include/asm/perf_event.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index 7558775..5e31d46 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -26,6 +26,25 @@ struct pt_regs;
extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
extern unsigned long perf_misc_flags(struct pt_regs *regs);
#define perf_misc_flags(regs) perf_misc_flags(regs)
+
+/*
+ * Take a snapshot of the regs.
+ * We only need a few of the regs:
+ * - ip for PERF_SAMPLE_IP
+ * - sp, fp for callchains
+ * - cpsr for user_mode() tests
+ */
+#define perf_arch_fetch_caller_regs(regs, __ip) { \
+ instruction_pointer(regs)= (__ip); \
+ __asm__ ( \
+ "mov %[_ARM_sp], sp \n\t" \
+ "mov %[_ARM_fp], fp \n\t" \
+ "mrs %[_ARM_cpsr], cpsr \n\t" \
+ : [_ARM_sp] "=r" (regs->ARM_sp), \
+ [_ARM_fp] "=r" (regs->ARM_fp), \
+ [_ARM_cpsr] "=r" (regs->ARM_cpsr) \
+ ); \
+}
#endif
#endif /* __ARM_PERF_EVENT_H__ */
--
1.8.1.2
when lock checking option enabled in kernel config, TC2 catch a deadlock bug
as following,
It looks hmp_idle_pull --> hmp_keepalive_delay --> cpuidle_driver_ref
interrupt into cpuidle_register_driver.
Since what we needs of cpuidle_driver in hmp_keepalive_delay are
exit_latency/target_residency, they should be fixed for this board.
So, could we avoid the cpuidle_driver_ref calling by giving a fixed value?
That also can save a cpuidle_get_cpu_driver?
===============
[ 113.878488] [ INFO: inconsistent lock state ]
[ 113.878493] 3.10.42+ #4 Not tainted
[ 113.878496] ---------------------------------
[ 113.878501] inconsistent
{SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
[ 113.878507] ksoftirqd/4/28 [HC0[0]:SC1[1]:HE1:SE0] takes:
[ 113.878531] (cpuidle_driver_lock){+.?...}, at: [<c035bded>] cpuidle_driver_ref+0x15/0x58
[ 113.878534] {SOFTIRQ-ON-W}
state was registered at:
[ 113.878545] [<c006eedd>] __lock_acquire+0x539/0x8c8
[ 113.878554] [<c006f913>] lock_acquire+0x113/0x164
[ 113.878565] [<c047e24b>] _raw_spin_lock+0x33/0x40
[ 113.878573] [<c035bc73>] cpuidle_register_driver+0x37/0xf4
[ 113.878583] [<c06bab1d>] bl_idle_init+0x85/0x128
[ 113.878592] [<c0008665>] do_one_initcall+0x99/0x11c
[ 113.878603] [<c0695a5f>] kernel_init_freeable+0x10b/0x188
[ 113.878611] [<c046f96d>] kernel_init+0x19/0x108
[ 113.878619] [<c000d4a9>] ret_from_fork+0x11/0x1c
[ 113.878622] irq event stamp: 28
[ 113.878633] hardirqs last enabled at (28): [<c047e48f>] _raw_spin_unlock_irqrestore+0x2f/0x44
[ 113.878642] hardirqs last disabled at (27): [<c047e335>] _raw_spin_lock_irqsave+0x19/0x4c
[ 113.878652] softirqs last enabled at (0): [<c001d658>] copy_process+0x3c4/0xe34
[ 113.878661] softirqs last disabled at (17): [<c002578b>] run_ksoftirqd+0x2f/0x5c
[ 113.878664]
[ 113.878664] other info that might help us debug this:
[ 113.878667] Possible unsafe locking scenario:
[ 113.878667]
[ 113.878670] CPU0
[ 113.878673] ----
[ 113.878681] lock(cpuidle_driver_lock);
[ 113.878684] <Interrupt>
[ 113.878691] lock(cpuidle_driver_lock);
[ 113.878693]
[ 113.878693] *** DEADLOCK ***
[ 113.878693]
[ 113.878697] 1 lock held by ksoftirqd/4/28:
[ 113.878719] #0: (hmp_force_migration){+.....}, at: [<c0054da5>] hmp_idle_pull+0x49/0x508
[ 113.878722]
--
Thanks
Alex
Changelog:
V5:
* Removed patch : "Move clock setup to pm.c"
* Added patch : "Move arm core power down clock to exynos5250 common code"
V4:
* Took into account Tomasz's comments
* Fixed missing call in for central suspend
* Passed parameter to the wakeup mask function
* Moved wakeup mask, boot vector and aftr state into a single
function
* Used this function as callback for platform data
* Moved S5P_CHECK_AFTR/S5P_CHECK_SLEEP into pm.c
* Set boot vector only one time
* Splitted some patches to make them more readable
V3:
* Added patch : "ARM: exynos: cpuidle: Disable cpuidle for 5440"
* Removed patch : "ARM: exynos: config: Enable cpuidle"
* Removed default ARM_EXYNOS4210_CPUIDLE=y
* Added comment about bug fix side effect 'for_each_possible_cpu'
V2:
* Added comment in changelog for calls order (5/17)
* Call the powerdown only for cpu0 in the pm notifier
* Set the pm notifier for all boards
V1: initial post
This patchset relies on the cpm_pm notifier to initiate the powerdown sequence
operations from pm.c instead cpuidle.c. Thus the cpuidle driver is no longer
dependent from arch specific code as everything is called from the pm.c file.
The patchset applies on top of linux-samsung/for-next.
Tested on exynos4: 4210
Tested on exynos5: 5250 (without AFTR)
Amit Daniel Kachhap (1):
ARM: EXYNOS: Move arm core power down clock to exynos5250 common
clock
Daniel Lezcano (19):
ARM: exynos: cpuidle: Prevent forward declaration
ARM: exynos: cpuidle: Use cpuidle_register
ARM: exynos: cpuidle: Change function name prefix
ARM: exynos: cpuidle: Encapsulate register access inside a function
ARM: exynos: cpuidle: Move some code inside the idle_finisher
ARM: exynos: cpuidle: Fix S5P_WAKEUP_STAT call
ARM: exynos: cpuidle: Use the cpu_pm notifier
ARM: exynos: cpuidle: Move scu_enable in the cpu_pm notifier
ARM: exynos: cpuidle: Remove ifdef for scu_enable
ARM: exynos: cpuidle: Pass wakeup mask parameter to function
ARM: exynos: cpuidle: Encapsulate boot vector code into a function
ARM: exynos: cpuidle: Disable cpuidle for 5440
ARM: exynos: cpuidle: Encapsulate the AFTR code into a function
ARM: exynos: cpuidle: Move the AFTR state function into pm.c
ARM: exynos: cpuidle: Move the power sequence call in the cpu_pm
notifier
ARM: exynos: cpuidle: Move S5P_CHECK_SLEEP into pm.c
ARM: exynos: cpuidle: Pass the AFTR callback to the platform_data
ARM: exynos: cpuidle: Cleanup all unneeded headers from cpuidle.c
ARM: exynos: cpuidle: Move the driver to drivers/cpuidle directory
arch/arm/mach-exynos/Makefile | 1 -
arch/arm/mach-exynos/common.h | 1 +
arch/arm/mach-exynos/cpuidle.c | 255 ----------------------------------
arch/arm/mach-exynos/exynos.c | 8 +-
arch/arm/mach-exynos/pm.c | 152 ++++++++++++++++----
arch/arm/mach-exynos/regs-pmu.h | 2 -
drivers/clk/samsung/clk-exynos5250.c | 42 ++++++
drivers/cpuidle/Kconfig.arm | 6 +
drivers/cpuidle/Makefile | 1 +
drivers/cpuidle/cpuidle-exynos.c | 98 +++++++++++++
10 files changed, 277 insertions(+), 289 deletions(-)
delete mode 100644 arch/arm/mach-exynos/cpuidle.c
create mode 100644 drivers/cpuidle/cpuidle-exynos.c
--
1.7.9.5