static void sysrq_handle_showmem(int key, struct tty_struct *tty) { struct user_beancounter *ub; rcu_read_lock(); for_each_beancounter(ub) show_ub_mem(ub); rcu_read_unlock(); show_mem(0); show_slab_info(); }
static void dump_header(struct oom_control *oc, struct task_struct *p, struct mem_cgroup *memcg) { pr_warn("%s invoked oom-killer: gfp_mask=%#x(%pGg), order=%d, oom_score_adj=%hd\n", current->comm, oc->gfp_mask, &oc->gfp_mask, oc->order, current->signal->oom_score_adj); cpuset_print_current_mems_allowed(); dump_stack(); if (memcg) mem_cgroup_print_oom_info(memcg, p); else show_mem(SHOW_MEM_FILTER_NODES); if (sysctl_oom_dump_tasks) dump_tasks(memcg, oc->nodemask); }
static void panic_print_sys_info(void) { if (panic_print & PANIC_PRINT_TASK_INFO) show_state(); if (panic_print & PANIC_PRINT_MEM_INFO) show_mem(0, NULL); if (panic_print & PANIC_PRINT_TIMER_INFO) sysrq_timer_list_show(); if (panic_print & PANIC_PRINT_LOCK_INFO) debug_show_all_locks(); if (panic_print & PANIC_PRINT_FTRACE_INFO) ftrace_dump(DUMP_ALL); }
static void dump_header(struct oom_control *oc, struct task_struct *p) { pr_warn("%s invoked oom-killer: gfp_mask=%#x(%pGg), order=%d, oom_score_adj=%hd\n", current->comm, oc->gfp_mask, &oc->gfp_mask, oc->order, current->signal->oom_score_adj); if (!IS_ENABLED(CONFIG_COMPACTION) && oc->order) pr_warn("COMPACTION is disabled!!!\n"); dump_stack(); if (is_memcg_oom(oc)) mem_cgroup_print_oom_meminfo(oc->memcg); else { show_mem(SHOW_MEM_FILTER_NODES, oc->nodemask); if (is_dump_unreclaim_slabs()) dump_unreclaimable_slab(); } if (sysctl_oom_dump_tasks) dump_tasks(oc->memcg, oc->nodemask); if (p) dump_oom_summary(oc, p); }
static asmlinkage void netpoll_netdump(struct pt_regs *regs, void *platform_arg) { reply_t reply; char *tmp = command_tmp; extern unsigned long totalram_pages; struct pt_regs myregs; req_t *req; /* * Just in case we are crashing within the networking code * ... attempt to fix up. */ netpoll_reset_locks(&np); platform_fix_regs(); platform_timestamp(t0); netpoll_set_trap(1); /* bypass networking stack */ local_irq_disable(); local_bh_disable(); printk("< netdump activated - performing handshake with the server. >\n"); netdump_startup_handshake(&np); printk("< handshake completed - listening for dump requests. >\n"); while (netdump_mode) { Dprintk("main netdump loop: polling controller ...\n"); netpoll_poll(&np); req = get_new_req(); if (!req) continue; Dprintk("got new req, command %d.\n", req->command); print_status(req); switch (req->command) { case COMM_NONE: Dprintk("got NO command.\n"); break; case COMM_SEND_MEM: Dprintk("got MEM command.\n"); send_netdump_mem(&np, req); break; case COMM_EXIT: Dprintk("got EXIT command.\n"); netdump_mode = 0; netpoll_set_trap(0); break; case COMM_REBOOT: Dprintk("got REBOOT command.\n"); printk("netdump: rebooting in 3 seconds.\n"); netdump_mdelay(3000); machine_restart(NULL); break; case COMM_HELLO: sprintf(tmp, "Hello, this is netdump version 0.%02d\n", NETDUMP_VERSION); reply.code = REPLY_HELLO; reply.nr = req->nr; reply.info = NETDUMP_VERSION; send_netdump_msg(&np, tmp, strlen(tmp), &reply); break; case COMM_GET_PAGE_SIZE: sprintf(tmp, "PAGE_SIZE: %ld\n", PAGE_SIZE); reply.code = REPLY_PAGE_SIZE; reply.nr = req->nr; reply.info = PAGE_SIZE; send_netdump_msg(&np, tmp, strlen(tmp), &reply); break; case COMM_GET_REGS: reply.code = REPLY_REGS; reply.nr = req->nr; reply.info = (u32)totalram_pages; send_netdump_msg(&np, tmp, platform_get_regs(tmp, &myregs), &reply); break; case COMM_GET_NR_PAGES: reply.code = REPLY_NR_PAGES; reply.nr = req->nr; reply.info = platform_max_pfn(); sprintf(tmp, "Number of pages: %ld\n", platform_max_pfn()); send_netdump_msg(&np, tmp, strlen(tmp), &reply); break; case COMM_SHOW_STATE: /* send response first */ reply.code = REPLY_SHOW_STATE; reply.nr = req->nr; reply.info = 0; netdump_mode = 0; if (regs) show_regs(regs); show_state(); show_mem(); netdump_mode = 1; send_netdump_msg(&np, tmp, strlen(tmp), &reply); break; default: reply.code = REPLY_ERROR; reply.nr = req->nr; reply.info = req->command; Dprintk("got UNKNOWN command!\n"); sprintf(tmp, "Got unknown command code %d!\n", req->command); send_netdump_msg(&np, tmp, strlen(tmp), &reply); break; } kfree(req); req = NULL; } sprintf(tmp, "NETDUMP end.\n"); reply.code = REPLY_END_NETDUMP; reply.nr = 0; reply.info = 0; send_netdump_msg(&np, tmp, strlen(tmp), &reply); printk("NETDUMP END!\n"); }
static int android_oom_handler(struct notifier_block *nb, unsigned long val, void *data) { struct task_struct *tsk; #ifdef MULTIPLE_OOM_KILLER struct task_struct *selected[OOM_DEPTH] = {NULL,}; #else struct task_struct *selected = NULL; #endif int rem = 0; int tasksize; int i; int min_score_adj = OOM_SCORE_ADJ_MAX + 1; #ifdef MULTIPLE_OOM_KILLER int selected_tasksize[OOM_DEPTH] = {0,}; int selected_oom_score_adj[OOM_DEPTH] = {OOM_ADJUST_MAX,}; int all_selected_oom = 0; int max_selected_oom_idx = 0; #else int selected_tasksize = 0; int selected_oom_score_adj; #endif #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL/5, 1); #endif unsigned long *freed = data; #if defined(CONFIG_CMA_PAGE_COUNTING) unsigned long nr_cma_free; unsigned long nr_cma_inactive_file; unsigned long nr_cma_active_file; int other_free; int other_file; nr_cma_free = global_page_state(NR_FREE_CMA_PAGES); other_free = global_page_state(NR_FREE_PAGES) - nr_cma_free; nr_cma_inactive_file = global_page_state(NR_CMA_INACTIVE_FILE); nr_cma_active_file = global_page_state(NR_CMA_ACTIVE_FILE); other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM) - total_swapcache_pages - nr_cma_inactive_file - nr_cma_active_file; #endif /* show status */ pr_warning("%s invoked Android-oom-killer: " "oom_adj=%d, oom_score_adj=%d\n", current->comm, current->signal->oom_adj, current->signal->oom_score_adj); #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO if (__ratelimit(&oom_rs)) { dump_stack(); show_mem(SHOW_MEM_FILTER_NODES); dump_tasks_info(); } #endif min_score_adj = 0; #ifdef MULTIPLE_OOM_KILLER for (i = 0; i < OOM_DEPTH; i++) selected_oom_score_adj[i] = min_score_adj; #else selected_oom_score_adj = min_score_adj; #endif read_lock(&tasklist_lock); for_each_process(tsk) { struct task_struct *p; int oom_score_adj; #ifdef MULTIPLE_OOM_KILLER int is_exist_oom_task = 0; #endif if (tsk->flags & PF_KTHREAD) continue; p = find_lock_task_mm(tsk); if (!p) continue; oom_score_adj = p->signal->oom_score_adj; if (oom_score_adj < min_score_adj) { task_unlock(p); continue; } tasksize = get_mm_rss(p->mm); task_unlock(p); if (tasksize <= 0) continue; lowmem_print(2, "oom: ------ %d (%s), adj %d, size %d\n", p->pid, p->comm, oom_score_adj, tasksize); #ifdef MULTIPLE_OOM_KILLER if (all_selected_oom < OOM_DEPTH) { for (i = 0; i < OOM_DEPTH; i++) { if (!selected[i]) { is_exist_oom_task = 1; max_selected_oom_idx = i; break; } } } else if (selected_oom_score_adj[max_selected_oom_idx] < oom_score_adj || (selected_oom_score_adj[max_selected_oom_idx] == oom_score_adj && selected_tasksize[max_selected_oom_idx] < tasksize)) { is_exist_oom_task = 1; } if (is_exist_oom_task) { selected[max_selected_oom_idx] = p; selected_tasksize[max_selected_oom_idx] = tasksize; selected_oom_score_adj[max_selected_oom_idx] = oom_score_adj; if (all_selected_oom < OOM_DEPTH) all_selected_oom++; if (all_selected_oom == OOM_DEPTH) { for (i = 0; i < OOM_DEPTH; i++) { if (selected_oom_score_adj[i] < selected_oom_score_adj[max_selected_oom_idx]) max_selected_oom_idx = i; else if (selected_oom_score_adj[i] == selected_oom_score_adj[max_selected_oom_idx] && selected_tasksize[i] < selected_tasksize[max_selected_oom_idx]) max_selected_oom_idx = i; } } lowmem_print(2, "oom: max_selected_oom_idx(%d) select %d (%s), adj %d, \ size %d, to kill\n", max_selected_oom_idx, p->pid, p->comm, oom_score_adj, tasksize); } #else if (selected) { if (oom_score_adj < selected_oom_score_adj) continue; if (oom_score_adj == selected_oom_score_adj && tasksize <= selected_tasksize) continue; } selected = p; selected_tasksize = tasksize; selected_oom_score_adj = oom_score_adj; lowmem_print(2, "oom: select %d (%s), adj %d, size %d, to kill\n", p->pid, p->comm, oom_score_adj, tasksize); #endif } #ifdef MULTIPLE_OOM_KILLER for (i = 0; i < OOM_DEPTH; i++) { if (selected[i]) { #if defined(CONFIG_CMA_PAGE_COUNTING) lowmem_print(1, "oom: send sigkill to %d (%s), adj %d, " "size %d ofree %d ofile %d " "cma_free %lu cma_i_file %lu cma_a_file %lu\n", selected[i]->pid, selected[i]->comm, selected_oom_score_adj[i], selected_tasksize[i], other_free, other_file, nr_cma_free, nr_cma_inactive_file, nr_cma_active_file); #else lowmem_print(1, "oom: send sigkill to %d (%s), adj %d,\ size %d\n", selected[i]->pid, selected[i]->comm, selected_oom_score_adj[i], selected_tasksize[i]); #endif send_sig(SIGKILL, selected[i], 0); rem -= selected_tasksize[i]; *freed += (unsigned long)selected_tasksize[i]; #ifdef OOM_COUNT_READ oom_count++; #endif } } #else if (selected) { lowmem_print(1, "oom: send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected_oom_score_adj, selected_tasksize); send_sig(SIGKILL, selected, 0); set_tsk_thread_flag(selected, TIF_MEMDIE); rem -= selected_tasksize; *freed += (unsigned long)selected_tasksize; #ifdef OOM_COUNT_READ oom_count++; #endif } #endif read_unlock(&tasklist_lock); lowmem_print(2, "oom: get memory %lu", *freed); return rem; }
static int android_oom_handler(struct notifier_block *nb, unsigned long val, void *data) { struct task_struct *tsk; #ifdef MULTIPLE_OOM_KILLER struct task_struct *selected[OOM_DEPTH] = {NULL,}; #else struct task_struct *selected = NULL; #endif int rem = 0; int tasksize; int i; int min_score_adj = OOM_SCORE_ADJ_MAX + 1; #ifdef MULTIPLE_OOM_KILLER int selected_tasksize[OOM_DEPTH] = {0,}; int selected_oom_score_adj[OOM_DEPTH] = {OOM_ADJUST_MAX,}; int all_selected_oom = 0; int max_selected_oom_idx = 0; #else int selected_tasksize = 0; int selected_oom_score_adj; #endif static DEFINE_RATELIMIT_STATE(oom_rs, DEFAULT_RATELIMIT_INTERVAL/5, 1); unsigned long *freed = data; /* show status */ pr_warning("%s invoked Android-oom-killer: " "oom_adj=%d, oom_score_adj=%d\n", current->comm, current->signal->oom_adj, current->signal->oom_score_adj); dump_stack(); show_mem(SHOW_MEM_FILTER_NODES); if (__ratelimit(&oom_rs)) dump_tasks_info(); min_score_adj = 0; #ifdef MULTIPLE_OOM_KILLER for (i = 0; i < OOM_DEPTH; i++) selected_oom_score_adj[i] = min_score_adj; #else selected_oom_score_adj = min_score_adj; #endif #ifdef CONFIG_ZRAM_FOR_ANDROID atomic_set(&s_reclaim.lmk_running, 1); #endif read_lock(&tasklist_lock); for_each_process(tsk) { struct task_struct *p; int oom_score_adj; #ifdef MULTIPLE_OOM_KILLER int is_exist_oom_task = 0; #endif if (tsk->flags & PF_KTHREAD) continue; p = find_lock_task_mm(tsk); if (!p) continue; oom_score_adj = p->signal->oom_score_adj; if (oom_score_adj < min_score_adj) { task_unlock(p); continue; } tasksize = get_mm_rss(p->mm); task_unlock(p); if (tasksize <= 0) continue; lowmem_print(2, "oom: ------ %d (%s), adj %d, size %d\n", p->pid, p->comm, oom_score_adj, tasksize); #ifdef MULTIPLE_OOM_KILLER if (all_selected_oom < OOM_DEPTH) { for (i = 0; i < OOM_DEPTH; i++) { if (!selected[i]) { is_exist_oom_task = 1; max_selected_oom_idx = i; break; } } } else if (selected_oom_score_adj[max_selected_oom_idx] < oom_score_adj || (selected_oom_score_adj[max_selected_oom_idx] == oom_score_adj && selected_tasksize[max_selected_oom_idx] < tasksize)) { is_exist_oom_task = 1; } if (is_exist_oom_task) { selected[max_selected_oom_idx] = p; selected_tasksize[max_selected_oom_idx] = tasksize; selected_oom_score_adj[max_selected_oom_idx] = oom_score_adj; if (all_selected_oom < OOM_DEPTH) all_selected_oom++; if (all_selected_oom == OOM_DEPTH) { for (i = 0; i < OOM_DEPTH; i++) { if (selected_oom_score_adj[i] < selected_oom_score_adj[max_selected_oom_idx]) max_selected_oom_idx = i; else if (selected_oom_score_adj[i] == selected_oom_score_adj[max_selected_oom_idx] && selected_tasksize[i] < selected_tasksize[max_selected_oom_idx]) max_selected_oom_idx = i; } } lowmem_print(2, "oom: max_selected_oom_idx(%d) select %d (%s), adj %d, \ size %d, to kill\n", max_selected_oom_idx, p->pid, p->comm, oom_score_adj, tasksize); } #else if (selected) { if (oom_score_adj < selected_oom_score_adj) continue; if (oom_score_adj == selected_oom_score_adj && tasksize <= selected_tasksize) continue; } selected = p; selected_tasksize = tasksize; selected_oom_score_adj = oom_score_adj; lowmem_print(2, "oom: select %d (%s), adj %d, size %d, to kill\n", p->pid, p->comm, oom_score_adj, tasksize); #endif } #ifdef MULTIPLE_OOM_KILLER for (i = 0; i < OOM_DEPTH; i++) { if (selected[i]) { lowmem_print(1, "oom: send sigkill to %d (%s), adj %d,\ size %d\n", selected[i]->pid, selected[i]->comm, selected_oom_score_adj[i], selected_tasksize[i]); send_sig(SIGKILL, selected[i], 0); rem -= selected_tasksize[i]; *freed += (unsigned long)selected_tasksize[i]; #ifdef OOM_COUNT_READ oom_count++; #endif } } #else if (selected) { lowmem_print(1, "oom: send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected_oom_score_adj, selected_tasksize); send_sig(SIGKILL, selected, 0); set_tsk_thread_flag(selected, TIF_MEMDIE); rem -= selected_tasksize; *freed += (unsigned long)selected_tasksize; #ifdef OOM_COUNT_READ oom_count++; #endif } #endif read_unlock(&tasklist_lock); #ifdef CONFIG_ZRAM_FOR_ANDROID atomic_set(&s_reclaim.lmk_running, 0); #endif lowmem_print(2, "oom: get memory %lu", *freed); return rem; }
static void sysrq_handle_showmem(int key) { show_mem(0); }
void handle_sysrq(int key, struct pt_regs *pt_regs, struct kbd_struct *kbd, struct tty_struct *tty) { int orig_log_level = console_loglevel; if (!key) return; console_loglevel = 7; printk(KERN_INFO "SysRq: "); switch (key) { case 'r': /* R -- Reset raw mode */ if (kbd) { kbd->kbdmode = VC_XLATE; printk("Keyboard mode set to XLATE\n"); } break; #ifdef CONFIG_VT case 'k': /* K -- SAK */ printk("SAK\n"); if (tty) do_SAK(tty); reset_vc(fg_console); break; #endif case 'b': /* B -- boot immediately */ printk("Resetting\n"); machine_restart(NULL); break; case 'o': /* O -- power off */ if (sysrq_power_off) { printk("Power off\n"); sysrq_power_off(); } break; case 's': /* S -- emergency sync */ printk("Emergency Sync\n"); emergency_sync_scheduled = EMERG_SYNC; wakeup_bdflush(0); break; case 'u': /* U -- emergency remount R/O */ printk("Emergency Remount R/O\n"); emergency_sync_scheduled = EMERG_REMOUNT; wakeup_bdflush(0); break; case 'p': /* P -- show PC */ printk("Show Regs\n"); if (pt_regs) show_regs(pt_regs); break; case 't': /* T -- show task info */ printk("Show State\n"); show_state(); break; case 'm': /* M -- show memory info */ printk("Show Memory\n"); show_mem(); break; case '0' ... '9': /* 0-9 -- set console logging level */ orig_log_level = key - '0'; printk("Log level set to %d\n", orig_log_level); break; case 'e': /* E -- terminate all user processes */ printk("Terminate All Tasks\n"); send_sig_all(SIGTERM, 0); orig_log_level = 8; /* We probably have killed syslogd */ break; case 'i': /* I -- kill all user processes */ printk("Kill All Tasks\n"); send_sig_all(SIGKILL, 0); orig_log_level = 8; break; case 'l': /* L -- kill all processes including init */ printk("Kill ALL Tasks (even init)\n"); send_sig_all(SIGKILL, 1); orig_log_level = 8; break; default: /* Unknown: help */ if (kbd) printk("unRaw "); #ifdef CONFIG_VT if (tty) printk("saK "); #endif printk("Boot "); if (sysrq_power_off) printk("Off "); printk("Sync Unmount showPc showTasks showMem loglevel0-8 tErm kIll killalL\n"); /* Don't use 'A' as it's handled specially on the Sparc */ } console_loglevel = orig_log_level; }
static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { struct task_struct *tsk; #ifdef ENHANCED_LMK_ROUTINE struct task_struct *selected[LOWMEM_DEATHPENDING_DEPTH] = {NULL,}; #else struct task_struct *selected = NULL; #endif #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO_VERBOSE static DEFINE_RATELIMIT_STATE(lmk_rs, DEFAULT_RATELIMIT_INTERVAL, 0); #else static DEFINE_RATELIMIT_STATE(lmk_rs, 6*DEFAULT_RATELIMIT_INTERVAL, 0); #endif #endif int rem = 0; int tasksize; int i; int min_score_adj = OOM_SCORE_ADJ_MAX + 1; #ifdef ENHANCED_LMK_ROUTINE int selected_tasksize[LOWMEM_DEATHPENDING_DEPTH] = {0,}; int selected_oom_score_adj[LOWMEM_DEATHPENDING_DEPTH] = {OOM_ADJUST_MAX,}; int all_selected_oom = 0; int max_selected_oom_idx = 0; #else int selected_tasksize = 0; int selected_oom_score_adj; #endif int array_size = ARRAY_SIZE(lowmem_adj); #if (!defined(CONFIG_MACH_JF) \ && !defined(CONFIG_SEC_PRODUCT_8960)\ ) unsigned long nr_to_scan = sc->nr_to_scan; #endif #ifndef CONFIG_CMA int other_free = global_page_state(NR_FREE_PAGES); #else int other_free = global_page_state(NR_FREE_PAGES) - global_page_state(NR_FREE_CMA_PAGES); #endif int other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM); #ifdef CONFIG_ZRAM_FOR_ANDROID other_file -= total_swapcache_pages; #endif /* CONFIG_ZRAM_FOR_ANDROID */ if (lowmem_adj_size < array_size) array_size = lowmem_adj_size; if (lowmem_minfree_size < array_size) array_size = lowmem_minfree_size; for (i = 0; i < array_size; i++) { if (other_free < lowmem_minfree[i] && other_file < lowmem_minfree[i]) { min_score_adj = lowmem_adj[i]; break; } } if (sc->nr_to_scan > 0) lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", sc->nr_to_scan, sc->gfp_mask, other_free, other_file, min_score_adj); rem = global_page_state(NR_ACTIVE_ANON) + global_page_state(NR_ACTIVE_FILE) + global_page_state(NR_INACTIVE_ANON) + global_page_state(NR_INACTIVE_FILE); if (sc->nr_to_scan <= 0 || min_score_adj == OOM_SCORE_ADJ_MAX + 1) { lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n", sc->nr_to_scan, sc->gfp_mask, rem); return rem; } #ifdef ENHANCED_LMK_ROUTINE for (i = 0; i < LOWMEM_DEATHPENDING_DEPTH; i++) selected_oom_score_adj[i] = min_score_adj; #else selected_oom_score_adj = min_score_adj; #endif #ifdef CONFIG_ZRAM_FOR_ANDROID atomic_set(&s_reclaim.lmk_running, 1); #endif /* CONFIG_ZRAM_FOR_ANDROID */ read_lock(&tasklist_lock); for_each_process(tsk) { struct task_struct *p; int oom_score_adj; #ifdef ENHANCED_LMK_ROUTINE int is_exist_oom_task = 0; #endif if (tsk->flags & PF_KTHREAD) continue; p = find_lock_task_mm(tsk); if (!p) continue; if (test_tsk_thread_flag(p, TIF_MEMDIE) && time_before_eq(jiffies, lowmem_deathpending_timeout)) { task_unlock(p); read_unlock(&tasklist_lock); #ifdef CONFIG_ZRAM_FOR_ANDROID atomic_set(&s_reclaim.lmk_running, 0); #endif /* CONFIG_ZRAM_FOR_ANDROID */ return 0; } oom_score_adj = p->signal->oom_score_adj; if (oom_score_adj < min_score_adj) { task_unlock(p); continue; } tasksize = get_mm_rss(p->mm); task_unlock(p); if (tasksize <= 0) continue; #ifdef ENHANCED_LMK_ROUTINE if (all_selected_oom < LOWMEM_DEATHPENDING_DEPTH) { for (i = 0; i < LOWMEM_DEATHPENDING_DEPTH; i++) { if (!selected[i]) { is_exist_oom_task = 1; max_selected_oom_idx = i; break; } } } else if (selected_oom_score_adj[max_selected_oom_idx] < oom_score_adj || (selected_oom_score_adj[max_selected_oom_idx] == oom_score_adj && selected_tasksize[max_selected_oom_idx] < tasksize)) { is_exist_oom_task = 1; } if (is_exist_oom_task) { selected[max_selected_oom_idx] = p; selected_tasksize[max_selected_oom_idx] = tasksize; selected_oom_score_adj[max_selected_oom_idx] = oom_score_adj; if (all_selected_oom < LOWMEM_DEATHPENDING_DEPTH) all_selected_oom++; if (all_selected_oom == LOWMEM_DEATHPENDING_DEPTH) { for (i = 0; i < LOWMEM_DEATHPENDING_DEPTH; i++) { if (selected_oom_score_adj[i] < selected_oom_score_adj[max_selected_oom_idx]) max_selected_oom_idx = i; else if (selected_oom_score_adj[i] == selected_oom_score_adj[max_selected_oom_idx] && selected_tasksize[i] < selected_tasksize[max_selected_oom_idx]) max_selected_oom_idx = i; } } lowmem_print(2, "select %d (%s), adj %d, \ size %d, to kill\n", p->pid, p->comm, oom_score_adj, tasksize); } #else if (selected) { if (oom_score_adj < selected_oom_score_adj) continue; if (oom_score_adj == selected_oom_score_adj && tasksize <= selected_tasksize) continue; } selected = p; selected_tasksize = tasksize; selected_oom_score_adj = oom_score_adj; lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n", p->pid, p->comm, oom_score_adj, tasksize); #endif } #ifdef ENHANCED_LMK_ROUTINE for (i = 0; i < LOWMEM_DEATHPENDING_DEPTH; i++) { if (selected[i]) { lowmem_print(1, "send sigkill to %d (%s), adj %d,\ size %d, free memory = %d, reclaimable memory = %d\n", selected[i]->pid, selected[i]->comm, selected_oom_score_adj[i], selected_tasksize[i], other_free, other_file); lowmem_deathpending_timeout = jiffies + HZ; send_sig(SIGKILL, selected[i], 0); set_tsk_thread_flag(selected[i], TIF_MEMDIE); rem -= selected_tasksize[i]; #ifdef LMK_COUNT_READ lmk_count++; #endif } } #else if (selected) { lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected_oom_score_adj, selected_tasksize); lowmem_deathpending_timeout = jiffies + HZ; send_sig(SIGKILL, selected, 0); set_tsk_thread_flag(selected, TIF_MEMDIE); rem -= selected_tasksize; #ifdef LMK_COUNT_READ lmk_count++; #endif } #endif #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO if (__ratelimit(&lmk_rs)) { lowmem_print(1, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", nr_to_scan, sc->gfp_mask, other_free, other_file, min_score_adj); #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO_VERBOSE show_mem(SHOW_MEM_FILTER_NODES); dump_tasks_info(); #endif } #endif lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", sc->nr_to_scan, sc->gfp_mask, rem); read_unlock(&tasklist_lock); #ifdef CONFIG_ZRAM_FOR_ANDROID atomic_set(&s_reclaim.lmk_running, 0); #endif /* CONFIG_ZRAM_FOR_ANDROID */ return rem; }
static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { struct task_struct *tsk; struct task_struct *selected = NULL; int rem = 0; int tasksize; int i; short min_score_adj = OOM_SCORE_ADJ_MAX + 1; int minfree = 0; int selected_tasksize = 0; short selected_oom_score_adj; int array_size = ARRAY_SIZE(lowmem_adj); int other_free; int other_file; unsigned long nr_to_scan = sc->nr_to_scan; #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO static DEFINE_RATELIMIT_STATE(lmk_rs, DEFAULT_RATELIMIT_INTERVAL, 1); #endif unsigned long nr_cma_free; if (nr_to_scan > 0) { if (mutex_lock_interruptible(&scan_mutex) < 0) return 0; } other_free = global_page_state(NR_FREE_PAGES); nr_cma_free = global_page_state(NR_FREE_CMA_PAGES); if (!current_is_kswapd() || sc->priority <= 6) other_free -= nr_cma_free; if (global_page_state(NR_SHMEM) + total_swapcache_pages() < global_page_state(NR_FILE_PAGES)) other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM) - total_swapcache_pages(); else other_file = 0; if (lowmem_adj_size < array_size) array_size = lowmem_adj_size; if (lowmem_minfree_size < array_size) array_size = lowmem_minfree_size; for (i = 0; i < array_size; i++) { minfree = lowmem_minfree[i]; if (other_free < minfree && other_file < minfree) { min_score_adj = lowmem_adj[i]; break; } } if (nr_to_scan > 0) lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %hd\n", nr_to_scan, sc->gfp_mask, other_free, other_file, min_score_adj); rem = global_page_state(NR_ACTIVE_ANON) + global_page_state(NR_ACTIVE_FILE) + global_page_state(NR_INACTIVE_ANON) + global_page_state(NR_INACTIVE_FILE); if (nr_to_scan <= 0 || min_score_adj == OOM_SCORE_ADJ_MAX + 1) { lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n", nr_to_scan, sc->gfp_mask, rem); if (nr_to_scan > 0) mutex_unlock(&scan_mutex); return rem; } selected_oom_score_adj = min_score_adj; rcu_read_lock(); for_each_process(tsk) { struct task_struct *p; short oom_score_adj; if (tsk->flags & PF_KTHREAD || tsk->state & TASK_UNINTERRUPTIBLE) continue; /* if task no longer has any memory ignore it */ if (test_task_flag(tsk, TIF_MM_RELEASED)) continue; if (time_before_eq(jiffies, lowmem_deathpending_timeout)) { if (test_task_flag(tsk, TIF_MEMDIE)) { rcu_read_unlock(); /* give the system time to free up the memory */ msleep_interruptible(20); mutex_unlock(&scan_mutex); return 0; } } p = find_lock_task_mm(tsk); if (!p) continue; oom_score_adj = p->signal->oom_score_adj; if (oom_score_adj < min_score_adj) { task_unlock(p); continue; } tasksize = get_mm_rss(p->mm); task_unlock(p); if (tasksize <= 0) continue; if (selected) { if (oom_score_adj < selected_oom_score_adj) continue; if (oom_score_adj == selected_oom_score_adj && tasksize <= selected_tasksize) continue; } selected = p; selected_tasksize = tasksize; selected_oom_score_adj = oom_score_adj; lowmem_print(3, "select '%s' (%d), adj %hd, size %d, to kill\n", p->comm, p->pid, oom_score_adj, tasksize); } if (selected) { lowmem_print(1, "Killing '%s' (%d), adj %hd,\n" \ " to free %ldkB on behalf of '%s' (%d) because\n" \ " cache %ldkB is below limit %ldkB for oom_score_adj %hd\n" \ " Free memory is %ldkB above reserved.\n" \ " is_kswapd %d priority %d\n" \ " Free CMA is %ldkB\n" \ " Total reserve is %ldkB\n" \ " Total free pages is %ldkB\n" \ " Total file cache is %ldkB\n" \ " Slab Reclaimable is %ldkB\n" \ " Slab UnReclaimable is %ldkB\n" \ " Total Slab is %ldkB\n" \ " GFP mask is 0x%x\n", selected->comm, selected->pid, selected_oom_score_adj, selected_tasksize * (long)(PAGE_SIZE / 1024), current->comm, current->pid, other_file * (long)(PAGE_SIZE / 1024), minfree * (long)(PAGE_SIZE / 1024), min_score_adj, other_free * (long)(PAGE_SIZE / 1024), !!current_is_kswapd(), sc->priority, nr_cma_free * (long)(PAGE_SIZE / 1024), totalreserve_pages * (long)(PAGE_SIZE / 1024), global_page_state(NR_FREE_PAGES) * (long)(PAGE_SIZE / 1024), global_page_state(NR_FILE_PAGES) * (long)(PAGE_SIZE / 1024), global_page_state(NR_SLAB_RECLAIMABLE) * (long)(PAGE_SIZE / 1024), global_page_state(NR_SLAB_UNRECLAIMABLE) * (long)(PAGE_SIZE / 1024), global_page_state(NR_SLAB_RECLAIMABLE) * (long)(PAGE_SIZE / 1024) + global_page_state(NR_SLAB_UNRECLAIMABLE) * (long)(PAGE_SIZE / 1024), sc->gfp_mask); if (lowmem_debug_level >= 2 && selected_oom_score_adj == 0) { show_mem(SHOW_MEM_FILTER_NODES); dump_tasks(NULL, NULL); show_mem_call_notifiers(); } lowmem_deathpending_timeout = jiffies + HZ; send_sig(SIGKILL, selected, 0); set_tsk_thread_flag(selected, TIF_MEMDIE); rem -= selected_tasksize; rcu_read_unlock(); #ifdef LMK_COUNT_READ lmk_count++; #endif #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO if (__ratelimit(&lmk_rs)) { lowmem_print(1, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", nr_to_scan, sc->gfp_mask, other_free, other_file, min_score_adj); show_mem(SHOW_MEM_FILTER_NODES); dump_tasks_info(); } #endif /* give the system time to free up the memory */ msleep_interruptible(20); } else rcu_read_unlock(); lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", nr_to_scan, sc->gfp_mask, rem); mutex_unlock(&scan_mutex); return rem; }
static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { struct task_struct *tsk; struct task_struct *selected = NULL; int rem = 0; int tasksize; int i; int min_score_adj = OOM_SCORE_ADJ_MAX + 1; int minfree = 0; int selected_tasksize = 0; int selected_oom_score_adj; int array_size = ARRAY_SIZE(lowmem_adj); int other_free; int other_file; unsigned long nr_to_scan = sc->nr_to_scan; if (nr_to_scan > 0) { if (mutex_lock_interruptible(&scan_mutex) < 0) return 0; } other_free = global_page_state(NR_FREE_PAGES); other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM); tune_lmk_param(&other_free, &other_file, sc); if (lowmem_adj_size < array_size) array_size = lowmem_adj_size; if (lowmem_minfree_size < array_size) array_size = lowmem_minfree_size; for (i = 0; i < array_size; i++) { minfree = lowmem_minfree[i]; if (other_free < minfree && other_file < minfree) { min_score_adj = lowmem_adj[i]; break; } } if (nr_to_scan > 0) lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", nr_to_scan, sc->gfp_mask, other_free, other_file, min_score_adj); rem = global_page_state(NR_ACTIVE_ANON) + global_page_state(NR_ACTIVE_FILE) + global_page_state(NR_INACTIVE_ANON) + global_page_state(NR_INACTIVE_FILE); if (nr_to_scan <= 0 || min_score_adj == OOM_SCORE_ADJ_MAX + 1) { lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n", nr_to_scan, sc->gfp_mask, rem); if (nr_to_scan > 0) mutex_unlock(&scan_mutex); return rem; } selected_oom_score_adj = min_score_adj; rcu_read_lock(); for_each_process(tsk) { struct task_struct *p; int oom_score_adj; if (tsk->flags & PF_KTHREAD) continue; /* if task no longer has any memory ignore it */ if (test_task_flag(tsk, TIF_MM_RELEASED)) continue; if (time_before_eq(jiffies, lowmem_deathpending_timeout)) { if (test_task_flag(tsk, TIF_MEMDIE)) { rcu_read_unlock(); /* give the system time to free up the memory */ msleep_interruptible(20); mutex_unlock(&scan_mutex); return 0; } } p = find_lock_task_mm(tsk); if (!p) continue; oom_score_adj = p->signal->oom_score_adj; if (oom_score_adj < min_score_adj) { task_unlock(p); continue; } tasksize = get_mm_rss(p->mm); task_unlock(p); if (tasksize <= 0) continue; if (selected) { if (oom_score_adj < selected_oom_score_adj) continue; if (oom_score_adj == selected_oom_score_adj && tasksize <= selected_tasksize) continue; } selected = p; selected_tasksize = tasksize; selected_oom_score_adj = oom_score_adj; lowmem_print(3, "select '%s' (%d), adj %hd, size %d, to kill\n", p->comm, p->pid, oom_score_adj, tasksize); } if (selected) { lowmem_print(1, "Killing '%s' (%d), adj %hd,\n" \ " to free %ldkB on behalf of '%s' (%d) because\n" \ " cache %ldkB is below limit %ldkB for oom_score_adj %hd\n" \ " Free memory is %ldkB above reserved.\n" \ " Free CMA is %ldkB\n" \ " Total reserve is %ldkB\n" \ " Total free pages is %ldkB\n" \ " Total file cache is %ldkB\n" \ " GFP mask is 0x%x\n", selected->comm, selected->pid, selected_oom_score_adj, selected_tasksize * (long)(PAGE_SIZE / 1024), current->comm, current->pid, other_file * (long)(PAGE_SIZE / 1024), minfree * (long)(PAGE_SIZE / 1024), min_score_adj, other_free * (long)(PAGE_SIZE / 1024), global_page_state(NR_FREE_CMA_PAGES) * (long)(PAGE_SIZE / 1024), totalreserve_pages * (long)(PAGE_SIZE / 1024), global_page_state(NR_FREE_PAGES) * (long)(PAGE_SIZE / 1024), global_page_state(NR_FILE_PAGES) * (long)(PAGE_SIZE / 1024), sc->gfp_mask); if (lowmem_debug_level >= 2 && selected_oom_score_adj == 0) { show_mem(SHOW_MEM_FILTER_NODES); dump_tasks(NULL, NULL); } lowmem_deathpending_timeout = jiffies + HZ; send_sig(SIGKILL, selected, 0); set_tsk_thread_flag(selected, TIF_MEMDIE); rem -= selected_tasksize; rcu_read_unlock(); /* give the system time to free up the memory */ msleep_interruptible(20); } else rcu_read_unlock(); lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", nr_to_scan, sc->gfp_mask, rem); mutex_unlock(&scan_mutex); return rem; }
static void sysrq_handle_showmem(int key, struct tty_struct *tty) { show_mem(); }
static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { struct task_struct *tsk; struct task_struct *selected = NULL; int rem = 0; int tasksize; int i; int min_score_adj = OOM_SCORE_ADJ_MAX + 1; int selected_tasksize = 0; int selected_oom_score_adj; #ifdef CONFIG_SAMP_HOTNESS int selected_hotness_adj = 0; #endif int array_size = ARRAY_SIZE(lowmem_adj); int other_free; int other_file; unsigned long nr_to_scan = sc->nr_to_scan; #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO static DEFINE_RATELIMIT_STATE(lmk_rs, DEFAULT_RATELIMIT_INTERVAL, 1); #endif unsigned long nr_cma_free; struct reclaim_state *reclaim_state = current->reclaim_state; #if defined(CONFIG_CMA_PAGE_COUNTING) unsigned long nr_cma_inactive_file; unsigned long nr_cma_active_file; unsigned long cma_page_ratio; bool is_active_high; bool flag = 0; #endif if (nr_to_scan > 0) { if (mutex_lock_interruptible(&scan_mutex) < 0) return 0; } other_free = global_page_state(NR_FREE_PAGES); nr_cma_free = global_page_state(NR_FREE_CMA_PAGES); #ifdef CONFIG_ZSWAP if (!current_is_kswapd() || sc->priority <= 6) #endif other_free -= nr_cma_free; #if defined(CONFIG_CMA_PAGE_COUNTING) nr_cma_inactive_file = global_page_state(NR_CMA_INACTIVE_FILE); nr_cma_active_file = global_page_state(NR_CMA_ACTIVE_FILE); cma_page_ratio = 100 * global_page_state(NR_CMA_INACTIVE_FILE) / global_page_state(NR_INACTIVE_FILE); is_active_high = (global_page_state(NR_ACTIVE_FILE) > global_page_state(NR_INACTIVE_FILE)) ? 1 : 0; #endif other_file = global_page_state(NR_FILE_PAGES); #if defined(CONFIG_CMA_PAGE_COUNTING) && defined(CONFIG_EXCLUDE_LRU_LIVING_IN_CMA) if (get_nr_swap_pages() < SSWAP_LMK_THRESHOLD && cma_page_ratio >= CMA_PAGE_RATIO && !is_active_high) { other_file = other_file - (nr_cma_inactive_file + nr_cma_active_file); flag = 1; } #endif if (global_page_state(NR_SHMEM) + total_swapcache_pages < other_file) other_file -= global_page_state(NR_SHMEM) + total_swapcache_pages; else other_file = 0; if (lowmem_adj_size < array_size) array_size = lowmem_adj_size; if (lowmem_minfree_size < array_size) array_size = lowmem_minfree_size; for (i = 0; i < array_size; i++) { if (other_free < lowmem_minfree[i] && other_file < lowmem_minfree[i]) { min_score_adj = lowmem_adj[i]; break; } } if (nr_to_scan > 0) lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", nr_to_scan, sc->gfp_mask, other_free, other_file, min_score_adj); rem = global_page_state(NR_ACTIVE_ANON) + global_page_state(NR_ACTIVE_FILE) + global_page_state(NR_INACTIVE_ANON) + global_page_state(NR_INACTIVE_FILE); if (nr_to_scan <= 0 || min_score_adj == OOM_SCORE_ADJ_MAX + 1) { lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n", nr_to_scan, sc->gfp_mask, rem); if (nr_to_scan > 0) mutex_unlock(&scan_mutex); return rem; } selected_oom_score_adj = min_score_adj; rcu_read_lock(); for_each_process(tsk) { struct task_struct *p; int oom_score_adj; #ifdef CONFIG_SAMP_HOTNESS int hotness_adj = 0; #endif if (tsk->flags & PF_KTHREAD) continue; /* if task no longer has any memory ignore it */ if (test_task_flag(tsk, TIF_MM_RELEASED)) continue; if (time_before_eq(jiffies, lowmem_deathpending_timeout)) { if (test_task_flag(tsk, TIF_MEMDIE)) { rcu_read_unlock(); /* give the system time to free up the memory */ msleep_interruptible(20); mutex_unlock(&scan_mutex); return 0; } } p = find_lock_task_mm(tsk); if (!p) continue; oom_score_adj = p->signal->oom_score_adj; if (oom_score_adj < min_score_adj) { task_unlock(p); continue; } tasksize = get_mm_rss(p->mm); #if defined(CONFIG_ZSWAP) if (atomic_read(&zswap_stored_pages)) { lowmem_print(3, "shown tasksize : %d\n", tasksize); tasksize += atomic_read(&zswap_pool_pages) * get_mm_counter(p->mm, MM_SWAPENTS) / atomic_read(&zswap_stored_pages); lowmem_print(3, "real tasksize : %d\n", tasksize); } #endif #ifdef CONFIG_SAMP_HOTNESS hotness_adj = p->signal->hotness_adj; #endif task_unlock(p); if (tasksize <= 0) continue; if (selected) { #ifdef CONFIG_SAMP_HOTNESS if (min_score_adj <= lowmem_adj[4]) { #endif if (oom_score_adj < selected_oom_score_adj) continue; if (oom_score_adj == selected_oom_score_adj && tasksize <= selected_tasksize) continue; #ifdef CONFIG_SAMP_HOTNESS } else { if (hotness_adj > selected_hotness_adj) continue; if (hotness_adj == selected_hotness_adj && tasksize <= selected_tasksize) continue; } #endif } selected = p; selected_tasksize = tasksize; selected_oom_score_adj = oom_score_adj; #ifdef CONFIG_SAMP_HOTNESS selected_hotness_adj = hotness_adj; #endif lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n", p->pid, p->comm, oom_score_adj, tasksize); } if (selected) { #if defined(CONFIG_CMA_PAGE_COUNTING) #ifdef CONFIG_SAMP_HOTNESS lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d, " "ofree %d, ofile %d(%c), is_kswapd %d - " "cma_free %lu priority %d cma_i_file %lu cma_a_file %lu, hotness %d\n", selected->pid, selected->comm, selected_oom_score_adj, selected_tasksize, other_free, other_file, flag ? '-' : '+', !!current_is_kswapd(), nr_cma_free, sc->priority, nr_cma_inactive_file, nr_cma_active_file, selected_hotness_adj); #else lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d, " "ofree %d, ofile %d(%c), is_kswapd %d - " "cma_free %lu priority %d cma_i_file %lu cma_a_file %lu\n", selected->pid, selected->comm, selected_oom_score_adj, selected_tasksize, other_free, other_file, flag ? '-' : '+', !!current_is_kswapd(), nr_cma_free, sc->priority, nr_cma_inactive_file, nr_cma_active_file); #endif #else #ifdef CONFIG_SAMP_HOTNESS lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d, " "free memory = %d, reclaimable memory = %d " "is_kswapd %d cma_free %lu priority %d, hotness %d\n", selected->pid, selected->comm, selected_oom_score_adj, selected_tasksize, other_free, other_file, !!current_is_kswapd(), nr_cma_free, sc->priority, selected_hotness_adj); #else lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d, " "free memory = %d, reclaimable memory = %d " "is_kswapd %d cma_free %lu priority %d\n", selected->pid, selected->comm, selected_oom_score_adj, selected_tasksize, other_free, other_file, !!current_is_kswapd(), nr_cma_free, sc->priority); #endif #endif lowmem_deathpending_timeout = jiffies + HZ; send_sig(SIGKILL, selected, 0); set_tsk_thread_flag(selected, TIF_MEMDIE); rem -= selected_tasksize; rcu_read_unlock(); #ifdef LMK_COUNT_READ lmk_count++; #endif #ifdef CONFIG_SEC_DEBUG_LMK_MEMINFO if ((selected_oom_score_adj < lowmem_adj[5]) && __ratelimit(&lmk_rs)) { lowmem_print(1, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", nr_to_scan, sc->gfp_mask, other_free, other_file, min_score_adj); show_mem(SHOW_MEM_FILTER_NODES); dump_tasks_info(); } #endif /* give the system time to free up the memory */ msleep_interruptible(20); if(reclaim_state) reclaim_state->reclaimed_slab = selected_tasksize; } else rcu_read_unlock(); lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", nr_to_scan, sc->gfp_mask, rem); mutex_unlock(&scan_mutex); return rem; }
void debugger() { char cmd[8]; char subcmd[256]; char *subopt1; char *subopt2; int chr_check_result; int sublen; int opt = 0; int menu = 1; while(menu) { memset(cmd,0,sizeof(cmd)); memset(subcmd,0,sizeof(subcmd)); printf("\n"); printf("LameNES debugger command>"); if(fgets(cmd, 5,stdin) != NULL) { if(cmd[0] != '\0' && cmd[strlen(cmd) - 1] == '\n') cmd[strlen(cmd) - 1] = '\0'; } switch(cmd[0]) { case 'b': printf("\nenter breakpoint: 0x"); if(fgets(subcmd, 7,stdin) != NULL) { if(subcmd[0] != '\0' && subcmd[strlen(subcmd) - 1] == '\n') subcmd[strlen(subcmd) - 1] = '\0'; } sublen = strlen(subcmd); if(sublen > 5) { printf("error: address range must be between 0x0000 and 0xFFFF\n"); } else { chr_check_result = str_chrchk(subcmd,"0123456789abcdef"); if((chr_check_result > 0) && (strlen(subcmd) == chr_check_result)) { breakpoint = strtoul(subcmd, NULL, 16); } else { printf("error: unknown memory address given!\n"); } } break; case 'c': printf("continue with emulation!\n"); hit_break = 0; disassemble = 0; menu = 0; break; case 'd': if(stackdebug == 1) { printf("stack debugging disabled!\n"); stackdebug = 0; } else { printf("stack debugging enabled!\n"); stackdebug = 1; } break; case 'f': printf("[%d] ppu_control1: %x\n",debug_cnt,ppu_control1); printf("[%d] ppu_control2: %x\n",debug_cnt,ppu_control2); printf("[%d] ppu_status: %x\n",debug_cnt,ppu_status); printf("[%d] ppu_status_ret: %x\n",debug_cnt,(ppu_status & 0xE0) | (ppu_addr_tmp & 0x1F)); printf("[%d] current scanline: %d\n",debug_cnt,current_scanline); printf("[%d] current nametable: %x\n",debug_cnt,0x2000 + (loopyV & 0x0fff)); printf("[%d] loopyT: %x\n",debug_cnt,loopyT); printf("[%d] loopyV: %x\n",debug_cnt,loopyV); printf("[%d] loopyX: %x\n",debug_cnt,loopyX); printf("[%d] exec_nmi_on_vblank: %x\n",debug_cnt,exec_nmi_on_vblank); printf("[%d] sprite_16: %d\n",debug_cnt,sprite_16); printf("[%d] background_addr_hi: %x\n",debug_cnt,background_addr_hi); printf("[%d] sprite_addr_hi: %d\n",debug_cnt,sprite_addr_hi); printf("[%d] increment_32: %d\n",debug_cnt,increment_32); printf("[%d] sprite_on: %d\n",debug_cnt,sprite_on); printf("[%d] background_on: %d\n",debug_cnt,background_on); printf("[%d] sprite_clipping_off: %d\n",debug_cnt,sprite_clipping_off); printf("[%d] background_clipping_off: %d\n",debug_cnt,background_clipping_off); printf("[%d] monochrome_on: %d\n",debug_cnt,monochrome_on); printf("[%d] vblank_on: %d\n",debug_cnt,vblank_on); printf("[%d] sprite_zero: %d\n",debug_cnt,sprite_zero); printf("[%d] scanline_sprite_count: %d\n",debug_cnt,scanline_sprite_count); printf("[%d] vram_write_flag: %d\n",debug_cnt,vram_write_flag); break; case 'h': printf("------------------------------\n"); printf("LameNES debugger command list:\n"); printf("------------------------------\n"); printf("(b)reakpoint -> set breakpoint\n"); printf("(c)ontinue -> continue emulation\n"); printf("(d)ebug stack operations -> enable/disable stack debugging\n"); printf("(i)nstruction counter break -> set instruction counter breakpoint\n"); printf("(f)lags states -> show all states of current flags\n"); printf("(h)elp -> this screen\n"); printf("(l)oad state -> loads emulation state\n"); printf("(m)emorydump -> show or dump the complete nes memory\n"); printf("(p)pu status -> show ppu status\n"); printf("(q)uit -> quit LameNES\n"); printf("(s)ave state -> saves emulation state\n"); printf("(u)pdate controller io -> send joypad1 io\n"); printf("(anything else) -> executes the next instruction\n"); break; case 'i': printf("\nenter instruction counter breakpoint: "); if(fgets(subcmd, 255,stdin) != NULL) { if(subcmd[0] != '\0' && subcmd[strlen(subcmd) - 1] == '\n') subcmd[strlen(subcmd) - 1] = '\0'; } sublen = strlen(subcmd); if(sublen > 255) { printf("error: counter too large!\n"); } else { stop_at_debug_cnt = atoi(subcmd); } break; case 'l': load_state(); break; case 'm': printf("memory options:\n" "m <memory address> -> display main ram from given address + next 100 bytes\n" "p <memory address> -> display ppu ram from given address + next 100 bytes\n" "s <memory address> -> display sprite ram from given address + next 100 bytes\n" "a -> dump all memory registers to bin files\n" "enter option: " ); if(fgets(subcmd, 255,stdin) != NULL) { if(subcmd[0] != '\0' && subcmd[strlen(subcmd) - 1] == '\n') subcmd[strlen(subcmd) - 1] = '\0'; } sublen = strlen(subcmd); if(sublen > 10) { printf("error: option string too large\n"); break; } switch(subcmd[0]) { case 'a': printf("dumping main memory to: lamenes_nesmem.bin\n"); dump_mem("lamenes_nesmem.bin"); printf("dumping ppu memory to: lamenes_ppumem.bin\n"); dump_ppu_mem("lamenes_ppumem.bin"); printf("dumping sprite memory to: lamenes_spritemem.bin\n"); dump_sprite_mem("lamenes_spritemem.bin"); printf("dumping nametables to: lamenes_nametables.bin\n"); dump_ppu_nam("lamenes_nametables.bin"); printf("dumping palette to: lamenes_palette.bin\n"); dump_ppu_palette("lamenes_palette.bin"); printf("dumping main ram to: lamenes_nesram.bin\n"); dump_nesram("lamenes_nesram.bin"); printf("dumping ppu ram to: lamenes_ppuram.bin\n"); dump_ppuram("lamenes_ppuram.bin"); printf("dumping stack to: lamenes_stackdump.bin\n"); dump_stack("lamenes_stackdump.bin"); break; case 'm': subopt1 = str_cut(subcmd," "); subopt2 = str_cut(NULL," "); chr_check_result = str_chrchk(subopt2,"0123456789abcdef"); if((chr_check_result > 0) && (strlen(subopt2) == chr_check_result)) { opt = strtoul(subopt2, NULL, 16); show_mem("main",opt); } else { printf("error: unknown memory address given!\n"); } break; case 'p': subopt1 = str_cut(subcmd," "); subopt2 = str_cut(NULL," "); chr_check_result = str_chrchk(subopt2,"0123456789abcdef"); if((chr_check_result > 0) && (strlen(subopt2) == chr_check_result)) { opt = strtoul(subopt2, NULL, 16); show_mem("ppu",opt); } else { printf("error: unknown memory address given!\n"); } break; case 's': subopt1 = str_cut(subcmd," "); subopt2 = str_cut(NULL," "); chr_check_result = str_chrchk(subopt2,"0123456789abcdef"); if((chr_check_result > 0) && (strlen(subopt2) == chr_check_result)) { opt = strtoul(subopt2, NULL, 16); show_mem("sprite",opt); } else { printf("error: unknown memory address given!\n"); } break; default: break; } break; case 'p': printf("ppu status options:\n" "(s)prite attributes -> display current sprite attributes\n" "enter option: " ); if(fgets(subcmd, 255,stdin) != NULL) { if(subcmd[0] != '\0' && subcmd[strlen(subcmd) - 1] == '\n') subcmd[strlen(subcmd) - 1] = '\0'; } sublen = strlen(subcmd); if(sublen > 10) { printf("error: option string too large\n"); break; } switch(subcmd[0]) { case 's': show_sprite_attribs(); break; default: break; } break; case 'q': quit_emulation(); break; case 's': save_state(); break; case 'u': printf("\nchoose the following joypad1 oi command to send:\n" "1 -> down\n" "2 -> up\n" "3 -> left\n" "4 -> right\n" "5 -> start\n" "6 -> select\n" "7 -> A\n" "8 -> B\n" "enter selection: "); if(fgets(subcmd, 2,stdin) != NULL) { if(subcmd[0] != '\0' && subcmd[strlen(subcmd) - 1] == '\n') subcmd[strlen(subcmd) - 1] = '\0'; } sublen = strlen(subcmd); if(sublen > 2) { printf("error: too many arguments!\n"); break; } chr_check_result = str_chrchk(subcmd,"12345678"); if((chr_check_result > 0) && (strlen(subcmd) == chr_check_result)) { opt = atoi(subcmd); switch(opt) { /* down */ case 1: printf("sending joypad1 [down] to io.\n"); set_input(1); break; /* up */ case 2: printf("sending joypad1 [up] to io.\n"); set_input(2); break; /* left */ case 3: printf("sending joypd1 [left] to io.\n"); set_input(3); break; /* right */ case 4: printf("sending joypad1 [right] to io.\n"); set_input(4); break; /* start */ case 5: printf("sending joypad1 [start] to io.\n"); set_input(5); break; /* select */ case 6: printf("sending joypad1 [select] to io.\n"); set_input(6); break; /* A */ case 7: printf("sending joypad1 [A] to io.\n"); set_input(7); break; /* B */ case 8: printf("sending joypad1 [B] to io.\n"); set_input(8); break; default: printf("error: unknown option!\n"); break; } } else { printf("error: wrong argument!\n"); } break; case 'v': printf("interrupt vectors:\n\n"); printf("INIT [0xfffc] -> 0x%x\n",(memory[0xfffd] << 8) | memory[0xfffc]); printf("IRQ [0xfffe] -> 0x%x\n",(memory[0xffff] << 8) | memory[0xfffe]); printf("NMI [0xfffa] -> 0x%x\n",(memory[0xfffb] << 8) | memory[0xfffa]); break; default: printf("executing next instruction!\n"); menu = 0; break; } } }
static void sysrq_handle_showmem(int key) { show_mem(0); dump_user_task(); }
static int lowmem_shrink(struct shrinker *s, struct shrink_control *sc) { struct task_struct *p; struct task_struct *selected = NULL; int rem = 0; int tasksize; int i; int min_adj = OOM_ADJUST_MAX + 1; int selected_tasksize = 0; int selected_oom_adj; int array_size = ARRAY_SIZE(lowmem_adj); int other_free = global_page_state(NR_FREE_PAGES); int other_file = global_page_state(NR_FILE_PAGES) - global_page_state(NR_SHMEM); int lru_file = global_page_state(NR_ACTIVE_FILE) + global_page_state(NR_INACTIVE_FILE); struct zone *zone; int fork_boost = 0; size_t minfree_boosted[6] = {0, 0, 0, 0, 0, 0}; size_t *min_array; int *adj_array; if (offlining) { /* Discount all free space in the section being offlined */ for_each_zone(zone) { if (zone_idx(zone) == ZONE_MOVABLE) { other_free -= zone_page_state(zone, NR_FREE_PAGES); lowmem_print(4, "lowmem_shrink discounted " "%lu pages in movable zone\n", zone_page_state(zone, NR_FREE_PAGES)); } } } /* * If we already have a death outstanding, then * bail out right away; indicating to vmscan * that we have nothing further to offer on * this pass. * */ if (lowmem_deathpending && time_before_eq(jiffies, lowmem_deathpending_timeout)) { dump_deathpending(lowmem_deathpending); return 0; } if (lowmem_fork_boost && time_before_eq(jiffies, lowmem_fork_boost_timeout)) { for (i = 0; i < lowmem_minfree_size; i++) minfree_boosted[i] = lowmem_minfree[i] + lowmem_fork_boost_minfree[i] ; /* Switch to fork_boost adj/minfree within boost_duration */ adj_array = fork_boost_adj; min_array = minfree_boosted; } else { adj_array = lowmem_adj; min_array = lowmem_minfree; } #ifdef CONFIG_SWAP if(fudgeswap != 0){ struct sysinfo si; si_swapinfo(&si); if(si.freeswap > 0){ if(fudgeswap > si.freeswap) other_file += si.freeswap; else other_file += fudgeswap; } } #endif if (lowmem_adj_size < array_size) array_size = lowmem_adj_size; if (lowmem_minfree_size < array_size) array_size = lowmem_minfree_size; for (i = 0; i < array_size; i++) { if (other_free < min_array[i]) { if (other_file < min_array[i] || (lowmem_check_filepages && (lru_file < min_array[i]))) { min_adj = adj_array[i]; fork_boost = lowmem_fork_boost_minfree[i]; break; } } } if (sc->nr_to_scan > 0) lowmem_print(3, "lowmem_shrink %lu, %x, ofree %d %d, ma %d\n", sc->nr_to_scan, sc->gfp_mask, other_free, other_file, min_adj); rem = global_page_state(NR_ACTIVE_ANON) + global_page_state(NR_ACTIVE_FILE) + global_page_state(NR_INACTIVE_ANON) + global_page_state(NR_INACTIVE_FILE); if (sc->nr_to_scan <= 0 || min_adj == OOM_ADJUST_MAX + 1) { lowmem_print(5, "lowmem_shrink %lu, %x, return %d\n", sc->nr_to_scan, sc->gfp_mask, rem); return rem; } selected_oom_adj = min_adj; read_lock(&tasklist_lock); for_each_process(p) { struct mm_struct *mm; struct signal_struct *sig; int oom_adj; task_lock(p); mm = p->mm; sig = p->signal; if (!mm || !sig) { task_unlock(p); continue; } oom_adj = sig->oom_adj; if (oom_adj < min_adj) { task_unlock(p); continue; } tasksize = get_mm_rss(mm); task_unlock(p); if (tasksize <= 0) continue; if (selected) { if (oom_adj < selected_oom_adj) continue; if (oom_adj == selected_oom_adj && tasksize <= selected_tasksize) continue; } selected = p; selected_tasksize = tasksize; selected_oom_adj = oom_adj; lowmem_print(2, "select %d (%s), adj %d, size %d, to kill\n", p->pid, p->comm, oom_adj, tasksize); } if (selected) { lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected_oom_adj, selected_tasksize); if (lowmem_fork_boost) lowmem_print(1, "current=[%s], min_adj=%d," " reclaim=%dK, free=%dK," " file=%dK, fork_boost=%dK\n", current->comm, min_adj, selected_tasksize << 2, other_free << 2, other_file << 2, fork_boost << 2); /* Show memory info if we reach certain adjs */ if (selected_oom_adj < last_min_selected_adj && (selected_oom_adj == 12 || selected_oom_adj == 9 || selected_oom_adj == 7)) { last_min_selected_adj = selected_oom_adj; show_mem(SHOW_MEM_FILTER_NODES); dump_tasks(); } /* Dump tasks if we hit low-memory condition */ if (selected_oom_adj < 7) { show_mem(SHOW_MEM_FILTER_NODES); dump_tasks(); } lowmem_deathpending = selected; lowmem_deathpending_timeout = jiffies + HZ; force_sig(SIGKILL, selected); rem -= selected_tasksize; } lowmem_print(4, "lowmem_shrink %lu, %x, return %d\n", sc->nr_to_scan, sc->gfp_mask, rem); read_unlock(&tasklist_lock); return rem; }
static void sysrq_handle_showmem(int key) { show_mem(0); show_mem_others(); }
static _INLINE_ void receive_chars(struct NIOS_serial *info, struct pt_regs *regs, unsigned short rx) { struct tty_struct *tty = info->tty; unsigned char ch; np_uart * uart= (np_uart *)(info->port); /* * This do { } while() loop will get ALL chars out of Rx FIFO */ do { ch = uart->np_uartrxdata; if(info->is_cons) { #ifdef CONFIG_MAGIC_SYSRQ if(rx & np_uartstatus_brk_mask) { batten_down_hatches(); return; } else if (ch == 0x10) { /* ^P */ show_state(); show_mem(); return; } else if (ch == 0x12) { /* ^R */ hard_reset_now(); return; #ifdef DEBUG } else if (ch == 0x02) { /* ^B */ batten_down_hatches(); return; } else if (ch == 0x01) { /* ^A */ asm("trap 0"); /* Back to monitor */ return; /* (won't be coming back) */ #endif } #endif /* CONFIG_MAGIC_SYSRQ */ } if(!tty) goto clear_and_exit; /* * Make sure that we do not overflow the buffer */ if (tty->flip.count >= TTY_FLIPBUF_SIZE) { queue_task(&tty->flip.tqueue, &tq_timer); return; } if(rx & np_uartstatus_pe_mask) { *tty->flip.flag_buf_ptr++ = TTY_PARITY; status_handle(info, rx); } else if(rx & np_uartstatus_roe_mask) { *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; status_handle(info, rx); } else if(rx & np_uartstatus_fe_mask) { *tty->flip.flag_buf_ptr++ = TTY_FRAME; status_handle(info, rx); } else if(rx & np_uartstatus_brk_mask) { *tty->flip.flag_buf_ptr++ = TTY_BREAK; status_handle(info, rx); } else { *tty->flip.flag_buf_ptr++ = 0; /* XXX */ } *tty->flip.char_buf_ptr++ = ch; tty->flip.count++; } while((rx = uart->np_uartstatus) & np_uartstatus_rrdy_mask); queue_task(&tty->flip.tqueue, &tq_timer); clear_and_exit: return; }