summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordormando <dormando@rydia.net>2015-10-06 22:39:27 -0700
committerdormando <dormando@rydia.net>2015-11-18 23:14:36 -0800
commit186509c27f1fadfb1552d289eba7d574f5e33e7a (patch)
treea52a251b69a1fdfa0f2925562ca0b8324f6619ee
parent1c3f0a3d0f1844dd1d8443dea4d04733663d6495 (diff)
downloadmemcached-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.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/slabs.c b/slabs.c
index 678226c..83b908c 100644
--- a/slabs.c
+++ b/slabs.c
@@ -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;