From 87a0c14600506d2a33a5a6bedc6e58d70ff7acc7 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Wed, 24 Jun 2020 16:35:49 -0700 Subject: [PATCH 1/3] Align PGAlignedBlock to expected page size. In order to be allowed to use O_DIRECT, we need to align buffers to the page or sector size. Author: Andres Freund Author: Thomas Munro --- src/include/c.h | 20 ++++++++++++-------- src/include/pg_config_manual.h | 8 ++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/include/c.h b/src/include/c.h index d70ed84ac5..0deaca0414 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -1070,17 +1070,18 @@ extern void ExceptionalCondition(const char *conditionName, /* * Use this, not "char buf[BLCKSZ]", to declare a field or local variable - * holding a page buffer, if that page might be accessed as a page and not - * just a string of bytes. Otherwise the variable might be under-aligned, - * causing problems on alignment-picky hardware. (In some places, we use - * this to declare buffers even though we only pass them to read() and - * write(), because copying to/from aligned buffers is usually faster than - * using unaligned buffers.) We include both "double" and "int64" in the - * union to ensure that the compiler knows the value must be MAXALIGN'ed - * (cf. configure's computation of MAXIMUM_ALIGNOF). + * holding a page buffer, if that page might be accessed as a page or passed to + * an I/O function and not just a string of bytes. Otherwise the variable + * might be under-aligned, causing problems on alignment-picky hardware, or if + * PG_O_DIRECT is used. We include both "double" and "int64" in the union to + * ensure that the compiler knows the value must be MAXALIGN'ed (cf. + * configure's computation of MAXIMUM_ALIGNOF). */ typedef union PGAlignedBlock { +#ifdef pg_attribute_aligned + pg_attribute_aligned(PG_IO_ALIGN_SIZE) +#endif char data[BLCKSZ]; double force_align_d; int64 force_align_i64; @@ -1089,6 +1090,9 @@ typedef union PGAlignedBlock /* Same, but for an XLOG_BLCKSZ-sized buffer */ typedef union PGAlignedXLogBlock { +#ifdef pg_attribute_aligned + pg_attribute_aligned(PG_IO_ALIGN_SIZE) +#endif char data[XLOG_BLCKSZ]; double force_align_d; int64 force_align_i64; diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index f2a106f983..a2ad08a110 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -227,6 +227,14 @@ */ #define PG_CACHE_LINE_SIZE 128 +/* + * Assumed memory alignment requirement for direct I/O. The real requirement + * may be based on sectors or pages. The default is the typical modern sector + * size and virtual memory page size, which is enough for currently known + * systems. + */ +#define PG_IO_ALIGN_SIZE 4096 + /* *------------------------------------------------------------------------ * The following symbols are for enabling debugging code, not for -- 2.35.1