summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDon Brady <[email protected]>2019-08-28 11:44:46 -0600
committerBrian Behlendorf <[email protected]>2019-08-28 10:44:46 -0700
commit28c91ab66d4607795f1e7ae3a2a82f3690ea6c4f (patch)
treeee74a6154946a75861c48196bef83159c8a4cfca
parent035e96118bc9a7cbf435dd17dda507b870fcf6e6 (diff)
Tag ABD pages for exclusion in kernel crash dumps
Tag the ABD data pages so that they can be identified for exclusion from kernel crash dumps. Eliminating the zfs file data allows for significantly smaller crash dump files. Note that ZFS in illumos has always excluded the zfs data pages from a kernel crash dump. This change tags ARC scatter data pages so they can be identified from the makedumpfile(8) command. That command is used to create smaller dump files by ignoring some memory regions and using compression. It already filters file data from the VFS page cache and will now be able to exclude ZFS file data pages from the dump file. A corresponding change to makeumpfile(8) is required to identify ZFS data pages. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Paul Dagnelie <[email protected]> Signed-off-by: Don Brady <[email protected]> Closes #8899
-rw-r--r--module/zfs/abd.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/module/zfs/abd.c b/module/zfs/abd.c
index 8b2514404..ac6b0b742 100644
--- a/module/zfs/abd.c
+++ b/module/zfs/abd.c
@@ -245,6 +245,32 @@ abd_chunkcnt_for_bytes(size_t size)
}
#ifdef _KERNEL
+/*
+ * Mark zfs data pages so they can be excluded from kernel crash dumps
+ */
+#ifdef _LP64
+#define ABD_FILE_CACHE_PAGE 0x2F5ABDF11ECAC4E
+
+static inline void
+abd_mark_zfs_page(struct page *page)
+{
+ get_page(page);
+ SetPagePrivate(page);
+ set_page_private(page, ABD_FILE_CACHE_PAGE);
+}
+
+static inline void
+abd_unmark_zfs_page(struct page *page)
+{
+ set_page_private(page, 0UL);
+ ClearPagePrivate(page);
+ put_page(page);
+}
+#else
+#define abd_mark_zfs_page(page)
+#define abd_unmark_zfs_page(page)
+#endif /* _LP64 */
+
#ifndef CONFIG_HIGHMEM
#ifndef __GFP_RECLAIM
@@ -318,6 +344,7 @@ abd_alloc_pages(abd_t *abd, size_t size)
size_t sg_size = MIN(PAGESIZE << compound_order(page),
remaining_size);
sg_set_page(sg, page, sg_size, 0);
+ abd_mark_zfs_page(page);
remaining_size -= sg_size;
sg = sg_next(sg);
@@ -404,6 +431,7 @@ abd_alloc_pages(abd_t *abd, size_t size)
ABDSTAT_BUMP(abdstat_scatter_orders[0]);
sg_set_page(sg, page, PAGESIZE, 0);
+ abd_mark_zfs_page(page);
}
if (nr_pages > 1) {
@@ -430,6 +458,7 @@ abd_free_pages(abd_t *abd)
abd_for_each_sg(abd, sg, nr_pages, i) {
page = sg_page(sg);
+ abd_unmark_zfs_page(page);
order = compound_order(page);
__free_pages(page, order);
ASSERT3U(sg->length, <=, PAGE_SIZE << order);