FADV_DEACTIVATE advises kernel to move file pages from active to inactive list.
https://jira.sw.ru/browse/PSBM-57915 Signed-off-by: Andrey Ryabinin <aryabi...@virtuozzo.com> --- include/uapi/linux/fadvise.h | 1 + mm/fadvise.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/uapi/linux/fadvise.h b/include/uapi/linux/fadvise.h index a3e0703..b6ade7e 100644 --- a/include/uapi/linux/fadvise.h +++ b/include/uapi/linux/fadvise.h @@ -17,6 +17,7 @@ #define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */ #define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */ #endif +#define FADV_DEACTIVATE 32 /* Mark pages as good candidates for reclaim */ #ifdef __KERNEL__ extern int generic_fadvise(struct file* file, loff_t off, loff_t len, int adv); diff --git a/mm/fadvise.c b/mm/fadvise.c index 2a1bdfb..e805d01 100644 --- a/mm/fadvise.c +++ b/mm/fadvise.c @@ -22,6 +22,43 @@ #include <asm/unistd.h> +static void fadvise_deactivate(struct address_space *mapping, + pgoff_t start, pgoff_t end) +{ + struct pagevec pvec; + pgoff_t index = start; + int i; + + if (start > end) + return; + + /* + * Note: this function may get called on a shmem/tmpfs mapping: + * pagevec_lookup() might then return 0 prematurely (because it + * got a gangful of swap entries); but it's hardly worth worrying + * about - it can rarely have anything to free from such a mapping + * (most pages are dirty), and already skips over any difficulties. + */ + + pagevec_init(&pvec, 0); + while (index <= end && pagevec_lookup(&pvec, mapping, index, + min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) { + for (i = 0; i < pagevec_count(&pvec); i++) { + struct page *page = pvec.pages[i]; + + /* We rely upon deletion not changing page->index */ + index = page->index; + if (index > end) + break; + + deactivate_page(page); + } + pagevec_release(&pvec); + cond_resched(); + index++; + } +} + /* * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could * deactivate the pages and clear PG_Referenced. @@ -44,6 +81,7 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice) case POSIX_FADV_WILLNEED: case POSIX_FADV_NOREUSE: case POSIX_FADV_DONTNEED: + case FADV_DEACTIVATE: /* no bad return value, but ignore advice */ break; default: @@ -124,6 +162,11 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice) } } break; + case FADV_DEACTIVATE: + start_index = (offset+(PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT; + end_index = (endbyte >> PAGE_CACHE_SHIFT); + fadvise_deactivate(mapping, start_index, end_index); + break; default: ret = -EINVAL; } -- 2.10.2 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel