[PATCH] accounting per process swapped out pages

From: Mulyadi Santosa
Date: Fri Aug 04 2006 - 02:51:04 EST


Hello everyone.

Here is patch to count per process swapped out pages. This patch is
created against 2.6.16.1. So far, I had tested by forcing certain task
to swap out (tail -f /dev/zero) and wait until top/vmstat/free reported
that swap is occupied.

Comments and feedbacks are greatly appreciated. Please keep me CC'ed
since I am not subscribed to linux-kernel mailing list.

regards,

Mulyadi


# diffstat ./swap-acct.patch
fs/proc/task_mmu.c | 14 ++++++++++++--
include/linux/mm.h | 1 +
mm/memory.c | 3 +++
mm/rmap.c | 1 +
mm/swapfile.c | 1 +
5 files changed, 18 insertions(+), 2 deletions(-)

--- fs/proc/task_mmu.c.bak 2006-03-28 13:49:02.000000000 +0700
+++ fs/proc/task_mmu.c 2006-07-22 19:18:33.000000000 +0700
@@ -15,6 +15,8 @@ char *task_mem(struct mm_struct *mm, cha
{
unsigned long data, text, lib;
unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;
+ struct vm_area_struct * this_vma;
+ unsigned long swp_out_pages=0;

/*
* Note: to minimize their overhead, mm maintains hiwater_vm and
@@ -33,6 +35,12 @@ char *task_mem(struct mm_struct *mm, cha
data = mm->total_vm - mm->shared_vm - mm->stack_vm;
text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text;
+
+ for(this_vma = mm->mmap;this_vma;this_vma = this_vma->vm_next)
+ {
+ swp_out_pages += atomic_read(&(this_vma)->swapped_out);
+ }
+
buffer += sprintf(buffer,
"VmPeak:\t%8lu kB\n"
"VmSize:\t%8lu kB\n"
@@ -43,7 +51,8 @@ char *task_mem(struct mm_struct *mm, cha
"VmStk:\t%8lu kB\n"
"VmExe:\t%8lu kB\n"
"VmLib:\t%8lu kB\n"
- "VmPTE:\t%8lu kB\n",
+ "VmPTE:\t%8lu kB\n"
+ "VmSwp:\t%8lu kB\n",
hiwater_vm << (PAGE_SHIFT-10),
(total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
mm->locked_vm << (PAGE_SHIFT-10),
@@ -51,7 +60,8 @@ char *task_mem(struct mm_struct *mm, cha
total_rss << (PAGE_SHIFT-10),
data << (PAGE_SHIFT-10),
mm->stack_vm << (PAGE_SHIFT-10), text, lib,
- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
+ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10,
+ swp_out_pages << (PAGE_SHIFT-10) );
return buffer;
}

--- include/linux/mm.h.bak 2006-03-28 13:49:02.000000000 +0700
+++ include/linux/mm.h 2006-07-22 19:20:34.000000000 +0700
@@ -111,6 +111,7 @@ struct vm_area_struct {
#ifdef CONFIG_NUMA
struct mempolicy *vm_policy; /* NUMA policy for the VMA */
#endif
+ atomic_t swapped_out; /* swapped out pages in this VMA */
};

/*
--- mm/rmap.c.bak 2006-03-28 13:49:02.000000000 +0700
+++ mm/rmap.c 2006-07-22 19:19:47.000000000 +0700
@@ -635,6 +635,7 @@ static int try_to_unmap_one(struct page
set_pte_at(mm, address, pte, swp_entry_to_pte(entry));
BUG_ON(pte_file(*pte));
dec_mm_counter(mm, anon_rss);
+ atomic_inc(&(vma)->swapped_out);
} else
dec_mm_counter(mm, file_rss);

--- mm/memory.c.bak 2006-03-28 13:49:02.000000000 +0700
+++ mm/memory.c 2006-07-25 16:04:42.000000000 +0700
@@ -683,6 +683,7 @@ static unsigned long zap_pte_range(struc
} while (pte++, addr += PAGE_SIZE, (addr != end && *zap_work > 0));

add_mm_rss(mm, file_rss, anon_rss);
+ atomic_sub(anon_rss,&(vma)->swapped_out);
pte_unmap_unlock(pte - 1, ptl);

return addr;
@@ -1928,6 +1929,8 @@ again:
/* The page isn't present yet, go ahead with the fault. */

inc_mm_counter(mm, anon_rss);
+ printk("Reducing swapped_out variable...\n");
+ atomic_dec(&(vma)->swapped_out);
pte = mk_pte(page, vma->vm_page_prot);
if (write_access && can_share_swap_page(page)) {
pte = maybe_mkwrite(pte_mkdirty(pte), vma);
--- mm/swapfile.c.bak 2006-07-25 18:25:57.000000000 +0700
+++ mm/swapfile.c 2006-07-25 18:43:17.000000000 +0700
@@ -426,6 +426,7 @@ static void unuse_pte(struct vm_area_str
unsigned long addr, swp_entry_t entry, struct page *page)
{
inc_mm_counter(vma->vm_mm, anon_rss);
+ atomic_dec(&(vma)->swapped_out);
get_page(page);
set_pte_at(vma->vm_mm, addr, pte,
pte_mkold(mk_pte(page, vma->vm_page_prot)));

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/