Re: [PATCH v2 5/6] mm: Support address range reclaim
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
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
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