[CRIU] [PATCHv2 9/9] ppc64/aarch64: Dynamically define PAGE_SIZE
Dmitry Safonov
dima at arista.com
Wed Mar 28 19:19:53 MSK 2018
On ppc64/aarch64 Linux can be set to use Large pages, so the PAGE_SIZE
isn't build-time constant anymore. Define it through _SC_PAGESIZE.
There are different sizes for a page on ppc64:
: #if defined(CONFIG_PPC_256K_PAGES)
: #define PAGE_SHIFT 18
: #elif defined(CONFIG_PPC_64K_PAGES)
: #define PAGE_SHIFT 16
: #elif defined(CONFIG_PPC_16K_PAGES)
: #define PAGE_SHIFT 14
: #else
: #define PAGE_SHIFT 12
: #endif
And on aarch64 there are default sizes and possibly someone can set his
own PAGE_SHIFT:
: config ARM64_PAGE_SHIFT
: int
: default 16 if ARM64_64K_PAGES
: default 14 if ARM64_16K_PAGES
: default 12
On the downside - each time we need PAGE_SIZE, we're doing libc
function call on aarch64/ppc64.
Fixes: #415
Save a couple of cycles by having __page_size && __page_shift cached
as suggested-by Mike.
Signed-off-by: Dmitry Safonov <dima at arista.com>
---
criu/arch/aarch64/crtools.c | 3 +++
criu/arch/ppc64/crtools.c | 3 +++
include/common/arch/aarch64/asm/page.h | 42 ++++++++++++++++++++++------------
include/common/arch/ppc64/asm/page.h | 40 ++++++++++++++++++++------------
4 files changed, 59 insertions(+), 29 deletions(-)
diff --git a/criu/arch/aarch64/crtools.c b/criu/arch/aarch64/crtools.c
index f98743a23be9..b2ef1c31241a 100644
--- a/criu/arch/aarch64/crtools.c
+++ b/criu/arch/aarch64/crtools.c
@@ -21,6 +21,9 @@
#include "restorer.h"
#include <compel/compel.h>
+unsigned __page_size = 0;
+unsigned __page_shift = 0;
+
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))(src)->e
int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
diff --git a/criu/arch/ppc64/crtools.c b/criu/arch/ppc64/crtools.c
index 5a5966ad4868..077c243b24a8 100644
--- a/criu/arch/ppc64/crtools.c
+++ b/criu/arch/ppc64/crtools.c
@@ -23,6 +23,9 @@
#include "images/core.pb-c.h"
#include "images/creds.pb-c.h"
+unsigned __page_size = 0;
+unsigned __page_shift = 0;
+
static UserPpc64FpstateEntry *copy_fp_regs(uint64_t *fpregs)
{
UserPpc64FpstateEntry *fpe;
diff --git a/include/common/arch/aarch64/asm/page.h b/include/common/arch/aarch64/asm/page.h
index 0e81dfcfabb2..8adde9bea3e2 100644
--- a/include/common/arch/aarch64/asm/page.h
+++ b/include/common/arch/aarch64/asm/page.h
@@ -4,22 +4,36 @@
#define ARCH_HAS_LONG_PAGES
#ifndef CR_NOGLIBC
-#include <unistd.h>
-
-#ifndef PAGE_SHIFT
-# define PAGE_SHIFT 12
-#endif
-
-#ifndef PAGE_SIZE
-# define PAGE_SIZE (1UL << PAGE_SHIFT)
-#endif
-
-#ifndef PAGE_MASK
-# define PAGE_MASK (~(PAGE_SIZE - 1))
-#endif
+#include <string.h> /* ffsl() */
+#include <unistd.h> /* _SC_PAGESIZE */
+
+extern unsigned __page_size;
+extern unsigned __page_shift;
+
+static inline unsigned page_size(void)
+{
+ if (!__page_size)
+ __page_size = sysconf(_SC_PAGESIZE);
+ return __page_size;
+}
+
+static inline unsigned page_shift(void)
+{
+ if (!__page_shift)
+ __page_shift = (ffsl(page_size()) - 1);
+ return __page_shift;
+}
+
+/*
+ * Don't add ifdefs for PAGE_SIZE: if any header defines it as a constant
+ * on aarch64, then we need refrain using PAGE_SIZE in criu and use
+ * page_size() across sources (as it may differ on aarch64).
+ */
+#define PAGE_SIZE page_size()
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+#define PAGE_SHIFT page_shift()
#define PAGE_PFN(addr) ((addr) / PAGE_SIZE)
-#define page_size() sysconf(_SC_PAGESIZE)
#else /* CR_NOGLIBC */
diff --git a/include/common/arch/ppc64/asm/page.h b/include/common/arch/ppc64/asm/page.h
index 3de489df7f13..d0dc66a6ec23 100644
--- a/include/common/arch/ppc64/asm/page.h
+++ b/include/common/arch/ppc64/asm/page.h
@@ -4,26 +4,36 @@
#define ARCH_HAS_LONG_PAGES
#ifndef CR_NOGLIBC
-#include <unistd.h>
+#include <string.h> /* ffsl() */
+#include <unistd.h> /* _SC_PAGESIZE */
+
+extern unsigned __page_size;
+extern unsigned __page_shift;
+
+static inline unsigned page_size(void)
+{
+ if (!__page_size)
+ __page_size = sysconf(_SC_PAGESIZE);
+ return __page_size;
+}
+
+static inline unsigned page_shift(void)
+{
+ if (!__page_shift)
+ __page_shift = (ffsl(page_size()) - 1);
+ return __page_shift;
+}
/*
- * Default config for Pseries is to use 64K pages.
- * See kernel file arch/powerpc/configs/pseries_*defconfig
+ * Don't add ifdefs for PAGE_SIZE: if any header defines it as a constant
+ * on ppc64, then we need refrain using PAGE_SIZE in criu and use
+ * page_size() across sources (as it may differ on ppc64).
*/
-#ifndef PAGE_SHIFT
-# define PAGE_SHIFT 16
-#endif
-
-#ifndef PAGE_SIZE
-# define PAGE_SIZE (1UL << PAGE_SHIFT)
-#endif
-
-#ifndef PAGE_MASK
-# define PAGE_MASK (~(PAGE_SIZE - 1))
-#endif
+#define PAGE_SIZE page_size()
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+#define PAGE_SHIFT page_shift()
#define PAGE_PFN(addr) ((addr) / PAGE_SIZE)
-#define page_size() sysconf(_SC_PAGESIZE)
#else /* CR_NOGLIBC */
--
2.13.6
More information about the CRIU
mailing list