/* * Copyright (c) 2020 Samsung Electronics Co., Ltd. * http://www.samsung.com * * Samsung TN debugging code * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #include #include #include #include #include #include #include #include #include #include #include "../../../kernel/sched/sched.h" #include static call_single_data_t csd; static struct task_struct *suspect; static inline char get_state(struct task_struct *p) { char state_array[] = {'R', 'S', 'D', 'T', 't', 'X', 'Z', 'P', 'x', 'K', 'W', 'I', 'N'}; unsigned char idx = 0; unsigned long state; if (!p) return 0; state = (p->state | p->exit_state) & (TASK_STATE_MAX - 1); while (state) { idx++; state >>= 1; } return state_array[idx]; } static void show_callstack(void *dummy) { #ifdef CONFIG_SEC_DEBUG_AUTO_COMMENT show_stack_auto_comment(NULL, NULL); #else show_stack(NULL, NULL); #endif } static struct task_struct *secdbg_softdog_find_key_suspect() { struct task_struct *c, *g; for_each_process(g) { if (g->pid == 1) suspect = g; else if (!strcmp(g->comm, "system_server")) { suspect = g; for_each_thread(g, c) { if (!strcmp(c->comm, "watchdog")) { suspect = c; goto out; } } goto out; } } out: return suspect; } void secdbg_softdog_show_info(void) { struct task_struct *p = NULL; p = secdbg_softdog_find_key_suspect(); if (p) { pr_auto(ASL5, "[SOFTDOG] %s:%d %c(%d) exec:%lluns\n", p->comm, p->pid, get_state(p), (int)p->state, p->se.exec_start); if (task_running(task_rq(p), p)) { csd.flags = 0; csd.func = show_callstack; csd.info = 0; smp_call_function_single_async(task_cpu(p), &csd); } else { #ifdef CONFIG_SEC_DEBUG_AUTO_COMMENT show_stack_auto_comment(p, NULL); #else show_stack(p, NULL); #endif } } else { pr_auto(ASL5, "[SOFTDOG] Init task not exist!\n"); } }