diff options
author | dormando <dormando@rydia.net> | 2015-10-06 22:39:27 -0700 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2015-11-18 23:14:36 -0800 |
commit | 186509c27f1fadfb1552d289eba7d574f5e33e7a (patch) | |
tree | a52a251b69a1fdfa0f2925562ca0b8324f6619ee | |
parent | 1c3f0a3d0f1844dd1d8443dea4d04733663d6495 (diff) | |
download | memcached-186509c27f1fadfb1552d289eba7d574f5e33e7a.tar.gz |
stop using slab class 255 for page mover
class 255 is now a legitimate class, used by the NOEXP LRU when the
expirezero_does_not_evict flag is enabled. Instead, we now force a single bit
ITEM_SLABBED when a chunk is returned to the slabber, and
ITEM_SLABBED|ITEM_FETCHED means it's been cleared for a page move.
item_alloc overwrites the chunk's flags on set. The only weirdness was
slab_free |='ing in the ITEM_SLABBED bit. I tracked that down to a commit in
2003 titled "more debugging" and can't come up with a good enough excuse for
preserving an item's flags when it's been returned to the free memory pool. So
now we overload the flag meaning.
-rw-r--r-- | slabs.c | 14 |
1 files changed, 8 insertions, 6 deletions
@@ -294,7 +294,7 @@ static void do_slabs_free(void *ptr, const size_t size, unsigned int id) { p = &slabclass[id]; it = (item *)ptr; - it->it_flags |= ITEM_SLABBED; + it->it_flags = ITEM_SLABBED; it->slabs_clsid = 0; it->prev = 0; it->next = p->slots; @@ -581,7 +581,10 @@ static int slab_rebalance_move(void) { hold_lock = NULL; item *it = slab_rebal.slab_pos; status = MOVE_PASS; - if (it->slabs_clsid != 255) { + /* ITEM_FETCHED when ITEM_SLABBED is overloaded to mean we've cleared + * the chunk for move. Only these two flags should exist. + */ + if (it->it_flags != (ITEM_SLABBED|ITEM_FETCHED)) { /* ITEM_SLABBED can only be added/removed under the slabs_lock */ if (it->it_flags & ITEM_SLABBED) { /* remove from slab freelist */ @@ -698,8 +701,7 @@ static int slab_rebalance_move(void) { s_cls->requested -= ntotal; case MOVE_FROM_SLAB: it->refcount = 0; - it->it_flags = 0; - it->slabs_clsid = 255; + it->it_flags = ITEM_SLABBED|ITEM_FETCHED; #ifdef DEBUG_SLAB_MOVER memcpy(ITEM_key(it), "deadbeef", 8); #endif @@ -753,9 +755,9 @@ static void slab_rebalance_finish(void) { slab_rebal.slab_pos = slab_rebal.slab_start; while (1) { item *it = slab_rebal.slab_pos; - assert(it->slabs_clsid == 255); + assert(it->it_flags == (ITEM_SLABBED|ITEM_FETCHED)); assert(memcmp(ITEM_key(it), "deadbeef", 8) == 0); - it->slabs_clsid = 255; + it->it_flags = ITEM_SLABBED|ITEM_FETCHED; slab_rebal.slab_pos = (char *)slab_rebal.slab_pos + s_cls->size; if (slab_rebal.slab_pos >= slab_rebal.slab_end) break; |