1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-08-01 06:46:55 +03:00

MCOL-5487 Managed shmem segment access/remap race

There is a potential edge case when a thread remaps EM
    managed shmem segment in grabEMEntryTable() whilst another
    thread access the current shmem segment mapping in virtual memory
This commit is contained in:
Roman Nozdrin
2023-04-26 17:36:21 +00:00
parent 445eb75e4f
commit eab91b5022
2 changed files with 23 additions and 6 deletions

View File

@ -219,7 +219,9 @@ boost::mutex ExtentMapRBTreeImpl::fInstanceMutex;
ExtentMapRBTreeImpl* ExtentMapRBTreeImpl::fInstance = nullptr;
/*static*/
ExtentMapRBTreeImpl* ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(unsigned key, off_t size, bool readOnly)
ExtentMapRBTreeImpl* ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(unsigned key, off_t size, bool readOnly,
bool& emLocked,
const MasterSegmentTable* emSegTable)
{
boost::mutex::scoped_lock lk(fInstanceMutex);
@ -227,7 +229,17 @@ ExtentMapRBTreeImpl* ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(unsigned key,
{
if (key != fInstance->fManagedShm.key())
{
if (emSegTable)
{
emSegTable->getTable_upgrade(MasterSegmentTable::EMTable);
emLocked = true;
}
fInstance->fManagedShm.reMapSegment();
if (emSegTable)
{
emLocked = false;
emSegTable->getTable_downgrade(MasterSegmentTable::EMTable);
}
}
return fInstance;
@ -1941,7 +1953,11 @@ void ExtentMap::grabEMEntryTable(OPS op)
}
else
{
fPExtMapRBTreeImpl = ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(fEMRBTreeShminfo->tableShmkey, 0);
const bool isReadOnly = false;
// The ternary sends EM segment table only if this grabEMEntryTable call
// is for a READ op to enable RWLock upgrade in case of a shmem segment remap.
fPExtMapRBTreeImpl = ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(
fEMRBTreeShminfo->tableShmkey, 0, isReadOnly, emLocked, op == READ ? &fMST : nullptr);
ASSERT(fPExtMapRBTreeImpl);
fExtentMapRBTree = fPExtMapRBTreeImpl->get();
@ -2176,8 +2192,8 @@ void ExtentMap::growEMShmseg(size_t size)
if (fEMRBTreeShminfo->tableShmkey == 0)
fEMRBTreeShminfo->tableShmkey = newShmKey;
fPExtMapRBTreeImpl =
ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(fEMRBTreeShminfo->tableShmkey, allocSize, r_only);
fPExtMapRBTreeImpl = ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(fEMRBTreeShminfo->tableShmkey,
allocSize, r_only, emLocked);
}
else
{

View File

@ -34,7 +34,7 @@
#include <tr1/unordered_map>
#include <mutex>
//#define NDEBUG
// #define NDEBUG
#include <cassert>
#include <boost/functional/hash.hpp> //boost::hash
#include <boost/interprocess/allocators/allocator.hpp>
@ -253,7 +253,8 @@ class ExtentMapRBTreeImpl
public:
~ExtentMapRBTreeImpl() = default;
static ExtentMapRBTreeImpl* makeExtentMapRBTreeImpl(unsigned key, off_t size, bool readOnly = false);
static ExtentMapRBTreeImpl* makeExtentMapRBTreeImpl(unsigned key, off_t size, bool readOnly, bool& emLocked,
const MasterSegmentTable* emSegTable = nullptr);
static void refreshShm()
{