Re: [PATCH v2 5/6] mm: Support address range reclaim

2013-04-24 Thread Minchan Kim
Hey Namhyung,

On Wed, Apr 24, 2013 at 08:01:48PM +0900, Namhyung Kim wrote:
> Hi Minchan,
> 
> On Wed, 24 Apr 2013 10:41:03 +0900, Minchan Kim wrote:
> > This patch adds address range reclaim of a process.
> > The requirement is following as,
> >
> > Like webkit1, it uses a address space for handling multi tabs.
> > IOW, it uses *one* process model so all tabs shares address space
> > of the process. In such scenario, per-process reclaim is rather
> > coarse-grained so this patch supports more fine-grained reclaim
> > for being able to reclaim target address range of the process.
> > For reclaim target range, you should use following format.
> >
> > echo [addr] [size-byte] > /proc/pid/reclaim
> >
> > addr should be page-aligned.
> >
> > So now reclaim konb's interface is following as.
> >
> > echo file > /proc/pid/reclaim
> > reclaim file-backed pages only
> >
> > echo anon > /proc/pid/reclaim
> > reclaim anonymous pages only
> >
> > echo all > /proc/pid/reclaim
> > reclaim all pages
> >
> > echo $((1<<20)) 8192 > /proc/pid/reclaim
> > reclaim pages in (0x10 - 0x102000)
> >
> > Signed-off-by: Minchan Kim 
> > ---
> >  fs/proc/task_mmu.c | 88 
> > --
> >  mm/internal.h  |  3 ++
> >  2 files changed, 76 insertions(+), 15 deletions(-)
> >
> > diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
> > index 79b674e..dff9756 100644
> > --- a/fs/proc/task_mmu.c
> > +++ b/fs/proc/task_mmu.c
> > @@ -12,6 +12,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  
> >  #include 
> >  #include 
> > @@ -1239,11 +1240,14 @@ static ssize_t reclaim_write(struct file *file, 
> > const char __user *buf,
> > size_t count, loff_t *ppos)
> >  {
> > struct task_struct *task;
> > -   char buffer[PROC_NUMBUF];
> > +   char buffer[200];
> > struct mm_struct *mm;
> > struct vm_area_struct *vma;
> > enum reclaim_type type;
> > char *type_buf;
> > +   struct mm_walk reclaim_walk = {};
> > +   unsigned long start = 0;
> > +   unsigned long end = 0;
> >  
> > memset(buffer, 0, sizeof(buffer));
> > if (count > sizeof(buffer) - 1)
> > @@ -1259,42 +1263,96 @@ static ssize_t reclaim_write(struct file *file, 
> > const char __user *buf,
> > type = RECLAIM_ANON;
> > else if (!strcmp(type_buf, "all"))
> > type = RECLAIM_ALL;
> > +   else if (isdigit(*type_buf))
> > +   type = RECLAIM_RANGE;
> > else
> > -   return -EINVAL;
> > +   goto out_err;
> > +
> > +   if (type == RECLAIM_RANGE) {
> > +   int ret;
> > +   size_t len;
> > +   unsigned long len_in;
> > +   char *token;
> > +
> > +   token = strsep(&type_buf, " ");
> > +   if (!token)
> > +   goto out_err;
> > +   ret = kstrtoul(token, 10, &start);
> 
> Why not using
> 
>   start = memparse(token, NULL);
> 
> to support something like:
> 
>   # echo 0x10 8K > /proc/pid/reclaim
> 

Because I'm brain-damage. :(
Thanks for noticing useful function.

> 
> Thanks,
> Namhyung
> 
> --
> To unsubscribe, send a message with 'unsubscribe linux-mm' in
> the body to majord...@kvack.org.  For more info on Linux MM,
> see: http://www.linux-mm.org/ .
> Don't email: mailto:"d...@kvack.org";> em...@kvack.org 

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


Re: [PATCH v2 5/6] mm: Support address range reclaim

2013-04-24 Thread Namhyung Kim
Hi Minchan,

On Wed, 24 Apr 2013 10:41:03 +0900, Minchan Kim wrote:
> This patch adds address range reclaim of a process.
> The requirement is following as,
>
> Like webkit1, it uses a address space for handling multi tabs.
> IOW, it uses *one* process model so all tabs shares address space
> of the process. In such scenario, per-process reclaim is rather
> coarse-grained so this patch supports more fine-grained reclaim
> for being able to reclaim target address range of the process.
> For reclaim target range, you should use following format.
>
>   echo [addr] [size-byte] > /proc/pid/reclaim
>
> addr should be page-aligned.
>
> So now reclaim konb's interface is following as.
>
> echo file > /proc/pid/reclaim
>   reclaim file-backed pages only
>
> echo anon > /proc/pid/reclaim
>   reclaim anonymous pages only
>
> echo all > /proc/pid/reclaim
>   reclaim all pages
>
> echo $((1<<20)) 8192 > /proc/pid/reclaim
>   reclaim pages in (0x10 - 0x102000)
>
> Signed-off-by: Minchan Kim 
> ---
>  fs/proc/task_mmu.c | 88 
> --
>  mm/internal.h  |  3 ++
>  2 files changed, 76 insertions(+), 15 deletions(-)
>
> diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
> index 79b674e..dff9756 100644
> --- a/fs/proc/task_mmu.c
> +++ b/fs/proc/task_mmu.c
> @@ -12,6 +12,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> @@ -1239,11 +1240,14 @@ static ssize_t reclaim_write(struct file *file, const 
> char __user *buf,
>   size_t count, loff_t *ppos)
>  {
>   struct task_struct *task;
> - char buffer[PROC_NUMBUF];
> + char buffer[200];
>   struct mm_struct *mm;
>   struct vm_area_struct *vma;
>   enum reclaim_type type;
>   char *type_buf;
> + struct mm_walk reclaim_walk = {};
> + unsigned long start = 0;
> + unsigned long end = 0;
>  
>   memset(buffer, 0, sizeof(buffer));
>   if (count > sizeof(buffer) - 1)
> @@ -1259,42 +1263,96 @@ static ssize_t reclaim_write(struct file *file, const 
> char __user *buf,
>   type = RECLAIM_ANON;
>   else if (!strcmp(type_buf, "all"))
>   type = RECLAIM_ALL;
> + else if (isdigit(*type_buf))
> + type = RECLAIM_RANGE;
>   else
> - return -EINVAL;
> + goto out_err;
> +
> + if (type == RECLAIM_RANGE) {
> + int ret;
> + size_t len;
> + unsigned long len_in;
> + char *token;
> +
> + token = strsep(&type_buf, " ");
> + if (!token)
> + goto out_err;
> + ret = kstrtoul(token, 10, &start);

Why not using

start = memparse(token, NULL);

to support something like:

  # echo 0x10 8K > /proc/pid/reclaim


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


[PATCH v2 5/6] mm: Support address range reclaim

2013-04-23 Thread Minchan Kim
This patch adds address range reclaim of a process.
The requirement is following as,

Like webkit1, it uses a address space for handling multi tabs.
IOW, it uses *one* process model so all tabs shares address space
of the process. In such scenario, per-process reclaim is rather
coarse-grained so this patch supports more fine-grained reclaim
for being able to reclaim target address range of the process.
For reclaim target range, you should use following format.

echo [addr] [size-byte] > /proc/pid/reclaim

addr should be page-aligned.

So now reclaim konb's interface is following as.

echo file > /proc/pid/reclaim
reclaim file-backed pages only

echo anon > /proc/pid/reclaim
reclaim anonymous pages only

echo all > /proc/pid/reclaim
reclaim all pages

echo $((1<<20)) 8192 > /proc/pid/reclaim
reclaim pages in (0x10 - 0x102000)

Signed-off-by: Minchan Kim 
---
 fs/proc/task_mmu.c | 88 --
 mm/internal.h  |  3 ++
 2 files changed, 76 insertions(+), 15 deletions(-)

diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 79b674e..dff9756 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1239,11 +1240,14 @@ static ssize_t reclaim_write(struct file *file, const 
char __user *buf,
size_t count, loff_t *ppos)
 {
struct task_struct *task;
-   char buffer[PROC_NUMBUF];
+   char buffer[200];
struct mm_struct *mm;
struct vm_area_struct *vma;
enum reclaim_type type;
char *type_buf;
+   struct mm_walk reclaim_walk = {};
+   unsigned long start = 0;
+   unsigned long end = 0;
 
memset(buffer, 0, sizeof(buffer));
if (count > sizeof(buffer) - 1)
@@ -1259,42 +1263,96 @@ static ssize_t reclaim_write(struct file *file, const 
char __user *buf,
type = RECLAIM_ANON;
else if (!strcmp(type_buf, "all"))
type = RECLAIM_ALL;
+   else if (isdigit(*type_buf))
+   type = RECLAIM_RANGE;
else
-   return -EINVAL;
+   goto out_err;
+
+   if (type == RECLAIM_RANGE) {
+   int ret;
+   size_t len;
+   unsigned long len_in;
+   char *token;
+
+   token = strsep(&type_buf, " ");
+   if (!token)
+   goto out_err;
+   ret = kstrtoul(token, 10, &start);
+   if (ret < 0 || (start & ~PAGE_MASK))
+   goto out_err;
+
+   token = strsep(&type_buf, " ");
+   if (!token)
+   goto out_err;
+   ret = kstrtoul(token, 10, &len_in);
+   if (ret < 0)
+   goto out_err;
+
+   len = (len_in + ~PAGE_MASK) & PAGE_MASK;
+   /*
+* Check to see whether len was rounded up from small -ve
+* to zero.
+*/
+   if (len_in && !len)
+   goto out_err;
+
+   end = start + len;
+   if (end < start)
+   goto out_err;
+   }
 
task = get_proc_task(file->f_path.dentry->d_inode);
if (!task)
return -ESRCH;
 
mm = get_task_mm(task);
-   if (mm) {
-   struct mm_walk reclaim_walk = {
-   .pmd_entry = reclaim_pte_range,
-   .mm = mm,
-   };
+   if (!mm)
+   goto out;
 
-   down_read(&mm->mmap_sem);
-   for (vma = mm->mmap; vma; vma = vma->vm_next) {
-   reclaim_walk.private = vma;
+   reclaim_walk.mm = mm;
+   reclaim_walk.pmd_entry = reclaim_pte_range;
 
+   down_read(&mm->mmap_sem);
+   if (type == RECLAIM_RANGE) {
+   vma = find_vma(mm, start);
+   while (vma) {
+   if (vma->vm_start > end)
+   break;
+   if (is_vm_hugetlb_page(vma))
+   continue;
+
+   reclaim_walk.private = vma;
+   walk_page_range(max(vma->vm_start, start),
+   min(vma->vm_end, end),
+   &reclaim_walk);
+   vma = vma->vm_next;
+   }
+   } else {
+   for (vma = mm->mmap; vma; vma = vma->vm_next) {
if (is_vm_hugetlb_page(vma))
continue;
 
if (type == RECLAIM_ANON && vma->vm_file)
continue;
+
if (type == RECLAIM_FILE && !vma->vm_file)
continue;
 
+   reclaim_walk.private = vma;
walk_page_range(vma