void xacct_add_tsk(struct taskstats *stats, struct task_struct *p)
{
	struct mm_struct *mm;

	
	stats->coremem = p->acct_rss_mem1 * PAGE_SIZE / MB;
	stats->virtmem = p->acct_vm_mem1 * PAGE_SIZE / MB;
	mm = get_task_mm(p);
	if (mm) {
		
		stats->hiwater_rss   = get_mm_hiwater_rss(mm) * PAGE_SIZE / KB;
		stats->hiwater_vm    = get_mm_hiwater_vm(mm)  * PAGE_SIZE / KB;
		mmput(mm);
	}
	stats->read_char	= p->ioac.rchar & KB_MASK;
	stats->write_char	= p->ioac.wchar & KB_MASK;
	stats->read_syscalls	= p->ioac.syscr & KB_MASK;
	stats->write_syscalls	= p->ioac.syscw & KB_MASK;
#ifdef CONFIG_TASK_IO_ACCOUNTING
	stats->read_bytes	= p->ioac.read_bytes & KB_MASK;
	stats->write_bytes	= p->ioac.write_bytes & KB_MASK;
	stats->cancelled_write_bytes = p->ioac.cancelled_write_bytes & KB_MASK;
#else
	stats->read_bytes	= 0;
	stats->write_bytes	= 0;
	stats->cancelled_write_bytes = 0;
#endif
}
Esempio n. 2
0
/*
 * fill in extended accounting fields
 */
void xacct_add_tsk(struct taskstats *stats, struct task_struct *p)
{
	struct mm_struct *mm;

	/* convert pages-usec to Mbyte-usec */
	stats->coremem = p->acct_rss_mem1 * PAGE_SIZE / MB;
	stats->virtmem = p->acct_vm_mem1 * PAGE_SIZE / MB;
	mm = get_task_mm(p);
	if (mm) {
		/* adjust to KB unit */
		stats->hiwater_rss   = get_mm_hiwater_rss(mm) * PAGE_SIZE / KB;
		stats->hiwater_vm    = get_mm_hiwater_vm(mm)  * PAGE_SIZE / KB;
		mmput(mm);
	}
	stats->read_char	= p->ioac.rchar;
	stats->write_char	= p->ioac.wchar;
	stats->read_syscalls	= p->ioac.syscr;
	stats->write_syscalls	= p->ioac.syscw;
#ifdef CONFIG_TASK_IO_ACCOUNTING
	stats->read_bytes	= p->ioac.read_bytes;
	stats->write_bytes	= p->ioac.write_bytes;
	stats->cancelled_write_bytes = p->ioac.cancelled_write_bytes;
#else
	stats->read_bytes	= 0;
	stats->write_bytes	= 0;
	stats->cancelled_write_bytes = 0;
#endif
}
static void lowmem_vm_shrinker(int largest, int rss_threshold)
{
       struct task_struct *p;
       struct task_struct *selected = NULL;
       int vmsize, rssize;
       int min_adj, min_large_adj;
       int selected_vmsize = 0;
       int selected_oom_adj;
       int array_size = ARRAY_SIZE(lowmem_adj);
       unsigned long flags;

       /*
        * 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)
               return;

       if (lowmem_adj_size < array_size)
               array_size = lowmem_adj_size;
       if (lowmem_minfree_size < array_size)
               array_size = lowmem_minfree_size;

       min_adj = lowmem_adj[array_size - 2];  /* lock onto cached processes only */
       min_large_adj = lowmem_adj[array_size - 3];  /* Minimum priority for large processes */

       lowmem_print(3, "lowmem_vm_shrink ma %d, large ma %d, largest %d, rss_threshold=%d\n",
                     min_adj, min_large_adj, largest, rss_threshold);

       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;
               vmsize = get_mm_hiwater_vm(mm);
                rssize = get_mm_rss(mm) * PAGE_SIZE;
               task_unlock(p);

               if (vmsize <= 0)
                       continue;

                /* Only look at cached processes */
                if (oom_adj < min_adj) {
                    /* Is this a very large home process in the background? */
                    if ((oom_adj > min_large_adj) && (rssize >= rss_threshold)) {
                        selected = p;
                        selected_vmsize = vmsize;
                       selected_oom_adj = oom_adj;
                        lowmem_print(2, "lowmem_shrink override %d (%s), adj %d, vm size %d, rs size %d to kill\n" ,p->pid, p->comm, oom_adj, vmsize, rssize);
                        break;
                    }

                    continue;
                }

                /* Is this process a better fit than last selected? */
               if (selected) {
                       if (oom_adj < selected_oom_adj)
                               continue;

                        /* If looking for largest, ignore priority */
                       if ((largest || (oom_adj == selected_oom_adj)) &&
                           (vmsize <= selected_vmsize))
                               continue;
               }

               selected = p;
               selected_vmsize = vmsize;

               if (largest == 0)  /* Do not filter by priority if searching for largest */
                       selected_oom_adj = oom_adj;

               lowmem_print(2, "lowmem_shrink select %d (%s), adj %d, vm size %d, rs size %d to kill\n",
                            p->pid, p->comm, oom_adj, vmsize, rssize);
       }
       if (selected) {
               spin_lock_irqsave(&lowmem_deathpending_lock, flags);
               if (!lowmem_deathpending) {
                       lowmem_print(1,
                               "lowmem_shrink send sigkill to %d (%s), adj %d, vm size %d\n",
                               selected->pid, selected->comm,
                               selected_oom_adj, selected_vmsize);
                       lowmem_deathpending = selected;
                       task_free_register(&task_nb);
                       force_sig(SIGKILL, selected);
               }
               spin_unlock_irqrestore(&lowmem_deathpending_lock, flags);
       }
       lowmem_print(4, "lowmem_vm_shrink, saved %d\n", selected_vmsize);
       read_unlock(&tasklist_lock);
       return;
}