From 40bdbe409fec1c6c2832b070c3b961f28a0e4e83 Mon Sep 17 00:00:00 2001
From: Peter Geoghegan
Date: Thu, 23 Apr 2020 14:43:54 -0700
Subject: [PATCH 3/6] Mark lockless nbtree leaf page memory undefined.
---
src/backend/access/nbtree/nbtsearch.c | 34 +++++++++++++++++++++++++++
src/backend/access/nbtree/nbtutils.c | 12 ++++++++++
2 files changed, 46 insertions(+)
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index 8ff49ce6d6..96e99774ba 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -21,6 +21,7 @@
#include "pgstat.h"
#include "storage/predicate.h"
#include "utils/lsyscache.h"
+#include "utils/memdebug.h"
#include "utils/rel.h"
@@ -66,6 +67,12 @@ _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp)
{
LockBuffer(sp->buf, BUFFER_LOCK_UNLOCK);
+ /*
+ * Buffer is pinned, and so is expected to be defined and addressable when
+ * we're called, no matter what happens here
+ */
+ VALGRIND_CHECK_MEM_IS_DEFINED(BufferGetPage(sp->buf), BLCKSZ);
+
if (IsMVCCSnapshot(scan->xs_snapshot) &&
RelationNeedsWAL(scan->indexRelation) &&
!scan->xs_want_itup)
@@ -73,6 +80,12 @@ _bt_drop_lock_and_maybe_pin(IndexScanDesc scan, BTScanPos sp)
ReleaseBuffer(sp->buf);
sp->buf = InvalidBuffer;
}
+#ifdef USE_VALGRIND
+ else if (!RelationUsesLocalBuffers(scan->indexRelation))
+ {
+ VALGRIND_MAKE_MEM_NOACCESS(BufferGetPage(sp->buf), BLCKSZ);
+ }
+#endif
}
/*
@@ -2065,7 +2078,28 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir)
* deleted.
*/
if (BTScanPosIsPinned(so->currPos))
+ {
+#ifdef USE_VALGRIND
+ if (!RelationUsesLocalBuffers(scan->indexRelation))
+ {
+ Page page;
+
+ /*
+ * Must not have called _bt_killitems() from _bt_steppage()
+ * (our caller), so mark buffer's page defined here instead.
+ *
+ * (If we happened to have killed items then _bt_killitems()
+ * would have been called and would have dropped both the lock
+ * and the pin, so we'd have both marked the buffer's page as
+ * defined before starting to kill, and released the buffer
+ * entirely once we were done with killing.)
+ */
+ page = BufferGetPage(so->currPos.buf);
+ VALGRIND_MAKE_MEM_DEFINED(page, BLCKSZ);
+ }
+#endif
LockBuffer(so->currPos.buf, BT_READ);
+ }
else
so->currPos.buf = _bt_getbuf(rel, so->currPos.currPage, BT_READ);
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index ce48a51640..05fcc3b873 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -27,6 +27,7 @@
#include "utils/array.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
+#include "utils/memdebug.h"
#include "utils/memutils.h"
#include "utils/rel.h"
@@ -1747,6 +1748,17 @@ _bt_killitems(IndexScanDesc scan)
LockBuffer(so->currPos.buf, BT_READ);
page = BufferGetPage(so->currPos.buf);
+
+#ifdef USE_VALGRIND
+ if (!RelationUsesLocalBuffers(scan->indexRelation))
+ {
+ /*
+ * We had a pin but not a buffer lock, so must mark page memory
+ * defined once again
+ */
+ VALGRIND_MAKE_MEM_DEFINED(page, BLCKSZ);
+ }
+#endif
}
else
{
--
2.25.1