You've already forked mariadb-columnstore-engine
mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-08-05 16:15:50 +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;
|
ExtentMapRBTreeImpl* ExtentMapRBTreeImpl::fInstance = nullptr;
|
||||||
|
|
||||||
/*static*/
|
/*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);
|
boost::mutex::scoped_lock lk(fInstanceMutex);
|
||||||
|
|
||||||
@@ -227,7 +229,17 @@ ExtentMapRBTreeImpl* ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(unsigned key,
|
|||||||
{
|
{
|
||||||
if (key != fInstance->fManagedShm.key())
|
if (key != fInstance->fManagedShm.key())
|
||||||
{
|
{
|
||||||
|
if (emSegTable)
|
||||||
|
{
|
||||||
|
emSegTable->getTable_upgrade(MasterSegmentTable::EMTable);
|
||||||
|
emLocked = true;
|
||||||
|
}
|
||||||
fInstance->fManagedShm.reMapSegment();
|
fInstance->fManagedShm.reMapSegment();
|
||||||
|
if (emSegTable)
|
||||||
|
{
|
||||||
|
emLocked = false;
|
||||||
|
emSegTable->getTable_downgrade(MasterSegmentTable::EMTable);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fInstance;
|
return fInstance;
|
||||||
@@ -1941,7 +1953,11 @@ void ExtentMap::grabEMEntryTable(OPS op)
|
|||||||
}
|
}
|
||||||
else
|
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);
|
ASSERT(fPExtMapRBTreeImpl);
|
||||||
|
|
||||||
fExtentMapRBTree = fPExtMapRBTreeImpl->get();
|
fExtentMapRBTree = fPExtMapRBTreeImpl->get();
|
||||||
@@ -2176,8 +2192,8 @@ void ExtentMap::growEMShmseg(size_t size)
|
|||||||
if (fEMRBTreeShminfo->tableShmkey == 0)
|
if (fEMRBTreeShminfo->tableShmkey == 0)
|
||||||
fEMRBTreeShminfo->tableShmkey = newShmKey;
|
fEMRBTreeShminfo->tableShmkey = newShmKey;
|
||||||
|
|
||||||
fPExtMapRBTreeImpl =
|
fPExtMapRBTreeImpl = ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(fEMRBTreeShminfo->tableShmkey,
|
||||||
ExtentMapRBTreeImpl::makeExtentMapRBTreeImpl(fEMRBTreeShminfo->tableShmkey, allocSize, r_only);
|
allocSize, r_only, emLocked);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -34,7 +34,7 @@
|
|||||||
#include <tr1/unordered_map>
|
#include <tr1/unordered_map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
//#define NDEBUG
|
// #define NDEBUG
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <boost/functional/hash.hpp> //boost::hash
|
#include <boost/functional/hash.hpp> //boost::hash
|
||||||
#include <boost/interprocess/allocators/allocator.hpp>
|
#include <boost/interprocess/allocators/allocator.hpp>
|
||||||
@@ -253,7 +253,8 @@ class ExtentMapRBTreeImpl
|
|||||||
public:
|
public:
|
||||||
~ExtentMapRBTreeImpl() = default;
|
~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()
|
static void refreshShm()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user