Skip to content

Commit eb706fd

Browse files
committed
Fix newly introduced bug in slab.c
d21ded7 changed the way slab.c works but introduced a bug that meant we could end up with the slab's curBlocklistIndex pointing to the wrong list. The condition which was checking for this was failing to account for two things: 1. The curBlocklistIndex could be 0 as we've currently got no non-full blocks to put chunks on. In this case, the dlist_is_empty() check cannot be performed as there can be any number of completely full blocks at that index. 2. The curBlocklistIndex may be greater than the index we just moved the block onto. Since we need to ensure we fill up fuller blocks first, we must reset curBlocklistIndex when changing any blocklist element that's less than the curBlocklistIndex too. Reported-by: Takamichi Osumi Discussion: https://postgr.es/m/TYCPR01MB8373329C6329768D7E093D68EDEB9@TYCPR01MB8373.jpnprd01.prod.outlook.com
1 parent f450695 commit eb706fd

File tree

1 file changed

+11
-7
lines changed

1 file changed

+11
-7
lines changed

src/backend/utils/mmgr/slab.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -691,16 +691,20 @@ SlabFree(void *pointer)
691691
dlist_push_head(&slab->blocklist[newBlocklistIdx], &block->node);
692692

693693
/*
694-
* It's possible that we've no blocks in the blocklist at the
695-
* curBlocklistIndex position. When this happens we must find the
696-
* next blocklist index which contains blocks. We can be certain
697-
* we'll find a block as at least one must exist for the chunk we're
698-
* currently freeing.
694+
* The blocklist[curBlocklistIdx] may now be empty or we may now be
695+
* able to use a lower-element blocklist. We'll need to redetermine
696+
* what the slab->curBlocklistIndex is if the current blocklist was
697+
* changed or if a lower element one was changed. We must ensure we
698+
* use the list with the fullest block(s).
699699
*/
700-
if (slab->curBlocklistIndex == curBlocklistIdx &&
701-
dlist_is_empty(&slab->blocklist[curBlocklistIdx]))
700+
if (slab->curBlocklistIndex >= curBlocklistIdx)
702701
{
703702
slab->curBlocklistIndex = SlabFindNextBlockListIndex(slab);
703+
704+
/*
705+
* We know there must be a block with at least 1 unused chunk as
706+
* we just pfree'd one. Ensure curBlocklistIndex reflects this.
707+
*/
704708
Assert(slab->curBlocklistIndex > 0);
705709
}
706710
}

0 commit comments

Comments
 (0)