Skip to content

Commit 6d847fe

Browse files
igchorbyrnedj
authored andcommitted
Remove parameter for markMoving()
initial sync logic just use parent in progress - only mark parent as moving fix chained items fix moving cleanup on failure currently fails asserts in move chained with sync sync on parent
1 parent 773d548 commit 6d847fe

File tree

8 files changed

+468
-149
lines changed

8 files changed

+468
-149
lines changed

cachelib/allocator/CacheAllocator-inl.h

Lines changed: 372 additions & 140 deletions
Large diffs are not rendered by default.

cachelib/allocator/CacheAllocator.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,25 @@ class CacheAllocator : public CacheBase {
15441544
WriteHandle allocateChainedItemInternal(const ReadHandle& parent,
15451545
uint32_t size);
15461546

1547+
// Allocate a chained item to a specific tier
1548+
//
1549+
// The resulting chained item does not have a parent item and
1550+
// will be freed once the handle is dropped
1551+
//
1552+
// The parent handle parameter here is mainly used to find the
1553+
// correct pool to allocate memory for this chained item
1554+
//
1555+
// @param parent handle to the cache item
1556+
// @param size the size for the chained allocation
1557+
// @param tid the tier to allocate on
1558+
//
1559+
// @return handle to the chained allocation
1560+
// @throw std::invalid_argument if the size requested is invalid or
1561+
// if the item is invalid
1562+
WriteHandle allocateChainedItemInternalTier(const ReadHandle& parent,
1563+
uint32_t size,
1564+
TierId tid);
1565+
15471566
// Given an item and its parentKey, validate that the parentKey
15481567
// corresponds to an item that's the parent of the supplied item.
15491568
//
@@ -1620,6 +1639,16 @@ class CacheAllocator : public CacheBase {
16201639
// @return true If the move was completed, and the containers were updated
16211640
// successfully.
16221641
bool moveRegularItemWithSync(Item& oldItem, WriteHandle& newItemHdl);
1642+
1643+
// Moves a chained item to a different memory tier.
1644+
//
1645+
// @param oldItem Reference to the item being moved
1646+
// @param newItemHdl Reference to the handle of the new item being moved into
1647+
// @param parentHandle Reference to the handle of the parent item
1648+
//
1649+
// @return true If the move was completed, and the containers were updated
1650+
// successfully.
1651+
bool moveChainedItemWithSync(ChainedItem& oldItem, WriteHandle& newItemHdl, WriteHandle& parentHandle);
16231652

16241653
// Moves a regular item to a different slab. This should only be used during
16251654
// slab release after the item's exclusive bit has been set. The user supplied
@@ -1689,6 +1718,9 @@ class CacheAllocator : public CacheBase {
16891718
WriteHandle newItemHdl,
16901719
const Item& parent);
16911720

1721+
void replaceChainedItemLockedForMoving(Item& oldItem,
1722+
WriteHandle& newItemHdl,
1723+
const Item& parent);
16921724
// Insert an item into MM container. The caller must hold a valid handle for
16931725
// the item.
16941726
//
@@ -1979,7 +2011,7 @@ auto& mmContainer = getMMContainer(tid, pid, cid);
19792011
throw std::runtime_error("Not supported for chained items");
19802012
}
19812013

1982-
if (candidate->markMoving(true)) {
2014+
if (candidate->markMoving()) {
19832015
mmContainer.remove(itr);
19842016
candidates.push_back(candidate);
19852017
} else {
@@ -2052,7 +2084,7 @@ auto& mmContainer = getMMContainer(tid, pid, cid);
20522084

20532085
// TODO: only allow it for read-only items?
20542086
// or implement mvcc
2055-
if (candidate->markMoving(true)) {
2087+
if (candidate->markMoving()) {
20562088
// promotions should rarely fail since we already marked moving
20572089
mmContainer.remove(itr);
20582090
candidates.push_back(candidate);

cachelib/allocator/CacheItem-inl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,8 @@ bool CacheItem<CacheTrait>::markForEvictionWhenMoving() {
238238
}
239239

240240
template <typename CacheTrait>
241-
bool CacheItem<CacheTrait>::markMoving(bool failIfRefNotZero) {
242-
return ref_.markMoving(failIfRefNotZero);
241+
bool CacheItem<CacheTrait>::markMoving() {
242+
return ref_.markMoving();
243243
}
244244

245245
template <typename CacheTrait>

cachelib/allocator/CacheItem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ class CACHELIB_PACKED_ATTR CacheItem {
381381
* Unmarking moving will also return the refcount at the moment of
382382
* unmarking.
383383
*/
384-
bool markMoving(bool failIfRefNotZero);
384+
bool markMoving();
385385
RefcountWithFlags::Value unmarkMoving() noexcept;
386386
bool isMoving() const noexcept;
387387
bool isOnlyMoving() const noexcept;

cachelib/allocator/Refcount.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,15 +320,23 @@ class FOLLY_PACK_ATTR RefcountWithFlags {
320320
*
321321
* Unmarking moving does not depend on `isInMMContainer`
322322
*/
323-
bool markMoving(bool failIfRefNotZero) {
324-
auto predicate = [failIfRefNotZero](const Value curValue) {
323+
bool markMoving() {
324+
auto predicate = [](const Value curValue) {
325325
Value conditionBitMask = getAdminRef<kLinked>();
326326
const bool flagSet = curValue & conditionBitMask;
327327
const bool alreadyExclusive = curValue & getAdminRef<kExclusive>();
328-
if (failIfRefNotZero && (curValue & kAccessRefMask) != 0) {
328+
const bool isChained = curValue & getFlag<kIsChainedItem>();
329+
330+
// chained item can have ref count == 1, this just means it's linked in the chain
331+
if (isChained && (curValue & kAccessRefMask) > 1) {
332+
return false;
333+
} else if (!isChained && (curValue & kAccessRefMask) != 0) {
329334
return false;
330335
}
331-
if (!flagSet || alreadyExclusive) {
336+
// when we mark a chained item as moving it - it may not
337+
// be in the mmContainer
338+
if ( (!isChained && (!flagSet || alreadyExclusive)) ||
339+
( isChained && alreadyExclusive) ) {
332340
return false;
333341
}
334342
if (UNLIKELY((curValue & kAccessRefMask) == (kAccessRefMask))) {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// @nolint like default.json, but moves items during slab release instead of evicting them.
2+
{
3+
"cache_config" : {
4+
"cacheSizeMB" : 2248,
5+
"cacheDir": "/tmp/mem-tier5",
6+
"memoryTiers" : [
7+
{
8+
"ratio": 1,
9+
"memBindNodes": 0
10+
}, {
11+
"ratio": 1,
12+
"memBindNodes": 0
13+
}
14+
],
15+
"poolRebalanceIntervalSec" : 1,
16+
"moveOnSlabRelease" : true,
17+
"rebalanceMinSlabs" : 2,
18+
"evictorThreads": 2,
19+
"promoterThreads": 2
20+
},
21+
"test_config" :
22+
{
23+
"preallocateCache" : true,
24+
"numOps" : 40000000,
25+
"numThreads" : 32,
26+
"numKeys" : 250000,
27+
"generator": "online",
28+
29+
"keySizeRange" : [1, 8, 32, 64, 128, 256, 512],
30+
"keySizeRangeProbability" : [0.1, 0.1, 0.2, 0.2, 0.3, 0.1],
31+
32+
"valSizeRange" : [1, 128, 512, 1024, 4096, 10240, 20480, 40960, 60000],
33+
"valSizeRangeProbability" : [0.1, 0.1, 0.1, 0.2, 0.2, 0.1, 0.1, 0.1],
34+
35+
"getRatio" : 0.70,
36+
"setRatio" : 0.30
37+
}
38+
39+
}
40+

cachelib/common/Mutex.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ class RWBucketLocks : public BaseBucketLocks<LockType, LockAlignmentType> {
341341
using Lock = LockType;
342342
using ReadLockHolder = ReadLockHolderType;
343343
using WriteLockHolder = WriteLockHolderType;
344+
using LockHolder = std::unique_lock<Lock>;
344345

345346
RWBucketLocks(uint32_t locksPower, std::shared_ptr<Hash> hasher)
346347
: Base::BaseBucketLocks(locksPower, std::move(hasher)) {}
@@ -357,6 +358,11 @@ class RWBucketLocks : public BaseBucketLocks<LockType, LockAlignmentType> {
357358
return WriteLockHolder{Base::getLock(args...)};
358359
}
359360

361+
template <typename... Args>
362+
LockHolder tryLockExclusive(Args... args) noexcept {
363+
return LockHolder(Base::getLock(args...), std::try_to_lock);
364+
}
365+
360366
// try to grab the reader lock for a limit _timeout_ duration
361367
template <typename... Args>
362368
ReadLockHolder lockShared(const std::chrono::microseconds& timeout,

run_tests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ fi
1313

1414
../bin/cachebench --json_test_config ../test_configs/consistency/navy.json
1515
../bin/cachebench --json_test_config ../test_configs/consistency/navy-multi-tier.json
16+
../opt/bin/cachebench --json_test_config /opt/test_configs/small_moving_bg.json

0 commit comments

Comments
 (0)