Commit de7b2e9a authored by unknown's avatar unknown

ndb - bug#29044

  Improve buddy high order allocation
  Make removeCommonArea O(1) instead of O(N)
  Add limit to left/right search


storage/ndb/src/kernel/blocks/dbtup/DbtupDebug.cpp:
  Add info to buddy module test about 
  1) loops being made in buddy
  2) how much was allocated
storage/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp:
  1) make removeCommonArea o(1) - as list is (after fix) double linked anyway
  2) set page_state = ZFREE_COMMON insertCommonArea and ~ZFREE_COMMON in removeCommonArea
  3) add max loops in search left/right
  4) add more debug info
parent 05ff34a2
...@@ -76,6 +76,10 @@ Dbtup::reportMemoryUsage(Signal* signal, int incDec){ ...@@ -76,6 +76,10 @@ Dbtup::reportMemoryUsage(Signal* signal, int incDec){
sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB); sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 6, JBB);
} }
#ifdef VM_TRACE
extern Uint32 fc_left, fc_right, fc_remove;
#endif
void void
Dbtup::execDUMP_STATE_ORD(Signal* signal) Dbtup::execDUMP_STATE_ORD(Signal* signal)
{ {
...@@ -157,12 +161,20 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal) ...@@ -157,12 +161,20 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal)
return; return;
}//if }//if
#endif #endif
#if defined VM_TRACE && 0 #if defined VM_TRACE
if (type == 1211){ if (type == 1211 || type == 1212 || type == 1213){
ndbout_c("Startar modul test av Page Manager"); Uint32 seed = time(0);
if (signal->getLength() > 1)
seed = signal->theData[1];
ndbout_c("Startar modul test av Page Manager (seed: 0x%x)", seed);
srand(seed);
Vector<Chunk> chunks; Vector<Chunk> chunks;
const Uint32 LOOPS = 1000; const Uint32 LOOPS = 1000;
Uint32 sum_req = 0;
Uint32 sum_conf = 0;
Uint32 sum_loop = 0;
Uint32 max_loop = 0;
for(Uint32 i = 0; i<LOOPS; i++){ for(Uint32 i = 0; i<LOOPS; i++){
// Case // Case
...@@ -180,7 +192,14 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal) ...@@ -180,7 +192,14 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal)
c = 1 + rand() % 2; c = 1 + rand() % 2;
} }
if (type == 1211)
ndbout_c("loop=%d case=%d free=%d alloc=%d", i, c, free, alloc); ndbout_c("loop=%d case=%d free=%d alloc=%d", i, c, free, alloc);
if (type == 1213)
{
c = 1;
alloc = 2 + (sum_conf >> 3) + (sum_conf >> 4);
}
switch(c){ switch(c){
case 0:{ // Release case 0:{ // Release
const int ch = rand() % chunks.size(); const int ch = rand() % chunks.size();
...@@ -192,15 +211,19 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal) ...@@ -192,15 +211,19 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal)
case 2: { // Seize(n) - fail case 2: { // Seize(n) - fail
alloc += free; alloc += free;
// Fall through // Fall through
sum_req += free;
goto doalloc;
} }
case 1: { // Seize(n) (success) case 1: { // Seize(n) (success)
sum_req += alloc;
doalloc:
Chunk chunk; Chunk chunk;
allocConsPages(alloc, chunk.pageCount, chunk.pageId); allocConsPages(alloc, chunk.pageCount, chunk.pageId);
ndbrequire(chunk.pageCount <= alloc); ndbrequire(chunk.pageCount <= alloc);
if(chunk.pageCount != 0){ if(chunk.pageCount != 0){
chunks.push_back(chunk); chunks.push_back(chunk);
if(chunk.pageCount != alloc) { if(chunk.pageCount != alloc) {
if (type == 1211)
ndbout_c(" Tried to allocate %d - only allocated %d - free: %d", ndbout_c(" Tried to allocate %d - only allocated %d - free: %d",
alloc, chunk.pageCount, free); alloc, chunk.pageCount, free);
} }
...@@ -209,6 +232,12 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal) ...@@ -209,6 +232,12 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal)
alloc, free); alloc, free);
} }
sum_conf += chunk.pageCount;
Uint32 tot = fc_left + fc_right + fc_remove;
sum_loop += tot;
if (tot > max_loop)
max_loop = tot;
for(Uint32 i = 0; i<chunk.pageCount; i++){ for(Uint32 i = 0; i<chunk.pageCount; i++){
PagePtr pagePtr; PagePtr pagePtr;
pagePtr.i = chunk.pageId + i; pagePtr.i = chunk.pageId + i;
...@@ -227,6 +256,10 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal) ...@@ -227,6 +256,10 @@ Dbtup::execDUMP_STATE_ORD(Signal* signal)
returnCommonArea(chunk.pageId, chunk.pageCount); returnCommonArea(chunk.pageId, chunk.pageCount);
chunks.erase(chunks.size() - 1); chunks.erase(chunks.size() - 1);
} }
ndbout_c("Got %u%% of requested allocs, loops : %u 100*avg: %u max: %u",
(100 * sum_conf) / sum_req, sum_loop, 100*sum_loop / LOOPS,
max_loop);
} }
#endif #endif
}//Dbtup::execDUMP_STATE_ORD() }//Dbtup::execDUMP_STATE_ORD()
......
...@@ -148,10 +148,17 @@ void Dbtup::initializePage() ...@@ -148,10 +148,17 @@ void Dbtup::initializePage()
cnoOfAllocatedPages = tmp; // Is updated by returnCommonArea cnoOfAllocatedPages = tmp; // Is updated by returnCommonArea
}//Dbtup::initializePage() }//Dbtup::initializePage()
#ifdef VM_TRACE
Uint32 fc_left, fc_right, fc_remove;
#endif
void Dbtup::allocConsPages(Uint32 noOfPagesToAllocate, void Dbtup::allocConsPages(Uint32 noOfPagesToAllocate,
Uint32& noOfPagesAllocated, Uint32& noOfPagesAllocated,
Uint32& allocPageRef) Uint32& allocPageRef)
{ {
#ifdef VM_TRACE
fc_left = fc_right = fc_remove = 0;
#endif
if (noOfPagesToAllocate == 0){ if (noOfPagesToAllocate == 0){
ljam(); ljam();
noOfPagesAllocated = 0; noOfPagesAllocated = 0;
...@@ -230,7 +237,10 @@ void Dbtup::findFreeLeftNeighbours(Uint32& allocPageRef, ...@@ -230,7 +237,10 @@ void Dbtup::findFreeLeftNeighbours(Uint32& allocPageRef,
{ {
PagePtr pageFirstPtr, pageLastPtr; PagePtr pageFirstPtr, pageLastPtr;
Uint32 remainAllocate = noOfPagesToAllocate - noPagesAllocated; Uint32 remainAllocate = noOfPagesToAllocate - noPagesAllocated;
while (allocPageRef > 0) { Uint32 loop = 0;
while (allocPageRef > 0 &&
++loop < 16)
{
ljam(); ljam();
pageLastPtr.i = allocPageRef - 1; pageLastPtr.i = allocPageRef - 1;
c_page_pool.getPtr(pageLastPtr); c_page_pool.getPtr(pageLastPtr);
...@@ -258,6 +268,9 @@ void Dbtup::findFreeLeftNeighbours(Uint32& allocPageRef, ...@@ -258,6 +268,9 @@ void Dbtup::findFreeLeftNeighbours(Uint32& allocPageRef,
remainAllocate -= listSize; remainAllocate -= listSize;
}//if }//if
}//if }//if
#ifdef VM_TRACE
fc_left++;
#endif
}//while }//while
}//Dbtup::findFreeLeftNeighbours() }//Dbtup::findFreeLeftNeighbours()
...@@ -271,7 +284,10 @@ void Dbtup::findFreeRightNeighbours(Uint32& allocPageRef, ...@@ -271,7 +284,10 @@ void Dbtup::findFreeRightNeighbours(Uint32& allocPageRef,
ljam(); ljam();
return; return;
}//if }//if
while ((allocPageRef + noPagesAllocated) < c_page_pool.getSize()) { Uint32 loop = 0;
while ((allocPageRef + noPagesAllocated) < c_page_pool.getSize() &&
++loop < 16)
{
ljam(); ljam();
pageFirstPtr.i = allocPageRef + noPagesAllocated; pageFirstPtr.i = allocPageRef + noPagesAllocated;
c_page_pool.getPtr(pageFirstPtr); c_page_pool.getPtr(pageFirstPtr);
...@@ -298,24 +314,37 @@ void Dbtup::findFreeRightNeighbours(Uint32& allocPageRef, ...@@ -298,24 +314,37 @@ void Dbtup::findFreeRightNeighbours(Uint32& allocPageRef,
remainAllocate -= listSize; remainAllocate -= listSize;
}//if }//if
}//if }//if
#ifdef VM_TRACE
fc_right++;
#endif
}//while }//while
}//Dbtup::findFreeRightNeighbours() }//Dbtup::findFreeRightNeighbours()
void Dbtup::insertCommonArea(Uint32 insPageRef, Uint32 insList) void Dbtup::insertCommonArea(Uint32 insPageRef, Uint32 insList)
{ {
cnoOfAllocatedPages -= (1 << insList); cnoOfAllocatedPages -= (1 << insList);
PagePtr pageLastPtr, pageInsPtr; PagePtr pageLastPtr, pageInsPtr, pageHeadPtr;
pageHeadPtr.i = cfreepageList[insList];
c_page_pool.getPtr(pageInsPtr, insPageRef); c_page_pool.getPtr(pageInsPtr, insPageRef);
ndbrequire(insList < 16); ndbrequire(insList < 16);
pageLastPtr.i = (pageInsPtr.i + (1 << insList)) - 1; pageLastPtr.i = (pageInsPtr.i + (1 << insList)) - 1;
pageInsPtr.p->next_cluster_page = cfreepageList[insList]; pageInsPtr.p->page_state = ZFREE_COMMON;
pageInsPtr.p->next_cluster_page = pageHeadPtr.i;
pageInsPtr.p->prev_cluster_page = RNIL; pageInsPtr.p->prev_cluster_page = RNIL;
pageInsPtr.p->last_cluster_page = pageLastPtr.i; pageInsPtr.p->last_cluster_page = pageLastPtr.i;
cfreepageList[insList] = pageInsPtr.i; cfreepageList[insList] = pageInsPtr.i;
if (pageHeadPtr.i != RNIL)
{
jam();
c_page_pool.getPtr(pageHeadPtr);
pageHeadPtr.p->prev_cluster_page = pageInsPtr.i;
}
c_page_pool.getPtr(pageLastPtr); c_page_pool.getPtr(pageLastPtr);
pageLastPtr.p->page_state = ZFREE_COMMON;
pageLastPtr.p->first_cluster_page = pageInsPtr.i; pageLastPtr.p->first_cluster_page = pageInsPtr.i;
pageLastPtr.p->next_page = RNIL; pageLastPtr.p->next_page = RNIL;
}//Dbtup::insertCommonArea() }//Dbtup::insertCommonArea()
...@@ -323,12 +352,13 @@ void Dbtup::insertCommonArea(Uint32 insPageRef, Uint32 insList) ...@@ -323,12 +352,13 @@ void Dbtup::insertCommonArea(Uint32 insPageRef, Uint32 insList)
void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list) void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list)
{ {
cnoOfAllocatedPages += (1 << list); cnoOfAllocatedPages += (1 << list);
PagePtr pagePrevPtr, pageNextPtr, pageLastPtr, pageSearchPtr, remPagePtr; PagePtr pagePrevPtr, pageNextPtr, pageLastPtr, remPagePtr;
c_page_pool.getPtr(remPagePtr, remPageRef); c_page_pool.getPtr(remPagePtr, remPageRef);
ndbrequire(list < 16); ndbrequire(list < 16);
if (cfreepageList[list] == remPagePtr.i) { if (cfreepageList[list] == remPagePtr.i) {
ljam(); ljam();
ndbassert(remPagePtr.p->prev_cluster_page == RNIL);
cfreepageList[list] = remPagePtr.p->next_cluster_page; cfreepageList[list] = remPagePtr.p->next_cluster_page;
pageNextPtr.i = cfreepageList[list]; pageNextPtr.i = cfreepageList[list];
if (pageNextPtr.i != RNIL) { if (pageNextPtr.i != RNIL) {
...@@ -337,30 +367,25 @@ void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list) ...@@ -337,30 +367,25 @@ void Dbtup::removeCommonArea(Uint32 remPageRef, Uint32 list)
pageNextPtr.p->prev_cluster_page = RNIL; pageNextPtr.p->prev_cluster_page = RNIL;
}//if }//if
} else { } else {
pageSearchPtr.i = cfreepageList[list]; pagePrevPtr.i = remPagePtr.p->prev_cluster_page;
while (true) {
ljam();
c_page_pool.getPtr(pageSearchPtr);
pagePrevPtr = pageSearchPtr;
pageSearchPtr.i = pageSearchPtr.p->next_cluster_page;
if (pageSearchPtr.i == remPagePtr.i) {
ljam();
break;
}//if
}//while
pageNextPtr.i = remPagePtr.p->next_cluster_page; pageNextPtr.i = remPagePtr.p->next_cluster_page;
c_page_pool.getPtr(pagePrevPtr);
pagePrevPtr.p->next_cluster_page = pageNextPtr.i; pagePrevPtr.p->next_cluster_page = pageNextPtr.i;
if (pageNextPtr.i != RNIL) { if (pageNextPtr.i != RNIL)
{
ljam(); ljam();
c_page_pool.getPtr(pageNextPtr); c_page_pool.getPtr(pageNextPtr);
pageNextPtr.p->prev_cluster_page = pagePrevPtr.i; pageNextPtr.p->prev_cluster_page = pagePrevPtr.i;
}//if }
}//if }//if
remPagePtr.p->next_cluster_page= RNIL; remPagePtr.p->next_cluster_page= RNIL;
remPagePtr.p->last_cluster_page= RNIL; remPagePtr.p->last_cluster_page= RNIL;
remPagePtr.p->prev_cluster_page= RNIL; remPagePtr.p->prev_cluster_page= RNIL;
remPagePtr.p->page_state = ~ZFREE_COMMON;
pageLastPtr.i = (remPagePtr.i + (1 << list)) - 1; pageLastPtr.i = (remPagePtr.i + (1 << list)) - 1;
c_page_pool.getPtr(pageLastPtr); c_page_pool.getPtr(pageLastPtr);
pageLastPtr.p->first_cluster_page= RNIL; pageLastPtr.p->first_cluster_page= RNIL;
pageLastPtr.p->page_state = ~ZFREE_COMMON;
}//Dbtup::removeCommonArea() }//Dbtup::removeCommonArea()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment