v1-0001-Add-runtime-control-over-CLOBBER_CACHE_ALWAYS.patch
text/x-patch
Filename: v1-0001-Add-runtime-control-over-CLOBBER_CACHE_ALWAYS.patch
Type: text/x-patch
Part: 0
Patch
Format: format-patch
Series: patch v1-0001
Subject: Add runtime control over CLOBBER_CACHE_ALWAYS
| File | + | − |
|---|---|---|
| src/backend/utils/cache/inval.c | 29 | 22 |
| src/backend/utils/misc/guc.c | 15 | 0 |
| src/include/pg_config_manual.h | 26 | 2 |
| src/include/utils/inval.h | 8 | 0 |
From 372defde443d178fb4a9c8cf4092dea7debf72ea Mon Sep 17 00:00:00 2001
From: Craig Ringer <craig.ringer@2ndquadrant.com>
Date: Tue, 22 Sep 2020 09:51:00 +0800
Subject: [PATCH v1] Add runtime control over CLOBBER_CACHE_ALWAYS
When CLOBBER_CACHE_ALWAYS or CLOBBER_CACHE_RECURSIVE are defined,
a new GUC "clobber_cache_depth" becomes available. This allows runtime
control over the behaviour of cache clobber builds in order to allow
more targeted testing of new or changed features using aggressive
cache clobbering.
clobber_cache_depth defaults to 1 if CLOBBER_CACHE_ALWAYS is defined,
and to 3 if CLOBBER_CACHE_RECURSIVE is defined. That makes it match
the previous hardcoded behaviour of these macros, ensuring buildfarm
members won't get upset.
While we're at it, expose the macros in pg_config_manual.h
---
src/backend/utils/cache/inval.c | 51 +++++++++++++++++++--------------
src/backend/utils/misc/guc.c | 15 ++++++++++
src/include/pg_config_manual.h | 28 ++++++++++++++++--
src/include/utils/inval.h | 8 ++++++
4 files changed, 78 insertions(+), 24 deletions(-)
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index 628d6f5d0c..620c9558ac 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -109,6 +109,7 @@
#include "storage/sinval.h"
#include "storage/smgr.h"
#include "utils/catcache.h"
+#include "utils/guc.h"
#include "utils/inval.h"
#include "utils/memdebug.h"
#include "utils/memutils.h"
@@ -179,6 +180,9 @@ static SharedInvalidationMessage *SharedInvalidMessagesArray;
static int numSharedInvalidMessagesArray;
static int maxSharedInvalidMessagesArray;
+#if CACHE_CLOBBER_ALWAYS
+int clobber_cache_depth = 0;
+#endif
/*
* Dynamically-registered callback functions. Current implementation
@@ -689,35 +693,38 @@ AcceptInvalidationMessages(void)
/*
* Test code to force cache flushes anytime a flush could happen.
*
- * If used with CLOBBER_FREED_MEMORY, CLOBBER_CACHE_ALWAYS provides a
+ * CLOBBER_CACHE_ALWAYS (clobber_cache_depth = 1) provides a
* fairly thorough test that the system contains no cache-flush hazards.
* However, it also makes the system unbelievably slow --- the regression
- * tests take about 100 times longer than normal.
- *
- * If you're a glutton for punishment, try CLOBBER_CACHE_RECURSIVELY. This
- * slows things by at least a factor of 10000, so I wouldn't suggest
- * trying to run the entire regression tests that way. It's useful to try
- * a few simple tests, to make sure that cache reload isn't subject to
- * internal cache-flush hazards, but after you've done a few thousand
- * recursive reloads it's unlikely you'll learn more.
+ * tests take about 100 times longer than normal. To mitigate the
+ * slowdown it can be turned on and off per-backend or globally using
+ * the clobber_cache_depth GUC to allow targeted testing of specific
+ * code paths.
+ *
+ * If you're a glutton for punishment, try CLOBBER_CACHE_RECURSIVELY
+ * (set clobber_cache_depth to > 1). This slows things by at least a
+ * factor of 10000, so I wouldn't suggest trying to run the entire
+ * regression tests that way. It's useful to try a few simple tests,
+ * to make sure that cache reload isn't subject to internal cache-flush
+ * hazards, but after you've done a few thousand recursive reloads it's
+ * unlikely you'll learn more.
+ *
+ * You can use postgresql.conf or any other convenient means to disable
+ * clobbering by default then re-enable for targeted sections of tests,
+ * e.g you can edit a specific pg_regress test to SET
+ * clobber_cache_depth=1, then run the suite with:
+ *
+ * PGOPTIONS="-c clobber_cache_depth=0" make -C src/test/regress check
+ *
+ * Remember to use ALTER SYSTEM SET and reload the config if you want
+ * the change to apply to bgworkers, autovacuum, etc too.
*/
#if defined(CLOBBER_CACHE_ALWAYS)
- {
- static bool in_recursion = false;
-
- if (!in_recursion)
- {
- in_recursion = true;
- InvalidateSystemCaches();
- in_recursion = false;
- }
- }
-#elif defined(CLOBBER_CACHE_RECURSIVELY)
+ if (clobber_cache_depth > 0)
{
static int recursion_depth = 0;
- /* Maximum depth is arbitrary depending on your threshold of pain */
- if (recursion_depth < 3)
+ if (recursion_depth < clobber_cache_depth)
{
recursion_depth++;
InvalidateSystemCaches();
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 596bcb7b84..ae7d46cff0 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -99,6 +99,7 @@
#include "utils/rls.h"
#include "utils/snapmgr.h"
#include "utils/tzparser.h"
+#include "utils/inval.h"
#include "utils/varlena.h"
#include "utils/xml.h"
@@ -3399,7 +3400,21 @@ static struct config_int ConfigureNamesInt[] =
check_huge_page_size, NULL, NULL
},
+#if defined(CLOBBER_CACHE_ALWAYS) || defined(CLOBBER_CACHE_RECURSIVELY)
+ /* Only available in special debug builds, see pg_config_manual.h */
+ {
+ {"clobber_cache_depth", PGC_SUSET, DEVELOPER_OPTIONS,
+ gettext_noop("Runtime control over CLOBBER_CACHE_ALWAYS and CLOBBER_CACHE_RECURSIVELY",
+ NULL,
+ GUC_NOT_IN_SAMPLE
+ },
+ &clobber_cache_depth,
+ DEFAULT_CLOBBER_CACHE_DEPTH, 0, 5,
+ NULL, NULL, NULL
+ },
+
/* End-of-list marker */
+#endif
{
{NULL, 0, 0, NULL, NULL}, NULL, 0, 0, 0, NULL, NULL, NULL
}
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index 705dc69c06..615e0833f1 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -6,8 +6,15 @@
* for developers. If you edit any of these, be sure to do a *full*
* rebuild (and an initdb if noted).
*
+ * You can define these by editing pg_config_manual.h but it's usually
+ * sufficient to pass CFLAGS to configure, e.g.
+ *
+ * ./configure --enable-debug --enable-cassert CFLAGS="-DUSE_VALGRIND"
+ *
+ * The flags are persisted in Makefile.global so they will be correctly
+ * applied to extensions, including those built by PGXS.
+ *
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
*
* src/include/pg_config_manual.h
*------------------------------------------------------------------------
@@ -280,7 +287,8 @@
* percentage points even when not run under Valgrind.
*
* You should normally use MEMORY_CONTEXT_CHECKING with USE_VALGRIND;
- * instrumentation of repalloc() is inferior without it.
+ * instrumentation of repalloc() is inferior without it. So it's defined
+ * automatically for USE_VALGRIND builds.
*/
/* #define USE_VALGRIND */
@@ -309,6 +317,22 @@
*/
/* #define RANDOMIZE_ALLOCATED_MEMORY */
+/*
+ * For cache invalidation debugging, clobber caches whenever an invalidation is
+ * possible. For CLOBBER_CACHE_RECURSIVELY, do so even when already processing
+ * invalidations. The GUC clobber_cache_depth is only available when these
+ * options are defined. See inval.c for details.
+ *
+ * It's strongly recommended that you use --enable-cassert and the
+ * implied CLOBBER_FREED_MEMORY if you enable either of these.
+ */
+/* #define CLOBBER_CACHE_ALWAYS */
+/* #define CLOBBER_CACHE_RECURSIVELY */
+
+#if defined(CLOBBER_CACHE_RECURSIVELY) && !defined(CLOBBER_CACHE_ALWAYS)
+#define CLOBBER_CACHE_ALWAYS
+#endif
+
/*
* Define this to force all parse and plan trees to be passed through
* copyObject(), to facilitate catching errors and omissions in
diff --git a/src/include/utils/inval.h b/src/include/utils/inval.h
index 463888c389..ddfae7a9d6 100644
--- a/src/include/utils/inval.h
+++ b/src/include/utils/inval.h
@@ -18,6 +18,14 @@
#include "storage/relfilenode.h"
#include "utils/relcache.h"
+#ifdef CLOBBER_CACHE_ALWAYS
+extern PGDLLIMPORT int clobber_cache_depth;
+#ifdef CLOBBER_CACHE_RECURSIVELY
+#define DEFAULT_CLOBBER_CACHE_DEPTH 3
+#else
+#define DEFAULT_CLOBBER_CACHE_DEPTH 1
+#endif
+#endif
typedef void (*SyscacheCallbackFunction) (Datum arg, int cacheid, uint32 hashvalue);
typedef void (*RelcacheCallbackFunction) (Datum arg, Oid relid);
--
2.26.2