Commit fe1e339f authored by marko's avatar marko

branches/zip: Fix bugs in the buddy allocator and add assertions.

buf_buddy_free(), buf_buddy_free_low(): Document that the data must
not be pointed to by the buffer pool.  Add ut_ad(!buf_pool_contains_zip())
assertions to catch pointers to freed blocks.

Validate the zip_free[] lists #ifdef UNIV_DEBUG.

buf_buddy_relocate(): Ensure that the size of the compressed page
matches.  The buddy block can be split, and the control block can be
pointing to a smaller compressed page than the one whose relocation
is being attempted.
parent 3b2806f4
...@@ -34,6 +34,7 @@ buf_buddy_alloc_zip( ...@@ -34,6 +34,7 @@ buf_buddy_alloc_zip(
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
ut_a(i < BUF_BUDDY_SIZES); ut_a(i < BUF_BUDDY_SIZES);
ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i]));
bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]); bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
if (bpage) { if (bpage) {
...@@ -48,8 +49,10 @@ buf_buddy_alloc_zip( ...@@ -48,8 +49,10 @@ buf_buddy_alloc_zip(
buf_page_t* buddy = (buf_page_t*) buf_page_t* buddy = (buf_page_t*)
(((char*) bpage) + (BUF_BUDDY_LOW << i)); (((char*) bpage) + (BUF_BUDDY_LOW << i));
ut_ad(!buf_pool_contains_zip(buddy));
ut_d(memset(buddy, i, BUF_BUDDY_LOW << i)); ut_d(memset(buddy, i, BUF_BUDDY_LOW << i));
buddy->state = BUF_BLOCK_ZIP_FREE; buddy->state = BUF_BLOCK_ZIP_FREE;
ut_ad(buf_pool->zip_free[i].start != buddy);
UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], buddy); UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], buddy);
} }
} }
...@@ -138,6 +141,9 @@ buf_buddy_alloc_from( ...@@ -138,6 +141,9 @@ buf_buddy_alloc_from(
bpage = (buf_page_t*) ((byte*) buf + offs); bpage = (buf_page_t*) ((byte*) buf + offs);
ut_d(memset(bpage, j, BUF_BUDDY_LOW << j)); ut_d(memset(bpage, j, BUF_BUDDY_LOW << j));
bpage->state = BUF_BLOCK_ZIP_FREE; bpage->state = BUF_BLOCK_ZIP_FREE;
ut_d(UT_LIST_VALIDATE(list, buf_page_t,
buf_pool->zip_free[j]));
ut_ad(buf_pool->zip_free[j].start != bpage);
UT_LIST_ADD_FIRST(list, buf_pool->zip_free[j], bpage); UT_LIST_ADD_FIRST(list, buf_pool->zip_free[j], bpage);
} }
...@@ -331,6 +337,15 @@ buf_buddy_relocate( ...@@ -331,6 +337,15 @@ buf_buddy_relocate(
return(FALSE); return(FALSE);
} }
if (page_zip_get_size(&bpage->zip) != size) {
/* The block is of different size. We would
have to relocate all blocks covered by src.
For the sake of simplicity, give up. */
ut_ad(page_zip_get_size(&bpage->zip) < size);
return(FALSE);
}
mutex = buf_page_get_mutex(bpage); mutex = buf_page_get_mutex(bpage);
mutex_enter(mutex); mutex_enter(mutex);
...@@ -416,7 +431,8 @@ Deallocate a block. */ ...@@ -416,7 +431,8 @@ Deallocate a block. */
void void
buf_buddy_free_low( buf_buddy_free_low(
/*===============*/ /*===============*/
void* buf, /* in: block to free */ void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */
ulint i) /* in: index of buf_pool->zip_free[] */ ulint i) /* in: index of buf_pool->zip_free[] */
{ {
buf_page_t* bpage; buf_page_t* bpage;
...@@ -427,6 +443,7 @@ buf_buddy_free_low( ...@@ -427,6 +443,7 @@ buf_buddy_free_low(
recombine: recombine:
ut_ad(i < BUF_BUDDY_SIZES); ut_ad(i < BUF_BUDDY_SIZES);
ut_ad(buf == ut_align_down(buf, BUF_BUDDY_LOW << i)); ut_ad(buf == ut_align_down(buf, BUF_BUDDY_LOW << i));
ut_ad(!buf_pool_contains_zip(buf));
/* Try to combine adjacent blocks. */ /* Try to combine adjacent blocks. */
...@@ -448,6 +465,7 @@ recombine: ...@@ -448,6 +465,7 @@ recombine:
if (bpage == buddy) { if (bpage == buddy) {
buddy_free: buddy_free:
/* The buddy is free: recombine */ /* The buddy is free: recombine */
ut_ad(!buf_pool_contains_zip(buddy));
UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage); UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
buf = ut_align_down(buf, BUF_BUDDY_LOW << (i + 1)); buf = ut_align_down(buf, BUF_BUDDY_LOW << (i + 1));
...@@ -465,6 +483,8 @@ buddy_free: ...@@ -465,6 +483,8 @@ buddy_free:
} }
buddy_nonfree: buddy_nonfree:
ut_d(UT_LIST_VALIDATE(list, buf_page_t, buf_pool->zip_free[i]));
/* The buddy is not free. Is there a free block of this size? */ /* The buddy is not free. Is there a free block of this size? */
bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]); bpage = UT_LIST_GET_FIRST(buf_pool->zip_free[i]);
...@@ -504,5 +524,6 @@ buddy_nonfree: ...@@ -504,5 +524,6 @@ buddy_nonfree:
bpage = buf; bpage = buf;
ut_d(memset(bpage, i, BUF_BUDDY_LOW << i)); ut_d(memset(bpage, i, BUF_BUDDY_LOW << i));
bpage->state = BUF_BLOCK_ZIP_FREE; bpage->state = BUF_BLOCK_ZIP_FREE;
ut_ad(buf_pool->zip_free[i].start != bpage);
UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage); UT_LIST_ADD_FIRST(list, buf_pool->zip_free[i], bpage);
} }
...@@ -59,7 +59,8 @@ UNIV_INLINE ...@@ -59,7 +59,8 @@ UNIV_INLINE
void void
buf_buddy_free( buf_buddy_free(
/*===========*/ /*===========*/
void* buf, /* in: block to free */ void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */
ulint size) /* in: block size, up to UNIV_PAGE_SIZE / 2 */ ulint size) /* in: block size, up to UNIV_PAGE_SIZE / 2 */
__attribute__((nonnull)); __attribute__((nonnull));
......
...@@ -35,7 +35,8 @@ Deallocate a block. */ ...@@ -35,7 +35,8 @@ Deallocate a block. */
void void
buf_buddy_free_low( buf_buddy_free_low(
/*===============*/ /*===============*/
void* buf, /* in: block to free */ void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */
ulint i) /* in: index of buf_pool->zip_free[] */ ulint i) /* in: index of buf_pool->zip_free[] */
__attribute__((nonnull)); __attribute__((nonnull));
...@@ -101,7 +102,8 @@ UNIV_INLINE ...@@ -101,7 +102,8 @@ UNIV_INLINE
void void
buf_buddy_free( buf_buddy_free(
/*===========*/ /*===========*/
void* buf, /* in: block to free */ void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */
ulint size) /* in: block size, up to UNIV_PAGE_SIZE / 2 */ ulint size) /* in: block size, up to UNIV_PAGE_SIZE / 2 */
{ {
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
......
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