static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu) { struct task_struct *g, *p; unsigned long flags; SEQ_printf(m, "\nrunnable tasks:\n" " task PID tree-key switches prio" " exec-runtime sum-exec sum-sleep\n" "------------------------------------------------------" "----------------------------------------------------\n"); read_lock_irqsave(&tasklist_lock, flags); do_each_thread(g, p) { if (!p->on_rq || task_cpu(p) != rq_cpu) continue; print_task(m, rq, p); } while_each_thread(g, p); read_unlock_irqrestore(&tasklist_lock, flags); }
static inline void check_for_tasks(int dead_cpu) { struct task_struct *g, *p; read_lock_irq(&tasklist_lock); do_each_thread(g, p) { if (!p->on_rq) continue; /* * We do the check with unlocked task_rq(p)->lock. * Order the reading to do not warn about a task, * which was running on this cpu in the past, and * it's just been woken on another cpu. */ rmb(); if (task_cpu(p) != dead_cpu) continue; pr_warn("Task %s (pid=%d) is on cpu %d (state=%ld, flags=%x)\n", p->comm, task_pid_nr(p), dead_cpu, p->state, p->flags); } while_each_thread(g, p); read_unlock_irq(&tasklist_lock); }
/* 0 = success, else # of processes that we failed to stop */ int freeze_processes(void) { int todo; unsigned long start_time; struct task_struct *g, *p; printk( "Stopping tasks: " ); start_time = jiffies; do { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { unsigned long flags; if (!freezeable(p)) continue; if ((p->flags & PF_FROZEN) || (p->state == TASK_TRACED) || (p->state == TASK_STOPPED)) continue; /* FIXME: smp problem here: we may not access other process' flags without locking */ p->flags |= PF_FREEZE; spin_lock_irqsave(&p->sighand->siglock, flags); signal_wake_up(p, 0); spin_unlock_irqrestore(&p->sighand->siglock, flags); todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); yield(); /* Yield is okay here */ if (time_after(jiffies, start_time + TIMEOUT)) { printk( "\n" ); printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo ); return todo; } } while(todo);
bool current_is_single_threaded(void) { struct task_struct *task = current; struct mm_struct *mm = task->mm; struct task_struct *p, *t; bool ret; if (atomic_read(&task->signal->live) != 1) return false; if (atomic_read(&mm->mm_users) == 1) return true; ret = false; rcu_read_lock(); for_each_process(p) { if (unlikely(p->flags & PF_KTHREAD)) continue; if (unlikely(p == task->group_leader)) continue; t = p; do { if (unlikely(t->mm == mm)) goto found; if (likely(t->mm)) break; smp_rmb(); } while_each_thread(p, t); } ret = true; found: rcu_read_unlock(); return ret; }
static void record_sync_timeout_handler(unsigned long data) { int max_count = sysctl_hung_task_check_count; int batch_count = HUNG_TASK_BATCHING; struct task_struct *g, *t; rcu_read_lock(); do_each_thread(g, t) { if (!--max_count) goto unlock; if (!--batch_count) { batch_count = HUNG_TASK_BATCHING; rcu_lock_break(g, t); /* Exit if t or g was unhashed during refresh. */ if (t->state == TASK_DEAD || g->state == TASK_DEAD) goto unlock; } /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ if (t->state == TASK_UNINTERRUPTIBLE) record_hung_task(t); } while_each_thread(g, t); unlock: rcu_read_unlock(); }
static int search_task_and_mark(struct page* page, unsigned int nr_pages) { struct task_struct* p; struct task_struct* t; pid_t glpid = page->onwer_info.group_leader_pid; int high = is_highmem(page_zone(page)); unsigned long flags; int task_found = 0; read_lock_irqsave(&tasklist_lock, flags); for_each_process(p) { if(p->pid == glpid) { t = p; do { if( if_task_is_page_onwer(t, page )) { task_found = 1; write_free_mem_usage(&t->leak_detector, nr_pages, high); goto out_tasklist_loop; } } while_each_thread(p, t); break; } }
static int rksub_get_sym_tasks( struct rkusb_dev *dev ) { ALL_TASK at; TASK_INFO *ti; struct task_struct *g, *p; int buf_full = 0; int tn , tntoal; ti = (TASK_INFO*)__rkusb_rwbuffer_start( dev ); at.size = sizeof( at ); at.start_ts = ti; at.ti_size = sizeof(*ti); tntoal = 0; tn = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if( !buf_full ) { if( ti+1 > (TASK_INFO*)__rkusb_rwbuffer_end( dev ) ) { buf_full = 1; tn = tntoal; } else { __rksub_copy_task_info( ti , p ); ti++; } } tntoal ++; } while_each_thread(g, p); read_unlock(&tasklist_lock); if( !tn ) tn = tntoal; at.task_num = tn; at.task_total_num = tntoal; at.now = ktime_to_ns(ktime_get() ); rkusb_normal_data_xfer_onetime( dev , &at ); return RKUSB_CB_OK_NONE; }
void gr_handle_kernel_exploit(void) { #ifdef CONFIG_GRKERNSEC_KERN_LOCKOUT const struct cred *cred; struct task_struct *tsk, *tsk2; struct user_struct *user; uid_t uid; if (in_irq() || in_serving_softirq() || in_nmi()) panic("grsec: halting the system due to suspicious kernel crash caused in interrupt context"); uid = current_uid(); if (uid == 0) panic("grsec: halting the system due to suspicious kernel crash caused by root"); else { /* kill all the processes of this user, hold a reference to their creds struct, and prevent them from creating another process until system reset */ printk(KERN_ALERT "grsec: banning user with uid %u until system restart for suspicious kernel crash\n", uid); /* we intentionally leak this ref */ user = get_uid(current->cred->user); if (user) { user->banned = 1; user->ban_expires = ~0UL; } read_lock(&tasklist_lock); do_each_thread(tsk2, tsk) { cred = __task_cred(tsk); if (cred->uid == uid) gr_fake_force_sig(SIGKILL, tsk); } while_each_thread(tsk2, tsk); read_unlock(&tasklist_lock); }
static int try_to_freeze_tasks(bool sig_only) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; struct timeval start, end; u64 elapsed_csecs64; unsigned int elapsed_csecs; unsigned int wakeup = 0; do_gettimeofday(&start); end_time = jiffies + TIMEOUT; do { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (frozen(p) || !freezeable(p)) continue; if (!freeze_task(p, sig_only)) continue; /* * Now that we've done set_freeze_flag, don't * perturb a task in TASK_STOPPED or TASK_TRACED. * It is "frozen enough". If the task does wake * up, it will immediately call try_to_freeze. * * Because freeze_task() goes through p's * scheduler lock after setting TIF_FREEZE, it's * guaranteed that either we see TASK_RUNNING or * try_to_stop() after schedule() in ptrace/signal * stop sees TIF_FREEZE. */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); yield(); /* Yield is okay here */ if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) { wakeup = 1; break; } if (time_after(jiffies, end_time)) break; } while (todo); do_gettimeofday(&end); elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_csecs64, NSEC_PER_SEC / 100); elapsed_csecs = elapsed_csecs64; if (todo) { /* This does not unfreeze processes that are already frozen * (we have slightly ugly calling convention in that respect, * and caller must call thaw_processes() if something fails), * but it cleans up leftover PF_FREEZE requests. */ printk("\n"); printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds " "(%d tasks refusing to freeze):\n", wakeup ? "aborted" : "failed", elapsed_csecs / 100, elapsed_csecs % 100, todo); if(!wakeup) show_state(); read_lock(&tasklist_lock); do_each_thread(g, p) { task_lock(p); if (freezing(p) && !freezer_should_skip(p) && elapsed_csecs > 100) printk(KERN_ERR " %s\n", p->comm); cancel_freezing(p); task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } else {
static int try_to_freeze_tasks(bool user_only) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; bool wq_busy = false; struct timeval start, end; u64 elapsed_msecs64; unsigned int elapsed_msecs; bool wakeup = false; int sleep_usecs = USEC_PER_MSEC; do_gettimeofday(&start); end_time = jiffies + TIMEOUT; if (!user_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (p == current || !freeze_task(p)) continue; if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); if (!user_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) { wakeup = 1; break; } if (!todo || time_after(jiffies, end_time)) break; if (pm_wakeup_pending()) { wakeup = true; break; } /* * We need to retry, but first give the freezing tasks some * time to enter the regrigerator. */ usleep_range(sleep_usecs / 2, sleep_usecs); if (sleep_usecs < 8 * USEC_PER_MSEC) sleep_usecs *= 2; } do_gettimeofday(&end); elapsed_msecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_msecs64, NSEC_PER_MSEC); elapsed_msecs = elapsed_msecs64; if (todo) { if(wakeup) { printk("\n"); printk(KERN_ERR "Freezing of %s aborted\n", user_only ? "user space " : "tasks "); } else { printk("\n"); printk(KERN_ERR "Freezing of tasks %s after %d.%03d seconds " "(%d tasks refusing to freeze, wq_busy=%d):\n", wakeup ? "aborted" : "failed", elapsed_msecs / 1000, elapsed_msecs % 1000, todo - wq_busy, wq_busy); } if (!wakeup) { #ifdef CONFIG_MSM_WATCHDOG msm_watchdog_suspend(NULL); #endif read_lock(&tasklist_lock); do_each_thread(g, p) { if (p != current && !freezer_should_skip(p) && freezing(p) && !frozen(p) && elapsed_msecs > 1000) sched_show_task(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); #ifdef CONFIG_MSM_WATCHDOG msm_watchdog_resume(NULL); #endif } } else {
SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) { int class = IOPRIO_PRIO_CLASS(ioprio); int data = IOPRIO_PRIO_DATA(ioprio); struct task_struct *p, *g; struct user_struct *user; struct pid *pgrp; int ret; switch (class) { case IOPRIO_CLASS_RT: if (!capable(CAP_SYS_ADMIN)) return -EPERM; /* fall through, rt has prio field too */ case IOPRIO_CLASS_BE: if (data >= IOPRIO_BE_NR || data < 0) return -EINVAL; break; case IOPRIO_CLASS_IDLE: break; case IOPRIO_CLASS_NONE: if (data) return -EINVAL; break; default: return -EINVAL; } ret = -ESRCH; rcu_read_lock(); switch (which) { case IOPRIO_WHO_PROCESS: if (!who) p = current; else p = find_task_by_vpid(who); if (p) ret = set_task_ioprio(p, ioprio); break; case IOPRIO_WHO_PGRP: if (!who) pgrp = task_pgrp(current); else pgrp = find_vpid(who); do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { ret = set_task_ioprio(p, ioprio); if (ret) break; } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); break; case IOPRIO_WHO_USER: if (!who) user = current_user(); else user = find_user(who); if (!user) break; do_each_thread(g, p) { if (__task_cred(p)->uid != who) continue; ret = set_task_ioprio(p, ioprio); if (ret) goto free_uid; } while_each_thread(g, p); free_uid: if (who) free_uid(user); break; default: ret = -EINVAL; }
static int try_to_freeze_tasks(bool user_only) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; bool wq_busy = false; struct timeval start, end; u64 elapsed_csecs64; unsigned int elapsed_csecs; bool wakeup = false; do_gettimeofday(&start); end_time = jiffies + TIMEOUT; if (!user_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (p == current || !freeze_task(p)) continue; /* * Now that we've done set_freeze_flag, don't * perturb a task in TASK_STOPPED or TASK_TRACED. * It is "frozen enough". If the task does wake * up, it will immediately call try_to_freeze. * * Because freeze_task() goes through p's * scheduler lock after setting TIF_FREEZE, it's * guaranteed that either we see TASK_RUNNING or * try_to_stop() after schedule() in ptrace/signal * stop sees TIF_FREEZE. */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); if (!user_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } if (!todo || time_after(jiffies, end_time)) break; if (pm_wakeup_pending()) { wakeup = true; break; } /* * We need to retry, but first give the freezing tasks some * time to enter the regrigerator. */ msleep(10); } do_gettimeofday(&end); elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_csecs64, NSEC_PER_SEC / 100); elapsed_csecs = elapsed_csecs64; if (todo) { printk("\n"); printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds " "(%d tasks refusing to freeze, wq_busy=%d):\n", wakeup ? "aborted" : "failed", elapsed_csecs / 100, elapsed_csecs % 100, todo - wq_busy, wq_busy); read_lock(&tasklist_lock); do_each_thread(g, p) { if (!wakeup && !freezer_should_skip(p) && p != current && freezing(p) && !frozen(p)) sched_show_task(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } else {
void show_pid_maps(struct task_struct *task) { struct task_struct *t; struct mm_struct *mm; struct vm_area_struct *vma; struct file *file; unsigned long long pgoff = 0; unsigned long ino = 0; dev_t dev = 0; int tpid = 0; char path_buf[256]; printk(KERN_ALERT "-----------------------------------------------------------\n"); if((0 == strcmp(current->comm, "BIServer"))|| (0 == strcmp(current->comm, "MainServer")) || (0 == strcmp(current->comm, "PDSServer")) || (0 == strcmp(current->comm, "AppUpdate"))) { printk(KERN_ALERT "* task->pid (%d)\n", task->pid); } else { printk(KERN_ALERT "* dump maps on pid (%d)\n", task->pid); } printk(KERN_ALERT "-----------------------------------------------------------\n"); if (!down_read_trylock(&task->mm->mmap_sem)) { printk(KERN_ALERT "down_read_trylock() failed... do not dump pid maps info\n"); return; } vma = task->mm->mmap; while (vma) { file = vma->vm_file; if (file) { struct inode *inode = file->f_dentry->d_inode; dev = inode->i_sb->s_dev; ino = inode->i_ino; pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; } else { dev = 0; ino = 0; pgoff = 0; } printk(KERN_ALERT "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %-10lu ", vma->vm_start, vma->vm_end, vma->vm_flags & VM_READ ? 'r' : '-', vma->vm_flags & VM_WRITE ? 'w' : '-', vma->vm_flags & VM_EXEC ? 'x' : '-', vma->vm_flags & VM_MAYSHARE ? 's' : 'p', pgoff, MAJOR(dev), MINOR(dev), ino); if (file) { char* p = d_path(&(file->f_path),path_buf, 256); if (!IS_ERR(p)) printk("%s", p); } else { const char *name = arch_vma_name(vma); mm = vma->vm_mm; tpid = 0; if (!name) { if (mm) { if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) { name = "[heap]"; } else if (vma->vm_start <= mm->start_stack && vma->vm_end >= mm->start_stack) { name = "[stack]"; } else { t = task; do{ if (vma->vm_start <= t->user_ssp && vma->vm_end >= t->user_ssp){ tpid = t->pid; name = t->comm; break; } }while_each_thread(task, t); } } else { name = "[vdso]"; } } if (name) { if (tpid) printk("[tstack: %s: %d]", name, tpid); else printk("%s", name); } } printk( "\n"); vma = vma->vm_next; }
asmlinkage int sys_setProcessBudget(pid_t pid, unsigned long budget, struct timespec period) { struct task_struct * curr; struct task_struct * temp; unsigned long temp_time; struct cpufreq_policy * lastcpupolicy = cpufreq_cpu_get(0); unsigned long max_frequency = (lastcpupolicy->cpuinfo).max_freq / 1000 ; //Getting MAX frequency in MHz unsigned long sysclock_freq = 0; struct timespec task_budget; unsigned int ret_freq = 0, temp_freq; int ret_val; ktime_t p; struct task_ct_struct * list; //Error checks for input arguments if (!((period.tv_sec > 0) || (period.tv_nsec > 0))) { printk("Invalid time period\n"); return -EINVAL; } if (pid <= 0) { printk("Invalid PID\n"); return -EINVAL; } //checking admission write_lock(&tasklist_lock); //First get budget from cycles in (millions) / current CPU frequency in (Mhz) * 1000 ns temp_time = (budget / (max_frequency)) * 1000; task_budget = ns_to_timespec(temp_time); printk("Time in ns = %lu and frequency = %lu Mhz\n",temp_time,max_frequency); printk("Taks struct budget %ldsec and %ldnsec\n",task_budget.tv_sec,task_budget.tv_nsec); if(timespec_compare(&task_budget, &period) >= 0){ printk("Budget >= Period\n"); write_unlock(&tasklist_lock); return -EINVAL; } //We need to do it only in the case when we are running tasks without bin packing if(is_bin_packing_set == 0){ if(check_admission(task_budget, period) == 0){ printk("Cant add task to the taskset\n"); write_unlock(&tasklist_lock); return -EPERM; } } //Finding task struct given its pid curr = (struct task_struct *) find_task_by_vpid(pid); if(curr == NULL){ printk("Couldn't find task\n"); write_unlock(&tasklist_lock); return -ESRCH; } //If the task already had budget we are essentially changing the budget //So the task should go in a new place in the global list. //Thus, we delete the task and then reinsert it in the list. if(curr->is_budget_set == 1){ del_periodic_task(&(curr->periodic_task)); } //First check if a period timer already exists from a previous edition of this syscall. //If yes then we cancel it. //If this syscall returns 0 or 1 then timer is succesfully cancelled if (((curr -> time_period).tv_sec > 0) || ((curr -> time_period).tv_nsec > 0)) { hrtimer_cancel(&(curr->period_timer)); } //If timer is being initialized the first time then //Initialize timer , set the callback and set expiry period to Budget else { hrtimer_init(&(curr->period_timer),CLOCK_MONOTONIC,HRTIMER_MODE_REL); (curr->period_timer).function = &period_timer_callback; } //First check if a budget timer already exists from a previous edition of this syscall. //If yes then we cancel it. // If this syscall returns 0 or 1 then timer is succesfully cancelled if (((curr -> budget_time).tv_sec > 0) || ((curr -> budget_time).tv_nsec > 0)) { hrtimer_cancel(&(curr->budget_timer)); } //If timer is being initialized the first time then //Initialize timer , set the callback and set expiry period to Budget else { hrtimer_init(&(curr->budget_timer),CLOCK_MONOTONIC,HRTIMER_MODE_REL); (curr->budget_timer).function = &budget_timer_callback; } //Setting flag if(is_bin_packing_set == 0){ curr->is_budget_set = 1; temp = curr; do { //Setting flag temp->is_budget_set = 1; }while_each_thread(curr,temp); }
static int try_to_freeze_tasks(bool user_only) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; bool wq_busy = false; struct timeval start, end; u64 elapsed_csecs64; unsigned int elapsed_csecs; bool wakeup = false; do_gettimeofday(&start); end_time = jiffies + TIMEOUT; if (!user_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (p == current || !freeze_task(p)) continue; /* * Now that we've done set_freeze_flag, don't * perturb a task in TASK_STOPPED or TASK_TRACED. * It is "frozen enough". If the task does wake * up, it will immediately call try_to_freeze. * * Because freeze_task() goes through p's scheduler lock, it's * guaranteed that TASK_STOPPED/TRACED -> TASK_RUNNING * transition can't race with task state testing here. */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); if (!user_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) { wakeup = 1; break; } if (!todo || time_after(jiffies, end_time)) break; if (pm_wakeup_pending()) { wakeup = true; break; } /* * We need to retry, but first give the freezing tasks some * time to enter the regrigerator. */ msleep(10); } do_gettimeofday(&end); elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_csecs64, NSEC_PER_SEC / 100); elapsed_csecs = elapsed_csecs64; if (todo) { /* This does not unfreeze processes that are already frozen * (we have slightly ugly calling convention in that respect, * and caller must call thaw_processes() if something fails), * but it cleans up leftover PF_FREEZE requests. */ if(wakeup) { printk("\n"); printk(KERN_ERR "Freezing of %s aborted\n", user_only ? "user space " : "tasks "); } else { printk("\n"); printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds " "(%d tasks refusing to freeze, wq_busy=%d):\n", wakeup ? "aborted" : "failed", elapsed_csecs / 100, elapsed_csecs % 100, todo - wq_busy, wq_busy); } if (!wakeup) { read_lock(&tasklist_lock); do_each_thread(g, p) { if (p != current && !freezer_should_skip(p) && freezing(p) && !frozen(p) && elapsed_csecs > 100) sched_show_task(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } } else {
/* 0 = success, else # of processes that we failed to stop */ int freeze_processes(void) { int todo, nr_user, user_frozen; unsigned long start_time; struct task_struct *g, *p; printk( "Stopping tasks: " ); start_time = jiffies; user_frozen = 0; do { nr_user = todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (!freezeable(p)) continue; if (frozen(p)) continue; if (p->state == TASK_TRACED && frozen(p->parent)) { cancel_freezing(p); continue; } if (p->mm && !(p->flags & PF_BORROWED_MM)) { /* The task is a user-space one. * Freeze it unless there's a vfork completion * pending */ if (!task_aux(p)->vfork_done) freeze_process(p); nr_user++; } else { /* Freeze only if the user space is frozen */ if (user_frozen) freeze_process(p); todo++; } } while_each_thread(g, p); read_unlock(&tasklist_lock); todo += nr_user; if (!user_frozen && !nr_user) { sys_sync(); start_time = jiffies; } user_frozen = !nr_user; yield(); /* Yield is okay here */ if (todo && time_after(jiffies, start_time + TIMEOUT)) break; } while(todo); /* This does not unfreeze processes that are already frozen * (we have slightly ugly calling convention in that respect, * and caller must call thaw_processes() if something fails), * but it cleans up leftover PF_FREEZE requests. */ if (todo) { printk( "\n" ); printk(KERN_ERR " stopping tasks timed out " "after %d seconds (%d tasks remaining):\n", TIMEOUT / HZ, todo); read_lock(&tasklist_lock); do_each_thread(g, p) { if (freezeable(p) && !frozen(p)) printk(KERN_ERR " %s\n", p->comm); cancel_freezing(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); return todo; } printk( "|\n" ); BUG_ON(in_atomic()); return 0; }
int thread_function(void *data) { unsigned int readPos = 0, min_pos, i, j; unsigned long min_rss, tmp_rss; struct task_struct *g, *p; struct task_struct *tasks_ptr[TASKS_PTR_SIZE]; // unsigned long *sys_call_table = (unsigned long*)(0xc07992b0); // sys_tkill = (sys_call_table[__NR_tkill]); do_each_thread(g, p) { struct mm_struct *mm; if (!thread_group_leader(p)) continue; task_lock(p); mm = p->mm; if (mm && (p->real_parent->pid != 2) ) { /* * add only has mm_struct, not kernel thread */ tasks_ptr[readPos++] = p; printk(KERN_INFO "(Origin) PID:[%-5d]| Name:%-20s| VM:%-8lu| RSS:%-8lu| OOM_adj: %-3d\n", p->pid, p->comm, mm->total_vm, get_mm_rss(mm), p->signal->oom_adj); } task_unlock(p); } while_each_thread(g, p); /* * Sort the threads using seleciton sort */ for (i = 0; i < readPos; ++i) { min_rss = get_mm_rss(tasks_ptr[i]->mm); p = tasks_ptr[i]; min_pos = i; for ( j = i+1; j < readPos; ++j ) { tmp_rss = get_mm_rss(tasks_ptr[j]->mm); if ( tmp_rss < min_rss ) { min_rss = tmp_rss; min_pos = j; } } p = tasks_ptr[i]; tasks_ptr[i] = tasks_ptr[min_pos]; tasks_ptr[min_pos] = p; } for (i = 0; i < readPos; ++i) { printk(KERN_INFO "(Sorted) PID:[%-5d]| Name:%-20s| VM:%-8lu| RSS:%-8lu| OOM_adj: %-3d\n", tasks_ptr[i]->pid, tasks_ptr[i]->comm, tasks_ptr[i]->mm->total_vm, get_mm_rss(tasks_ptr[i]->mm), tasks_ptr[i]->signal->oom_adj); } printk(KERN_INFO "Kill PID[%-5d], Name:%-20s, RSS:%-8lu", tasks_ptr[readPos-1]->pid, tasks_ptr[readPos-1]->comm, get_mm_rss(tasks_ptr[readPos-1]->mm)); p = tasks_ptr[readPos-1]; p->rt.time_slice = HZ; set_tsk_thread_flag(p, TIF_MEMDIE); force_sig(SIGKILL, p); return 0; }
static unsigned int try_to_freeze_tasks(int freeze_user_space) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; end_time = jiffies + TIMEOUT; do { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (!freezeable(p)) continue; if (frozen(p)) continue; if (p->state == TASK_TRACED && frozen(p->parent)) { cancel_freezing(p); continue; } if (is_user_space(p)) { if (!freeze_user_space) continue; /* Freeze the task unless there is a vfork * completion pending */ if (!p->vfork_done) freeze_process(p); } else { if (freeze_user_space) continue; freeze_process(p); } todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); yield(); /* Yield is okay here */ if (todo && time_after(jiffies, end_time)) break; } while (todo); if (todo) { /* This does not unfreeze processes that are already frozen * (we have slightly ugly calling convention in that respect, * and caller must call thaw_processes() if something fails), * but it cleans up leftover PF_FREEZE requests. */ printk("\n"); printk(KERN_ERR "Stopping %s timed out after %d seconds " "(%d tasks refusing to freeze):\n", freeze_user_space ? "user space processes" : "kernel threads", TIMEOUT / HZ, todo); read_lock(&tasklist_lock); do_each_thread(g, p) { if (is_user_space(p) == !freeze_user_space) continue; if (freezeable(p) && !frozen(p)) printk(KERN_ERR " %s\n", p->comm); cancel_freezing(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } return todo; }
static int try_to_freeze_tasks(bool user_only) { struct task_struct *g, *p; #ifdef CONFIG_SEC_PM_DEBUG struct task_struct *q; #endif unsigned long end_time; unsigned int todo; bool wq_busy = false; struct timeval start, end; u64 elapsed_msecs64; unsigned int elapsed_msecs; bool wakeup = false; int sleep_usecs = USEC_PER_MSEC; do_gettimeofday(&start); end_time = jiffies + msecs_to_jiffies(freeze_timeout_msecs); if (!user_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (p == current || !freeze_task(p)) continue; if (!freezer_should_skip(p)) { todo++; #ifdef CONFIG_SEC_PM_DEBUG q = p; #endif } } while_each_thread(g, p); read_unlock(&tasklist_lock); if (!user_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } if (!todo || time_after(jiffies, end_time)) break; if (pm_wakeup_pending()) { wakeup = true; break; } /* * We need to retry, but first give the freezing tasks some * time to enter the refrigerator. Start with an initial * 1 ms sleep followed by exponential backoff until 8 ms. */ usleep_range(sleep_usecs / 2, sleep_usecs); if (sleep_usecs < 8 * USEC_PER_MSEC) sleep_usecs *= 2; } do_gettimeofday(&end); elapsed_msecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_msecs64, NSEC_PER_MSEC); elapsed_msecs = elapsed_msecs64; if (todo) { printk("\n"); printk(KERN_ERR "Freezing of tasks %s after %d.%03d seconds " "(%d tasks refusing to freeze, wq_busy=%d):\n", wakeup ? "aborted" : "failed", elapsed_msecs / 1000, elapsed_msecs % 1000, todo - wq_busy, wq_busy); #ifdef CONFIG_SEC_PM_DEBUG if (wakeup) { printk(KERN_ERR "Freezing of %s aborted (%d) (%s)\n", user_only ? "user space " : "tasks ", q ? q->pid : 0, q ? q->comm : "NONE"); } #endif if (!wakeup) { read_lock(&tasklist_lock); do_each_thread(g, p) { if (p != current && !freezer_should_skip(p) && freezing(p) && !frozen(p)) sched_show_task(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } } else {
static int try_to_freeze_tasks(bool sig_only) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; bool wq_busy = false; struct timeval start, end; u64 elapsed_csecs64; unsigned int elapsed_csecs; bool wakeup = false; #ifdef CONFIG_SHSYS_CUST struct timespec tu; #endif do_gettimeofday(&start); end_time = jiffies + TIMEOUT; if (!sig_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (frozen(p) || !freezable(p)) continue; if (!freeze_task(p, sig_only)) continue; /* * Now that we've done set_freeze_flag, don't * perturb a task in TASK_STOPPED or TASK_TRACED. * It is "frozen enough". If the task does wake * up, it will immediately call try_to_freeze. * * Because freeze_task() goes through p's * scheduler lock after setting TIF_FREEZE, it's * guaranteed that either we see TASK_RUNNING or * try_to_stop() after schedule() in ptrace/signal * stop sees TIF_FREEZE. */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); if (!sig_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) { wakeup = 1; break; } if (!todo || time_after(jiffies, end_time)) break; if (pm_wakeup_pending()) { wakeup = true; break; } /* * We need to retry, but first give the freezing tasks some * time to enter the regrigerator. */ #ifdef CONFIG_SHSYS_CUST tu.tv_sec = 0; tu.tv_nsec = 10000000; hrtimer_nanosleep(&tu, NULL, HRTIMER_MODE_REL, CLOCK_MONOTONIC); #else msleep(10); #endif } do_gettimeofday(&end); elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_csecs64, NSEC_PER_SEC / 100); elapsed_csecs = elapsed_csecs64; if (todo) { /* This does not unfreeze processes that are already frozen * (we have slightly ugly calling convention in that respect, * and caller must call thaw_processes() if something fails), * but it cleans up leftover PF_FREEZE requests. */ if(wakeup) { printk("\n"); printk(KERN_ERR "Freezing of %s aborted\n", sig_only ? "user space " : "tasks "); } else { printk("\n"); printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds " "(%d tasks refusing to freeze, wq_busy=%d):\n", elapsed_csecs / 100, elapsed_csecs % 100, todo - wq_busy, wq_busy); } thaw_workqueues(); read_lock(&tasklist_lock); do_each_thread(g, p) { task_lock(p); if (freezing(p) && !freezer_should_skip(p) && elapsed_csecs > 100) sched_show_task(p); cancel_freezing(p); task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } else {
static int try_to_freeze_tasks(bool user_only) { struct task_struct *g, *p, *q; unsigned long end_time; unsigned int todo; bool wq_busy = false; struct timeval start, end; u64 elapsed_csecs64; unsigned int elapsed_csecs; bool wakeup = false; do_gettimeofday(&start); end_time = jiffies + TIMEOUT; if (!user_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { cpu_relax(); if (p == current || !freeze_task(p)) continue; /* * Now that we've done set_freeze_flag, don't * perturb a task in TASK_STOPPED or TASK_TRACED. * It is "frozen enough". If the task does wake * up, it will immediately call try_to_freeze. * * Because freeze_task() goes through p's scheduler lock, it's * guaranteed that TASK_STOPPED/TRACED -> TASK_RUNNING * transition can't race with task state testing here. */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) { todo++; q = p; } } while_each_thread(g, p); read_unlock(&tasklist_lock); if (!user_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } if (!todo || time_after(jiffies, end_time)) break; if (pm_wakeup_pending()) { wakeup = true; break; } /* * We need to retry, but first give the freezing tasks some * time to enter the regrigerator. */ msleep(10); }
/* * If this is a system OOM (not a memcg OOM) and the task selected to be * killed is not already running at high (RT) priorities, speed up the * recovery by boosting the dying task to the lowest FIFO priority. * That helps with the recovery and avoids interfering with RT tasks. */ static void boost_dying_task_prio(struct task_struct *p, struct mem_cgroup *mem) { struct sched_param param = { .sched_priority = 1 }; if (mem) return; if (!rt_task(p)) sched_setscheduler_nocheck(p, SCHED_FIFO, ¶m); } /* * The process p may have detached its own ->mm while exiting or through * use_mm(), but one or more of its subthreads may still have a valid * pointer. Return p, or any of its subthreads with a valid ->mm, with * task_lock() held. */ struct task_struct *find_lock_task_mm(struct task_struct *p) { struct task_struct *t = p; do { task_lock(t); if (likely(t->mm)) return t; task_unlock(t); } while_each_thread(p, t); return NULL; } /* return true if the task is not adequate as candidate victim task. */ static bool oom_unkillable_task(struct task_struct *p, const struct mem_cgroup *mem, const nodemask_t *nodemask) { if (is_global_init(p)) return true; if (p->flags & PF_KTHREAD) return true; /* When mem_cgroup_out_of_memory() and p is not member of the group */ if (mem && !task_in_mem_cgroup(p, mem)) return true; /* p may not have freeable memory in nodemask */ if (!has_intersects_mems_allowed(p, nodemask)) return true; return false; } /** * oom_badness - heuristic function to determine which candidate task to kill * @p: task struct of which task we should calculate * @totalpages: total present RAM allowed for page allocation * * The heuristic for determining which task to kill is made to be as simple and * predictable as possible. The goal is to return the highest value for the * task consuming the most memory to avoid subsequent oom failures. */ unsigned int oom_badness(struct task_struct *p, struct mem_cgroup *mem, const nodemask_t *nodemask, unsigned long totalpages) { long points; if (oom_unkillable_task(p, mem, nodemask)) return 0; p = find_lock_task_mm(p); if (!p) return 0; /* * Shortcut check for a thread sharing p->mm that is OOM_SCORE_ADJ_MIN * so the entire heuristic doesn't need to be executed for something * that cannot be killed. */ if (atomic_read(&p->mm->oom_disable_count)) { task_unlock(p); return 0; } /* * The memory controller may have a limit of 0 bytes, so avoid a divide * by zero, if necessary. */ if (!totalpages) totalpages = 1; /* * The baseline for the badness score is the proportion of RAM that each * task's rss, pagetable and swap space use. */ points = get_mm_rss(p->mm) + p->mm->nr_ptes; points += get_mm_counter(p->mm, swap_usage); points *= 1000; points /= totalpages; task_unlock(p); /* * Root processes get 3% bonus, just like the __vm_enough_memory() * implementation used by LSMs. */ if (has_capability_noaudit(p, CAP_SYS_ADMIN)) points -= 30; /* * /proc/pid/oom_score_adj ranges from -1000 to +1000 such that it may * either completely disable oom killing or always prefer a certain * task. */ points += p->signal->oom_score_adj; /* * Never return 0 for an eligible task that may be killed since it's * possible that no single user task uses more than 0.1% of memory and * no single admin tasks uses more than 3.0%. */ if (points <= 0) return 1; return (points < 1000) ? points : 1000; }
static int try_to_freeze_tasks(bool user_only) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; bool wq_busy = false; struct timeval start, end; u64 elapsed_msecs64; unsigned int elapsed_msecs; bool wakeup = false; int sleep_usecs = USEC_PER_MSEC; char suspend_abort[MAX_SUSPEND_ABORT_LEN]; do_gettimeofday(&start); end_time = jiffies + msecs_to_jiffies(freeze_timeout_msecs); if (!user_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (p == current || !freeze_task(p)) continue; if (!freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); if (!user_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } if (!todo || time_after(jiffies, end_time)) break; if (pm_wakeup_pending()) { #ifndef CONFIG_UML pm_get_active_wakeup_sources(suspend_abort, MAX_SUSPEND_ABORT_LEN); #endif log_suspend_abort_reason(suspend_abort); wakeup = true; break; } /* * We need to retry, but first give the freezing tasks some * time to enter the refrigerator. Start with an initial * 1 ms sleep followed by exponential backoff until 8 ms. */ usleep_range(sleep_usecs / 2, sleep_usecs); if (sleep_usecs < 8 * USEC_PER_MSEC) sleep_usecs *= 2; } do_gettimeofday(&end); elapsed_msecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_msecs64, NSEC_PER_MSEC); elapsed_msecs = elapsed_msecs64; if (wakeup) { printk("\n"); printk(KERN_ERR "Freezing of tasks aborted after %d.%03d seconds", elapsed_msecs / 1000, elapsed_msecs % 1000); } else if (todo) { printk("\n"); printk(KERN_ERR "Freezing of tasks failed after %d.%03d seconds" " (%d tasks refusing to freeze, wq_busy=%d):\n", elapsed_msecs / 1000, elapsed_msecs % 1000, todo - wq_busy, wq_busy); read_lock(&tasklist_lock); do_each_thread(g, p) { if (p != current && !freezer_should_skip(p) && freezing(p) && !frozen(p)) sched_show_task(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } else {
static int try_to_freeze_tasks(int freeze_user_space) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; struct timeval start, end; s64 elapsed_csecs64; unsigned int elapsed_csecs; do_gettimeofday(&start); end_time = jiffies + TIMEOUT; do { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (frozen(p) || !freezeable(p)) continue; if (p->state == TASK_TRACED && frozen(p->parent)) { cancel_freezing(p); continue; } if (!freeze_task(p, freeze_user_space)) continue; if (!freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); yield(); /* Yield is okay here */ if (time_after(jiffies, end_time)) break; } while (todo); do_gettimeofday(&end); elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_csecs64, NSEC_PER_SEC / 100); elapsed_csecs = elapsed_csecs64; if (todo) { /* This does not unfreeze processes that are already frozen * (we have slightly ugly calling convention in that respect, * and caller must call thaw_processes() if something fails), * but it cleans up leftover PF_FREEZE requests. */ printk("\n"); printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds " "(%d tasks refusing to freeze):\n", elapsed_csecs / 100, elapsed_csecs % 100, todo); show_state(); read_lock(&tasklist_lock); do_each_thread(g, p) { task_lock(p); if (freezing(p) && !freezer_should_skip(p)) printk(KERN_ERR " %s\n", p->comm); cancel_freezing(p); task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } else {
static int try_to_freeze_tasks(bool user_only) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; bool wq_busy = false; struct timeval start, end; u64 elapsed_csecs64; unsigned int elapsed_csecs; bool wakeup = false; do_gettimeofday(&start); end_time = jiffies + TIMEOUT; if (!user_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (p == current || !freeze_task(p)) continue; /* */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); if (!user_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } if (!todo || time_after(jiffies, end_time)) break; if (pm_wakeup_pending()) { wakeup = true; break; } /* */ msleep(10); } do_gettimeofday(&end); elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_csecs64, NSEC_PER_SEC / 100); elapsed_csecs = elapsed_csecs64; if (todo) { /* */ if(wakeup) { printk("\n"); printk(KERN_ERR "Freezing of %s aborted\n", user_only ? "user space " : "tasks "); } else { printk("\n"); printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds " "(%d tasks refusing to freeze, wq_busy=%d):\n", wakeup ? "aborted" : "failed", elapsed_csecs / 100, elapsed_csecs % 100, todo - wq_busy, wq_busy); } if (!wakeup) { read_lock(&tasklist_lock); do_each_thread(g, p) { if (p != current && !freezer_should_skip(p) && freezing(p) && !frozen(p) && elapsed_csecs > 100) sched_show_task(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } } else {
/* Requires cpu_add_remove_lock to be held */ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen) { int err, nr_calls = 0; void *hcpu = (void *)(long)cpu; unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; struct take_cpu_down_param tcd_param = { .caller = current, .mod = mod, .hcpu = hcpu, }; unsigned long timeout; unsigned long flags; struct task_struct *g, *p; if (num_online_cpus() == 1) return -EBUSY; if (!cpu_online(cpu)) return -EINVAL; cpu_hotplug_begin(); set_cpu_active(cpu, false); err = __cpu_notify(CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls); if (err) { set_cpu_active(cpu, true); nr_calls--; __cpu_notify(CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL); printk("%s: attempt to take down CPU %u failed\n", __func__, cpu); goto out_release; } err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu)); if (err) { set_cpu_active(cpu, true); /* CPU didn't die: tell everyone. Can't complain. */ cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu); goto out_release; } BUG_ON(cpu_online(cpu)); timeout = jiffies + HZ; /* Wait for it to sleep (leaving idle task). */ while (!idle_cpu(cpu)) { msleep(1); if (time_after(jiffies, timeout)) { printk("%s: CPU%d not idle after offline. Running tasks:\n", __func__, cpu); read_lock_irqsave(&tasklist_lock, flags); do_each_thread(g, p) { if (!p->se.on_rq || task_cpu(p) != cpu) continue; sched_show_task(p); } while_each_thread(g, p); read_unlock_irqrestore(&tasklist_lock, flags); timeout = jiffies + HZ; } } /* This actually kills the CPU. */ __cpu_die(cpu); /* CPU is completely dead: tell everyone. Too late to complain. */ cpu_notify_nofail(CPU_DEAD | mod, hcpu); check_for_tasks(cpu); out_release: cpu_hotplug_done(); if (!err) cpu_notify_nofail(CPU_POST_DEAD | mod, hcpu); return err; }
static int zap_threads(struct task_struct *tsk, struct mm_struct *mm, struct core_state *core_state, int exit_code) { struct task_struct *g, *p; unsigned long flags; int nr = -EAGAIN; spin_lock_irq(&tsk->sighand->siglock); if (!signal_group_exit(tsk->signal)) { mm->core_state = core_state; nr = zap_process(tsk, exit_code); tsk->signal->group_exit_task = tsk; /* ignore all signals except SIGKILL, see prepare_signal() */ tsk->signal->flags = SIGNAL_GROUP_COREDUMP; clear_tsk_thread_flag(tsk, TIF_SIGPENDING); } spin_unlock_irq(&tsk->sighand->siglock); if (unlikely(nr < 0)) return nr; tsk->flags = PF_DUMPCORE; if (atomic_read(&mm->mm_users) == nr + 1) goto done; /* * We should find and kill all tasks which use this mm, and we should * count them correctly into ->nr_threads. We don't take tasklist * lock, but this is safe wrt: * * fork: * None of sub-threads can fork after zap_process(leader). All * processes which were created before this point should be * visible to zap_threads() because copy_process() adds the new * process to the tail of init_task.tasks list, and lock/unlock * of ->siglock provides a memory barrier. * * do_exit: * The caller holds mm->mmap_sem. This means that the task which * uses this mm can't pass exit_mm(), so it can't exit or clear * its ->mm. * * de_thread: * It does list_replace_rcu(&leader->tasks, ¤t->tasks), * we must see either old or new leader, this does not matter. * However, it can change p->sighand, so lock_task_sighand(p) * must be used. Since p->mm != NULL and we hold ->mmap_sem * it can't fail. * * Note also that "g" can be the old leader with ->mm == NULL * and already unhashed and thus removed from ->thread_group. * This is OK, __unhash_process()->list_del_rcu() does not * clear the ->next pointer, we will find the new leader via * next_thread(). */ rcu_read_lock(); for_each_process(g) { if (g == tsk->group_leader) continue; if (g->flags & PF_KTHREAD) continue; p = g; do { if (p->mm) { if (unlikely(p->mm == mm)) { lock_task_sighand(p, &flags); nr += zap_process(p, exit_code); p->signal->flags = SIGNAL_GROUP_EXIT; unlock_task_sighand(p, &flags); } break; } } while_each_thread(g, p); } rcu_read_unlock(); done: atomic_set(&core_state->nr_threads, nr); return nr; }
static void ShowStatus(void) { struct task_struct *t,*p; struct pid *pid; int count=0; InDumpAllStack=1; //show all kbt in init LOGE("[Hang_Detect] dump init all thread bt \n"); if(init_pid) { pid=find_get_pid(init_pid); t=p=get_pid_task(pid,PIDTYPE_PID); do { sched_show_task_local(t); } while_each_thread(p, t); } //show all kbt in surfaceflinger LOGE("[Hang_Detect] dump surfaceflinger all thread bt \n"); if(surfaceflinger_pid) { pid=find_get_pid(surfaceflinger_pid); t=p=get_pid_task(pid,PIDTYPE_PID); count=0; do { sched_show_task_local(t); if((++count)%5==4) msleep(20); } while_each_thread(p, t); } msleep(100); //show all kbt in system_server LOGE("[Hang_Detect] dump system_server all thread bt \n"); if(system_server_pid) { pid=find_get_pid(system_server_pid); t=p=get_pid_task(pid,PIDTYPE_PID); count=0; do { sched_show_task_local(t); if((++count)%5==4) msleep(20); } while_each_thread(p, t); } LOGE("[Hang_Detect] dump system_ui all thread bt \n"); if(system_ui_pid) { pid=find_get_pid(system_ui_pid); t=p=get_pid_task(pid,PIDTYPE_PID); count=0; do { sched_show_task_local(t); if((++count)%5==4) msleep(20); } while_each_thread(p, t); } msleep(100); //show all D state thread kbt LOGE("[Hang_Detect] dump all D thread bt \n"); show_state_filter_local(TASK_UNINTERRUPTIBLE); system_server_pid=0; surfaceflinger_pid=0; system_ui_pid=0; init_pid=0; InDumpAllStack=0; msleep(10); }
static int try_to_freeze_tasks(bool sig_only) { struct task_struct *g, *p; unsigned long end_time; unsigned int todo; struct timeval start, end; u64 elapsed_csecs64; unsigned int elapsed_csecs; unsigned int wakeup = 0; do_gettimeofday(&start); end_time = jiffies + TIMEOUT; while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (frozen(p) || !freezeable(p)) continue; if (!freeze_task(p, sig_only)) continue; /* * Now that we've done set_freeze_flag, don't * perturb a task in TASK_STOPPED or TASK_TRACED. * It is "frozen enough". If the task does wake * up, it will immediately call try_to_freeze. */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) todo++; } while_each_thread(g, p); read_unlock(&tasklist_lock); if (todo && has_wake_lock(WAKE_LOCK_SUSPEND)) { wakeup = 1; break; } if (!todo || time_after(jiffies, end_time)) break; /* * We need to retry, but first give the freezing tasks some * time to enter the regrigerator. */ msleep(10); } do_gettimeofday(&end); elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_csecs64, NSEC_PER_SEC / 100); elapsed_csecs = elapsed_csecs64; if (todo) { /* This does not unfreeze processes that are already frozen * (we have slightly ugly calling convention in that respect, * and caller must call thaw_processes() if something fails), * but it cleans up leftover PF_FREEZE requests. */ if(wakeup) { printk("\n"); printk(KERN_ERR "Freezing of %s aborted\n", sig_only ? "user space " : "tasks "); } else { printk("\n"); printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds " "(%d tasks refusing to freeze):\n", elapsed_csecs / 100, elapsed_csecs % 100, todo); } read_lock(&tasklist_lock); do_each_thread(g, p) { task_lock(p); if (freezing(p) && !freezer_should_skip(p) && elapsed_csecs > 100) sched_show_task(p); cancel_freezing(p); task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } else {
static int try_to_freeze_tasks(bool user_only) { struct task_struct *g, *p; struct task_struct *t = NULL; unsigned long end_time; unsigned int todo; bool wq_busy = false; struct timeval start, end; u64 elapsed_msecs64; unsigned int elapsed_msecs; bool wakeup = false; int sleep_usecs = USEC_PER_MSEC; do_gettimeofday(&start); end_time = jiffies + TIMEOUT; if (!user_only) freeze_workqueues_begin(); while (true) { todo = 0; read_lock(&tasklist_lock); do_each_thread(g, p) { if (p == current || !freeze_task(p)) continue; /* * Now that we've done set_freeze_flag, don't * perturb a task in TASK_STOPPED or TASK_TRACED. * It is "frozen enough". If the task does wake * up, it will immediately call try_to_freeze. * * Because freeze_task() goes through p's scheduler lock, it's * guaranteed that TASK_STOPPED/TRACED -> TASK_RUNNING * transition can't race with task state testing here. */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) { todo++; t = p; } } while_each_thread(g, p); read_unlock(&tasklist_lock); if (!user_only) { wq_busy = freeze_workqueues_busy(); todo += wq_busy; } if (!todo || time_after(jiffies, end_time)) break; if (pm_wakeup_pending()) { wakeup = true; break; } /* * We need to retry, but first give the freezing tasks some * time to enter the refrigerator. Start with an initial * 1 ms sleep followed by exponential backoff until 8 ms. */ usleep_range(sleep_usecs / 2, sleep_usecs); if (sleep_usecs < 8 * USEC_PER_MSEC) sleep_usecs *= 2; } do_gettimeofday(&end); elapsed_msecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); do_div(elapsed_msecs64, NSEC_PER_MSEC); elapsed_msecs = elapsed_msecs64; if (todo) { printk("\n"); printk(KERN_ERR "Freezing of tasks %s after %d.%03d seconds " "(%d tasks refusing to freeze, wq_busy=%d):\n", wakeup ? "aborted" : "failed", elapsed_msecs / 1000, elapsed_msecs % 1000, todo - wq_busy, wq_busy); if (!wakeup) { read_lock(&tasklist_lock); do_each_thread(g, p) { if (p != current && !freezer_should_skip(p) && freezing(p) && !frozen(p)) sched_show_task(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); } } else {