etmem/0001-fix-64K-pagesize-scan-problem.patch
2021-03-18 16:14:21 +08:00

110 lines
3.7 KiB
Diff

From b5543c083777aa5d75d6b240b718f8c6be2def12 Mon Sep 17 00:00:00 2001
From: liubo <liubo254@huawei.com>
Date: Thu, 18 Mar 2021 15:13:22 +0800
Subject: [PATCH] fix 64K pagesize scan problem
Signed-off-by: liubo <liubo254@huawei.com>
---
inc/etmemd_inc/etmemd_scan.h | 1 +
src/etmemd_src/etmemd.c | 5 +++++
src/etmemd_src/etmemd_scan.c | 38 ++++++++++++++++++++++++++++++++++++--
3 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/inc/etmemd_inc/etmemd_scan.h b/inc/etmemd_inc/etmemd_scan.h
index dbb6f70..9ae387e 100644
--- a/inc/etmemd_inc/etmemd_scan.h
+++ b/inc/etmemd_inc/etmemd_scan.h
@@ -109,4 +109,5 @@ void clean_page_refs_unexpected(void *arg);
void clean_memory_grade_unexpected(void *arg);
struct page_refs *add_page_refs_into_memory_grade(struct page_refs *page_refs, struct page_refs **list);
+int init_g_page_size(void);
#endif
diff --git a/src/etmemd_src/etmemd.c b/src/etmemd_src/etmemd.c
index 6670197..d99b7c8 100644
--- a/src/etmemd_src/etmemd.c
+++ b/src/etmemd_src/etmemd.c
@@ -20,6 +20,7 @@
#include "etmemd_rpc.h"
#include "etmemd_common.h"
#include "etmemd_project.h"
+#include "etmemd_scan.h"
int main(int argc, char *argv[])
{
@@ -35,6 +36,10 @@ int main(int argc, char *argv[])
return 0;
}
+ if (init_g_page_size() == -1) {
+ return -1;
+ }
+
etmemd_handle_signal();
if (etmemd_rpc_server() != 0) {
printf("fail to start rpc server of etmemd\n");
diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c
index 8617e8f..d67c940 100644
--- a/src/etmemd_src/etmemd_scan.c
+++ b/src/etmemd_src/etmemd_scan.c
@@ -45,12 +45,46 @@ static const enum page_type g_page_type_by_idle_kind[] = {
PAGE_TYPE_INVAL,
};
-static const u_int64_t g_page_size[PAGE_TYPE_INVAL] = {
+static u_int64_t g_page_size[PAGE_TYPE_INVAL] = {
1UL << PTE_SIZE_SHIFT, /* PTE size */
1UL << PMD_SIZE_SHIFT, /* PMD size */
1UL << PUD_SIZE_SHIFT, /* PUD size */
};
+static unsigned int get_page_shift(long pagesize)
+{
+ unsigned int page_shift = 0;
+ pagesize = pagesize >> 1;
+ while (pagesize != 0) {
+ page_shift++;
+ pagesize = pagesize >> 1;
+ }
+
+ return page_shift;
+}
+
+int init_g_page_size(void)
+{
+ unsigned int page_shift;
+ long pagesize = -1;
+
+ pagesize = sysconf(_SC_PAGESIZE);
+ if (pagesize == -1) {
+ etmemd_log(ETMEMD_LOG_ERR, "get pagesize fail, error: %d\n", errno);
+ return -1;
+ }
+
+ /* In the x86 architecture, the pagesize is 4kB. In the arm64 architecture,
+ * the pagesize is 4KB, 16KB, 64KB. Therefore, the pagesize in different
+ * scenarios is calculated as follows: */
+ page_shift = get_page_shift(pagesize);
+ g_page_size[PTE_TYPE] = 1 << page_shift; /* PTE_SIZE */
+ g_page_size[PMD_TYPE] = 1 << (((page_shift - 3) * (4 - 2)) + 3); /* PMD_SIZE = (page_shift - 3) * (4 - 2) + 3 */
+ g_page_size[PUD_TYPE] = 1 << (((page_shift - 3) * (4 - 1)) + 3); /* PUD_SIZE = (page_shift - 3) * (4 - 1) + 3 */
+
+ return 0;
+}
+
static bool is_anonymous(const struct vma *vma)
{
if (vma->stat[VMA_STAT_MAY_SHARE] || vma->stat[VMA_STAT_EXEC]) {
@@ -470,7 +504,7 @@ static struct page_refs **walk_vmas(int fd,
/* we make the buffer size as fitable as within a vma.
* because the size of buffer passed to kernel will be calculated again (<< (3 + PAGE_SHIFT)) */
- size = (walk_address->walk_end - walk_address->walk_start) >> (3 + PAGE_SHIFT);
+ size = ((walk_address->walk_end - walk_address->walk_start) >> 3) / g_page_size[PTE_TYPE];
/* we need to compare the size to the minimum size that kernel handled */
size = size < EPT_IDLE_BUF_MIN ? EPT_IDLE_BUF_MIN : size;
--
1.8.3.1