You've already forked mariadb-columnstore-engine
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:
@ -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
|
||||
{
|
||||
|
@ -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()
|
||||
{
|
||||
|
Reference in New Issue
Block a user