79 lines
2.6 KiB
Diff
79 lines
2.6 KiB
Diff
From 582febffa8b3567339148c2bb916fc70f2fc546e Mon Sep 17 00:00:00 2001
|
|
From: Johan Erlandsson <johan.erlandsson@sony.com>
|
|
Date: Fri, 20 Oct 2023 19:10:52 +0200
|
|
Subject: [PATCH 03/14] zram: Fixes for lookup_swap_cache()
|
|
|
|
Fix the following three issues:
|
|
(1) swap cache missing page tree offset
|
|
The radix or xarray start at an offset inside struct address_space.
|
|
(2) swap cache entries are pointer to struct page
|
|
The entries in radix, xarray (swap cache) are address to struct page.
|
|
(3) exclude shadow entries from swap cache lookup
|
|
radix or xarray can contain shadow entries from previous page
|
|
entries. These should be ignored when looking for a page pointer.
|
|
|
|
Without the patch,
|
|
- lookup_swap_cache() returns NULL since do_xarray() call returns FALSE,
|
|
- in try_zram_decompress(), since 'entry' is NULL, page is filled with 0,
|
|
if (!entry || (flags & ZRAM_FLAG_SAME_BIT)) {
|
|
and pages in swap cache will be seen to be a 'zero' page.
|
|
|
|
Signed-off-by: Johan Erlandsson <johan.erlandsson@sony.com>
|
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|
---
|
|
diskdump.c | 19 ++++++++++++++-----
|
|
1 file changed, 14 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/diskdump.c b/diskdump.c
|
|
index f20f3ac519a1..660c25729dad 100644
|
|
--- a/diskdump.c
|
|
+++ b/diskdump.c
|
|
@@ -27,6 +27,7 @@
|
|
#include "diskdump.h"
|
|
#include "xen_dom0.h"
|
|
#include "vmcore.h"
|
|
+#include "maple_tree.h"
|
|
|
|
#define BITMAP_SECT_LEN 4096
|
|
|
|
@@ -2877,11 +2878,16 @@ out:
|
|
return zram_buf;
|
|
}
|
|
|
|
+static inline bool radix_tree_exceptional_entry(ulong entry)
|
|
+{
|
|
+ return entry & RADIX_TREE_EXCEPTIONAL_ENTRY;
|
|
+}
|
|
+
|
|
static unsigned char *
|
|
lookup_swap_cache(ulonglong pte_val, unsigned char *zram_buf)
|
|
{
|
|
ulonglong swp_offset;
|
|
- ulong swp_type, swp_space, page;
|
|
+ ulong swp_type, swp_space;
|
|
struct list_pair lp;
|
|
physaddr_t paddr;
|
|
static int is_xarray = -1;
|
|
@@ -2907,10 +2913,13 @@ lookup_swap_cache(ulonglong pte_val, unsigned char *zram_buf)
|
|
swp_space += (swp_offset >> SWAP_ADDRESS_SPACE_SHIFT) * SIZE(address_space);
|
|
|
|
lp.index = swp_offset;
|
|
- if ((is_xarray ? do_xarray : do_radix_tree)(swp_space, RADIX_TREE_SEARCH, &lp)) {
|
|
- readmem((ulong)lp.value, KVADDR, &page, sizeof(void *),
|
|
- "swap_cache page", FAULT_ON_ERROR);
|
|
- if (!is_page_ptr(page, &paddr)) {
|
|
+ if ((is_xarray ? do_xarray : do_radix_tree)
|
|
+ (swp_space+OFFSET(address_space_page_tree), RADIX_TREE_SEARCH, &lp)) {
|
|
+ if ((is_xarray ? xa_is_value : radix_tree_exceptional_entry)((ulong)lp.value)) {
|
|
+ /* ignore shadow values */
|
|
+ return NULL;
|
|
+ }
|
|
+ if (!is_page_ptr((ulong)lp.value, &paddr)) {
|
|
error(WARNING, "radix page: %lx: not a page pointer\n", lp.value);
|
|
return NULL;
|
|
}
|
|
--
|
|
2.41.0
|
|
|