static void unwind_dump(struct unwind_state *state, unsigned long *sp) { static bool dumped_before = false; bool prev_zero, zero = false; unsigned long word; if (dumped_before) return; dumped_before = true; printk_deferred("unwind stack type:%d next_sp:%p mask:%lx graph_idx:%d\n", state->stack_info.type, state->stack_info.next_sp, state->stack_mask, state->graph_idx); for (sp = state->orig_sp; sp < state->stack_info.end; sp++) { word = READ_ONCE_NOCHECK(*sp); prev_zero = zero; zero = word == 0; if (zero) { if (!prev_zero) printk_deferred("%p: %016x ...\n", sp, 0); continue; } printk_deferred("%p: %016lx (%pB)\n", sp, word, (void *)word); } }
static void ShowStatus (void) { struct task_struct * task ; for_each_process(task) { printk_deferred("[Hang_Detect] %s found:%d.,RT[%lld]\n", task->comm, task->pid, sched_clock()); show_stack(task,NULL) ; } }
static void unwind_dump(struct unwind_state *state) { static bool dumped_before = false; bool prev_zero, zero = false; unsigned long word, *sp; struct stack_info stack_info = {0}; unsigned long visit_mask = 0; if (dumped_before) return; dumped_before = true; printk_deferred("unwind stack type:%d next_sp:%p mask:0x%lx graph_idx:%d\n", state->stack_info.type, state->stack_info.next_sp, state->stack_mask, state->graph_idx); for (sp = state->orig_sp; sp; sp = PTR_ALIGN(stack_info.next_sp, sizeof(long))) { if (get_stack_info(sp, state->task, &stack_info, &visit_mask)) break; for (; sp < stack_info.end; sp++) { word = READ_ONCE_NOCHECK(*sp); prev_zero = zero; zero = word == 0; if (zero) { if (!prev_zero) printk_deferred("%p: %0*x ...\n", sp, BITS_PER_LONG/4, 0); continue; } printk_deferred("%p: %0*lx (%pB)\n", sp, BITS_PER_LONG/4, word, (void *)word); } } }
int aee_kernel_wdt_kick_api(int kinterval) { int ret=0; #ifdef CONFIG_MTK_AEE_POWERKEY_HANG_DETECT if(pwk_start_monitor &&(get_boot_mode()==NORMAL_BOOT)&&(FindTaskByName("system_server")!=-1) ) { //Only in normal_boot! printk_deferred("Press powerkey!! g_boot_mode=%d,wdt_kick_status=0x%x,tickTimes=0x%x,g_kinterval=%d,RT[%lld]\n",get_boot_mode(),wdt_kick_status,hwt_kick_times,kinterval,sched_clock()); hwt_kick_times++; if((kinterval*hwt_kick_times > 180))//only monitor 3 min { pwk_start_monitor=0; //check all modules is ok~~~ if( (wdt_kick_status& (WDT_SETBY_Display|WDT_SETBY_SF))!= (WDT_SETBY_Display|WDT_SETBY_SF)) { #ifdef CONFIG_MT_ENG_BUILD ShowStatus() ;//catch task kernel bt printk_deferred("[WDK] Powerkey Tick fail,kick_status 0x%08x,RT[%lld]\n ", wdt_kick_status,sched_clock()); aee_kernel_warning("\nCR_DISPATCH_KEY:UI Hang(Powerkey)\n", "Powerkey Monitor"); #else ShowStatus() ;//catch task kernel bt printk_deferred("[WDK] Powerkey Tick fail,kick_status 0x%08x,RT[%lld]\n ", wdt_kick_status,sched_clock()); ret=WDT_PWK_HANG_FORCE_HWT; //trigger HWT #endif } } if( (wdt_kick_status& (WDT_SETBY_Display|WDT_SETBY_SF))== (WDT_SETBY_Display|WDT_SETBY_SF)) { pwk_start_monitor=0; printk_deferred("[WDK] Powerkey Tick ok,kick_status 0x%08x,RT[%lld]\n ", wdt_kick_status,sched_clock()); } } #endif return ret; }
void psi_task_change(struct task_struct *task, int clear, int set) { int cpu = task_cpu(task); struct psi_group *group; bool wake_clock = true; void *iter = NULL; if (!task->pid) return; if (((task->psi_flags & set) || (task->psi_flags & clear) != clear) && !psi_bug) { printk_deferred(KERN_ERR "psi: inconsistent task state! task=%d:%s cpu=%d psi_flags=%x clear=%x set=%x\n", task->pid, task->comm, cpu, task->psi_flags, clear, set); psi_bug = 1; } task->psi_flags &= ~clear; task->psi_flags |= set; /* * Periodic aggregation shuts off if there is a period of no * task changes, so we wake it back up if necessary. However, * don't do this if the task change is the aggregation worker * itself going to sleep, or we'll ping-pong forever. */ if (unlikely((clear & TSK_RUNNING) && (task->flags & PF_WQ_WORKER) && wq_worker_last_func(task) == psi_update_work)) wake_clock = false; while ((group = iterate_groups(task, &iter))) { psi_group_change(group, cpu, clear, set); if (wake_clock && !delayed_work_pending(&group->clock_work)) schedule_delayed_work(&group->clock_work, PSI_FREQ); } }
static void psi_group_change(struct psi_group *group, int cpu, unsigned int clear, unsigned int set) { struct psi_group_cpu *groupc; unsigned int t, m; groupc = per_cpu_ptr(group->pcpu, cpu); /* * First we assess the aggregate resource states this CPU's * tasks have been in since the last change, and account any * SOME and FULL time these may have resulted in. * * Then we update the task counts according to the state * change requested through the @clear and @set bits. */ write_seqcount_begin(&groupc->seq); record_times(groupc, cpu, false); for (t = 0, m = clear; m; m &= ~(1 << t), t++) { if (!(m & (1 << t))) continue; if (groupc->tasks[t] == 0 && !psi_bug) { printk_deferred(KERN_ERR "psi: task underflow! cpu=%d t=%d tasks=[%u %u %u] clear=%x set=%x\n", cpu, t, groupc->tasks[0], groupc->tasks[1], groupc->tasks[2], clear, set); psi_bug = 1; } groupc->tasks[t]--; } for (t = 0; set; set &= ~(1 << t), t++) if (set & (1 << t)) groupc->tasks[t]++; write_seqcount_end(&groupc->seq); }
static int kwdt_thread(void *arg) { struct sched_param param = {.sched_priority = RTPM_PRIO_WDT }; struct rtc_time tm; struct timeval tv = { 0 }; /* android time */ struct rtc_time tm_android; struct timeval tv_android = { 0 }; int cpu = 0; int local_bit = 0, loc_need_config = 0, loc_timeout = 0; struct wd_api *loc_wk_wdt = NULL; sched_setscheduler(current, SCHED_FIFO, ¶m); set_current_state(TASK_INTERRUPTIBLE); for (;;) { if (kthread_should_stop()) break; spin_lock(&lock); cpu = smp_processor_id(); loc_wk_wdt = g_wd_api; loc_need_config = g_need_config; loc_timeout = g_timeout; spin_unlock(&lock); /* printk("fwq loc_wk_wdt(%x),loc_wk_wdt->ready(%d)\n",loc_wk_wdt ,loc_wk_wdt->ready); */ if (loc_wk_wdt && loc_wk_wdt->ready && g_enable) { if (loc_need_config) { /* daul mode */ loc_wk_wdt->wd_config(WDT_DUAL_MODE, loc_timeout); spin_lock(&lock); g_need_config = 0; spin_unlock(&lock); } /* printk("[WDK] cpu-task=%d, current_pid=%d\n", wk_tsk[cpu]->pid, current->pid); */ if (wk_tsk[cpu]->pid == current->pid) { /* only process WDT info if thread-x is on cpu-x */ spin_lock(&lock); local_bit = kick_bit; printk_deferred("[WDK], local_bit:0x%x, cpu:%d,RT[%lld]\n", local_bit, cpu, sched_clock()); if ((local_bit & (1 << cpu)) == 0) { /* printk("[WDK]: set WDT kick_bit\n"); */ local_bit |= (1 << cpu); /* aee_rr_rec_wdk_kick_jiffies(jiffies); */ } printk_deferred("[WDK], local_bit:0x%x, cpu:%d, check bit0x:%x,RT[%lld]\n", local_bit, cpu, wk_check_kick_bit(), sched_clock()); if (local_bit == wk_check_kick_bit()) { printk_deferred("[WDK]: kick Ex WDT,RT[%lld]\n", sched_clock()); mtk_wdt_restart(WD_TYPE_NORMAL); /* for KICK external wdt */ local_bit = 0; } kick_bit = local_bit; spin_unlock(&lock); #ifdef CONFIG_LOCAL_WDT printk_deferred("[WDK]: cpu:%d, kick local wdt,RT[%lld]\n", cpu, sched_clock()); /* kick local wdt */ mpcore_wdt_restart(WD_TYPE_NORMAL); #endif } } else if (0 == g_enable) { printk("WDK stop to kick\n"); } else { errmsg("No watch dog driver is hooked\n"); BUG(); } if (wk_tsk[cpu]->pid == current->pid) { #if (DEBUG_WDK == 1) msleep(debug_sleep * 1000); dbgmsg("WD kicker woke up %d\n", debug_sleep); #endif do_gettimeofday(&tv); tv_android = tv; rtc_time_to_tm(tv.tv_sec, &tm); tv_android.tv_sec -= sys_tz.tz_minuteswest * 60; rtc_time_to_tm(tv_android.tv_sec, &tm_android); printk_deferred("[thread:%d][RT:%lld] %d-%02d-%02d %02d:%02d:%02d.%u UTC; android time %d-%02d-%02d %02d:%02d:%02d.%03d\n", current->pid, sched_clock(), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, (unsigned int)tv.tv_usec, tm_android.tm_year + 1900, tm_android.tm_mon + 1, tm_android.tm_mday, tm_android.tm_hour, tm_android.tm_min, tm_android.tm_sec, (unsigned int)tv_android.tv_usec); } msleep((g_kinterval) * 1000); #ifdef CONFIG_MTK_AEE_POWERKEY_HANG_DETECT if ((cpu == 0) && (wk_tsk[cpu]->pid == current->pid)) /* only effect at cpu0 */ { if (aee_kernel_wdt_kick_api(g_kinterval) == WDT_PWK_HANG_FORCE_HWT) { printk_deferred("power key trigger HWT\n"); cpus_kick_bit = 0xFFFF; /* Try to force to HWT */ } } #endif } printk("[WDK] WDT kicker thread stop, cpu:%d, pid:%d\n", cpu, current->pid); return 0; }