From 77f717588ab00bfe0f372bf93b89f4dbdedfd713 Mon Sep 17 00:00:00 2001 From: Gopi Krishna Nedanuri <gnedanur@codeaurora.org> Date: Tue, 18 Jul 2017 16:20:46 +0530 Subject: [PATCH] lrdp_v2: Print more info related to NS Watchdog Print more info needed to analyze NS watchdog issues without loading ramdump. Change-Id: I3dd2624d6edf2cf639652cf6f06881b2fe0bebc0 --- linux-ramdump-parser-v2/watchdog_v2.py | 80 ++++++++++++++++++++++---- 1 file changed, 70 insertions(+), 10 deletions(-) mode change 100755 => 100644 linux-ramdump-parser-v2/watchdog_v2.py diff --git a/linux-ramdump-parser-v2/watchdog_v2.py b/linux-ramdump-parser-v2/watchdog_v2.py old mode 100755 new mode 100644 index 68dbdab..409eec6 --- a/linux-ramdump-parser-v2/watchdog_v2.py +++ b/linux-ramdump-parser-v2/watchdog_v2.py @@ -831,7 +831,12 @@ class Watchdog(RamParser): get_wdog_timing(self.ramdump) +def ns_to_sec(ns): + return ns/1000000000.0 + + def get_wdog_timing(ramdump): + logical_map = [] jiffies = ramdump.read_word('jiffies') last_jiffies_update = ramdump.read_word('last_jiffies_update') tick_do_timer_cpu = ramdump.read_word('tick_do_timer_cpu') @@ -841,8 +846,8 @@ def get_wdog_timing(ramdump): timer_expires_off = ramdump.field_offset('struct timer_list', 'expires') pet_timer_expires = ramdump.read_word( wdog_data_addr + pet_timer_off + timer_expires_off) - last_pet_off = ramdump.field_offset('struct msm_watchdog_data', 'last_pet') - wdog_last_pet = ramdump.read_word(wdog_data_addr + last_pet_off) + wdog_last_pet = ramdump.read_structure_field( + wdog_data_addr, 'struct msm_watchdog_data', 'last_pet') timer_expired_off = ramdump.field_offset( 'struct msm_watchdog_data', 'timer_expired') pet_timer_expired = ramdump.read_word(wdog_data_addr + timer_expired_off) @@ -851,23 +856,78 @@ def get_wdog_timing(ramdump): 'struct msm_watchdog_data', 'bark_time') pet_time = ramdump.read_int(wdog_data_addr + pet_time_off) bark_time = ramdump.read_int(wdog_data_addr + bark_time_off) + wdog_alive_mask = ramdump.read_structure_field( + wdog_data_addr, 'struct msm_watchdog_data', 'alive_mask.bits') + cpu_online_bits = ramdump.read_word('cpu_online_bits') + wdog_task = ramdump.read_structure_field( + wdog_data_addr, 'struct msm_watchdog_data', 'watchdog_task') + wdog_task_state = ramdump.read_structure_field( + wdog_task, 'struct task_struct', 'state') + wdog_task_threadinfo = ramdump.read_structure_field( + wdog_task, 'struct task_struct', 'stack') + wdog_task_oncpu = ramdump.read_structure_field( + wdog_task, 'struct task_struct', 'on_cpu') + wdog_task_cpu = ramdump.read_structure_field( + wdog_task_threadinfo, 'struct thread_info', 'cpu') + wdog_task_arrived = ramdump.read_structure_field( + wdog_task, 'struct task_struct', 'sched_info.last_arrival') + wdog_task_queued = ramdump.read_structure_field( + wdog_task, 'struct task_struct', 'sched_info.last_queued') + logical_map_addr = ramdump.address_of('__cpu_logical_map') + +# Assuming number of cores per cluster as 4 in case of multicluster. +# New targets has only one cluster. So this will work for both. + for i in range(0, ramdump.get_num_cpus()): + cpu_logical_map_addr = logical_map_addr + (i * 8) + core_id = ramdump.read_u64(cpu_logical_map_addr) + phys_core = (core_id & 0x00FF) + ((core_id >> 8) * 4) + logical_map.append(phys_core) + print_out_str('Non-secure Watchdog data') - print_out_str('Pet time: {0}s'.format(pet_time/1000.0)) - print_out_str('Bark time: {0}s'.format(bark_time/1000.0)) - print_out_str('Watchdog last pet: {0}'.format(wdog_last_pet/1000000000.0)) - if pet_timer_expired == 1: - print_out_str('Watchdog pet timer expired') + print_out_str('Pet time: {0}s'.format(pet_time / 1000.0)) + print_out_str('Bark time: {0}s'.format(bark_time / 1000.0)) + if wdog_last_pet > 1000000000: + last_pet_sec = ns_to_sec(wdog_last_pet) + print_out_str('Watchdog last pet: {0:.9f}'.format(last_pet_sec)) + else: + print_out_str('Watchdog last pet: {0:.3f}'.format(wdog_last_pet)) + + if wdog_task_state == 0 and wdog_task_oncpu == 1: + print_out_str("Watchdog task running on core {0} from {1:.6f}".format( + wdog_task_cpu, ns_to_sec(wdog_task_arrived))) + print_out_str("CPUs responded to pet(alive_mask): {0:08b}".format( + wdog_alive_mask)) + alive_cpus = wdog_alive_mask | (~cpu_online_bits) + for i in range(0, ramdump.get_num_cpus()): + if (alive_cpus & 1): + alive_cpus = alive_cpus >> 1 + else: + print_out_str("CPU which didn't respond to pet: {0}".format(i)) + break + + elif wdog_task_state == 0: + print_out_str( + "Watchdog task is waiting on core {0} from {1:.6f}".format( + wdog_task_cpu, ns_to_sec(wdog_task_queued))) + + elif wdog_task_state == 1 and pet_timer_expired == 1: + print_out_str("Pet timer expired but Watchdog task is not queued") + else: print_out_str('Watchdog pet timer not expired') if jiffies > pet_timer_expires: print_out_str('Current jiffies crossed pet_timer expires jiffies') + + print_out_str('CPU online bits: {0:b}'.format(cpu_online_bits)) print_out_str('pet_timer_expires: {0}'.format(pet_timer_expires)) print_out_str('Current jiffies : {0}'.format(jiffies)) print_out_str( 'Timestamp of last timer interrupt(last_jiffies_update): {0}'.format( - last_jiffies_update/1000000000.0)) - print_out_str('Core which updates jiffies(tick_do_timer_cpu): {0}'.format( - tick_do_timer_cpu)) + ns_to_sec(last_jiffies_update))) + print_out_str("tick_do_timer_cpu: {0}".format(tick_do_timer_cpu)) + print_out_str('tick_do_timer_cpu is core which increments jiffies and ' + 'processes watchdog pet timer') + print_out_str('CPU logical map: {0}'.format(logical_map)) epoch_ns = ramdump.read_word('cd.read_data[0].epoch_ns') epoch_cyc = ramdump.read_word('cd.read_data[0].epoch_cyc') print_out_str('epoch_ns: {0}ns epoch_cyc: {1}'.format(epoch_ns,epoch_cyc)) -- GitLab