[Devel] [PATCH rh7] fs/fadvise: introduce FADV_DEACTIVATE flag
Andrey Ryabinin
aryabinin at virtuozzo.com
Thu Dec 22 03:58:24 PST 2016
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 <aryabinin at 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
More information about the Devel
mailing list