Skip to content

Commit aa758e8

Browse files
authored
Merge pull request #3 from igchor/develop2
Publish changes from innersouce
2 parents 17eb460 + ba089ef commit aa758e8

24 files changed

+1359
-280
lines changed

cachelib/allocator/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ if (BUILD_TESTS)
109109
add_test (tests/ChainedHashTest.cpp)
110110
add_test (tests/AllocatorResizeTypeTest.cpp)
111111
add_test (tests/AllocatorHitStatsTypeTest.cpp)
112+
add_test (tests/MemoryTiersTest.cpp)
112113
add_test (tests/MultiAllocatorTest.cpp)
113114
add_test (tests/NvmAdmissionPolicyTest.cpp)
114115
add_test (nvmcache/tests/NvmItemTests.cpp)

cachelib/allocator/CacheAllocator-inl.h

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ CacheAllocator<CacheTrait>::CacheAllocator(SharedMemNewT, Config config)
6868
AccessContainer::getRequiredSize(
6969
config_.accessConfig.getNumBuckets()),
7070
nullptr,
71-
ShmSegmentOpts(config_.accessConfig.getPageSize()))
71+
ShmSegmentOpts(config_.accessConfig.getPageSize(),
72+
false, config_.usePosixShm))
7273
.addr,
7374
compressor_,
7475
[this](Item* it) -> ItemHandle { return acquire(it); })),
@@ -79,7 +80,8 @@ CacheAllocator<CacheTrait>::CacheAllocator(SharedMemNewT, Config config)
7980
AccessContainer::getRequiredSize(
8081
config_.chainedItemAccessConfig.getNumBuckets()),
8182
nullptr,
82-
ShmSegmentOpts(config_.accessConfig.getPageSize()))
83+
ShmSegmentOpts(config_.accessConfig.getPageSize(),
84+
false, config_.usePosixShm))
8385
.addr,
8486
compressor_,
8587
[this](Item* it) -> ItemHandle { return acquire(it); })),
@@ -89,7 +91,8 @@ CacheAllocator<CacheTrait>::CacheAllocator(SharedMemNewT, Config config)
8991
nvmCacheState_{config_.cacheDir, config_.isNvmCacheEncryptionEnabled(),
9092
config_.isNvmCacheTruncateAllocSizeEnabled()} {
9193
initCommon(false);
92-
shmManager_->removeShm(detail::kShmInfoName);
94+
shmManager_->removeShm(detail::kShmInfoName,
95+
PosixSysVSegmentOpts(config_.usePosixShm));
9396
}
9497

9598
template <typename CacheTrait>
@@ -107,13 +110,15 @@ CacheAllocator<CacheTrait>::CacheAllocator(SharedMemAttachT, Config config)
107110
accessContainer_(std::make_unique<AccessContainer>(
108111
deserializer_->deserialize<AccessSerializationType>(),
109112
config_.accessConfig,
110-
shmManager_->attachShm(detail::kShmHashTableName),
113+
shmManager_->attachShm(detail::kShmHashTableName, nullptr,
114+
ShmSegmentOpts(PageSizeT::NORMAL, false, config_.usePosixShm)),
111115
compressor_,
112116
[this](Item* it) -> ItemHandle { return acquire(it); })),
113117
chainedItemAccessContainer_(std::make_unique<AccessContainer>(
114118
deserializer_->deserialize<AccessSerializationType>(),
115119
config_.chainedItemAccessConfig,
116-
shmManager_->attachShm(detail::kShmChainedItemHashTableName),
120+
shmManager_->attachShm(detail::kShmChainedItemHashTableName, nullptr,
121+
ShmSegmentOpts(PageSizeT::NORMAL, false, config_.usePosixShm)),
117122
compressor_,
118123
[this](Item* it) -> ItemHandle { return acquire(it); })),
119124
chainedItemLocks_(config_.chainedItemsLockPower,
@@ -130,7 +135,8 @@ CacheAllocator<CacheTrait>::CacheAllocator(SharedMemAttachT, Config config)
130135
// We will create a new info shm segment on shutDown(). If we don't remove
131136
// this info shm segment here and the new info shm segment's size is larger
132137
// than this one, creating new one will fail.
133-
shmManager_->removeShm(detail::kShmInfoName);
138+
shmManager_->removeShm(detail::kShmInfoName,
139+
PosixSysVSegmentOpts(config_.usePosixShm));
134140
}
135141

136142
template <typename CacheTrait>
@@ -148,6 +154,7 @@ std::unique_ptr<MemoryAllocator>
148154
CacheAllocator<CacheTrait>::createNewMemoryAllocator() {
149155
ShmSegmentOpts opts;
150156
opts.alignment = sizeof(Slab);
157+
opts.typeOpts = PosixSysVSegmentOpts(config_.usePosixShm);
151158
return std::make_unique<MemoryAllocator>(
152159
getAllocatorConfig(config_),
153160
shmManager_
@@ -162,6 +169,7 @@ std::unique_ptr<MemoryAllocator>
162169
CacheAllocator<CacheTrait>::restoreMemoryAllocator() {
163170
ShmSegmentOpts opts;
164171
opts.alignment = sizeof(Slab);
172+
opts.typeOpts = PosixSysVSegmentOpts(config_.usePosixShm);
165173
return std::make_unique<MemoryAllocator>(
166174
deserializer_->deserialize<MemoryAllocator::SerializationType>(),
167175
shmManager_
@@ -265,7 +273,8 @@ void CacheAllocator<CacheTrait>::initWorkers() {
265273

266274
template <typename CacheTrait>
267275
std::unique_ptr<Deserializer> CacheAllocator<CacheTrait>::createDeserializer() {
268-
auto infoAddr = shmManager_->attachShm(detail::kShmInfoName);
276+
auto infoAddr = shmManager_->attachShm(detail::kShmInfoName, nullptr,
277+
ShmSegmentOpts(PageSizeT::NORMAL, false, config_.usePosixShm));
269278
return std::make_unique<Deserializer>(
270279
reinterpret_cast<uint8_t*>(infoAddr.addr),
271280
reinterpret_cast<uint8_t*>(infoAddr.addr) + infoAddr.size);
@@ -3041,8 +3050,11 @@ void CacheAllocator<CacheTrait>::saveRamCache() {
30413050
std::unique_ptr<folly::IOBuf> ioBuf = serializedBuf.move();
30423051
ioBuf->coalesce();
30433052

3044-
void* infoAddr =
3045-
shmManager_->createShm(detail::kShmInfoName, ioBuf->length()).addr;
3053+
ShmSegmentOpts opts;
3054+
opts.typeOpts = PosixSysVSegmentOpts(config_.usePosixShm);
3055+
3056+
void* infoAddr = shmManager_->createShm(detail::kShmInfoName, ioBuf->length(),
3057+
nullptr, opts).addr;
30463058
Serializer serializer(reinterpret_cast<uint8_t*>(infoAddr),
30473059
reinterpret_cast<uint8_t*>(infoAddr) + ioBuf->length());
30483060
serializer.writeToBuffer(std::move(ioBuf));
@@ -3386,7 +3398,7 @@ bool CacheAllocator<CacheTrait>::stopReaper(std::chrono::seconds timeout) {
33863398

33873399
template <typename CacheTrait>
33883400
bool CacheAllocator<CacheTrait>::cleanupStrayShmSegments(
3389-
const std::string& cacheDir, bool posix) {
3401+
const std::string& cacheDir, bool posix /*TODO(SHM_FILE): const std::vector<CacheMemoryTierConfig>& config */) {
33903402
if (util::getStatIfExists(cacheDir, nullptr) && util::isDir(cacheDir)) {
33913403
try {
33923404
// cache dir exists. clean up only if there are no other processes
@@ -3405,6 +3417,12 @@ bool CacheAllocator<CacheTrait>::cleanupStrayShmSegments(
34053417
ShmManager::removeByName(cacheDir, detail::kShmHashTableName, posix);
34063418
ShmManager::removeByName(cacheDir, detail::kShmChainedItemHashTableName,
34073419
posix);
3420+
3421+
// TODO(SHM_FILE): try to nuke segments of differente types (which require
3422+
// extra info)
3423+
// for (auto &tier : config) {
3424+
// ShmManager::removeByName(cacheDir, tierShmName, config_.memoryTiers[i].opts);
3425+
// }
34083426
}
34093427
return true;
34103428
}

cachelib/allocator/CacheAllocator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,8 @@ class CacheAllocator : public CacheBase {
10351035
// returns true if there was no error in trying to cleanup the segment
10361036
// because another process was attached. False if the user tried to clean up
10371037
// and the cache was actually attached.
1038-
static bool cleanupStrayShmSegments(const std::string& cacheDir, bool posix);
1038+
static bool cleanupStrayShmSegments(const std::string& cacheDir, bool posix
1039+
/*TODO: const std::vector<CacheMemoryTierConfig>& config = {} */);
10391040

10401041
// gives a relative offset to a pointer within the cache.
10411042
uint64_t getItemPtrAsOffset(const void* ptr);

cachelib/allocator/CacheAllocatorConfig.h

Lines changed: 86 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <string>
2626

2727
#include "cachelib/allocator/Cache.h"
28+
#include "cachelib/allocator/MemoryTierCacheConfig.h"
2829
#include "cachelib/allocator/MM2Q.h"
2930
#include "cachelib/allocator/MemoryMonitor.h"
3031
#include "cachelib/allocator/NvmAdmissionPolicy.h"
@@ -49,6 +50,7 @@ class CacheAllocatorConfig {
4950
using NvmCacheDeviceEncryptor = typename CacheT::NvmCacheT::DeviceEncryptor;
5051
using MoveCb = typename CacheT::MoveCb;
5152
using NvmCacheConfig = typename CacheT::NvmCacheT::Config;
53+
using MemoryTierConfigs = std::vector<MemoryTierCacheConfig>;
5254
using Key = typename CacheT::Key;
5355
using EventTrackerSharedPtr = std::shared_ptr<typename CacheT::EventTracker>;
5456
using Item = typename CacheT::Item;
@@ -186,14 +188,23 @@ class CacheAllocatorConfig {
186188
// This allows cache to be persisted across restarts. One example use case is
187189
// to preserve the cache when releasing a new version of your service. Refer
188190
// to our user guide for how to set up cache persistence.
191+
// TODO: get rid of baseAddr or if set make sure all mapping are adjacent?
192+
// We can also make baseAddr a per-tier configuration
189193
CacheAllocatorConfig& enableCachePersistence(std::string directory,
190194
void* baseAddr = nullptr);
191195

192-
// uses posix shm segments instead of the default sys-v shm segments.
193-
// @throw std::invalid_argument if called without enabling
194-
// cachePersistence()
196+
// Uses posix shm segments instead of the default sys-v shm
197+
// segments. @throw std::invalid_argument if called without enabling
198+
// cachePersistence().
195199
CacheAllocatorConfig& usePosixForShm();
196200

201+
// Configures cache memory tiers. Accepts vector of MemoryTierCacheConfig.
202+
// Each vector element describes configuration for a single memory cache tier.
203+
CacheAllocatorConfig& configureMemoryTiers(const MemoryTierConfigs& configs);
204+
205+
// Return reference to MemoryTierCacheConfigs.
206+
const MemoryTierConfigs& getMemoryTierConfigs();
207+
197208
// This turns on a background worker that periodically scans through the
198209
// access container and look for expired items and remove them.
199210
CacheAllocatorConfig& enableItemReaperInBackground(
@@ -541,6 +552,9 @@ class CacheAllocatorConfig {
541552
// cache.
542553
uint64_t nvmAdmissionMinTTL{0};
543554

555+
// Configuration for memory tiers.
556+
MemoryTierConfigs memoryTierConfigs;
557+
544558
friend CacheT;
545559

546560
private:
@@ -801,6 +815,74 @@ CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::enableItemReaperInBackground(
801815
return *this;
802816
}
803817

818+
template <typename T>
819+
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::configureMemoryTiers(
820+
const MemoryTierConfigs& config) {
821+
memoryTierConfigs = config;
822+
size_t sum_ratios = 0;
823+
size_t sum_sizes = 0;
824+
825+
for (auto tier_config: memoryTierConfigs) {
826+
auto tier_size = tier_config.getSize();
827+
auto tier_ratio = tier_config.getRatio();
828+
if ((!tier_size and !tier_ratio) || (tier_size and tier_ratio)) {
829+
throw std::invalid_argument(
830+
"For each memory tier either size or ratio must be set.");
831+
}
832+
sum_ratios += tier_ratio;
833+
sum_sizes += tier_size;
834+
}
835+
836+
if (sum_ratios) {
837+
if (!getCacheSize()) {
838+
throw std::invalid_argument(
839+
"Total cache size must be specified when size ratios are \
840+
used to specify memory tier sizes.");
841+
} else {
842+
if (getCacheSize() < sum_ratios) {
843+
throw std::invalid_argument(
844+
"Sum of all tier size ratios is greater than total cache size.");
845+
}
846+
// Convert ratios to sizes
847+
sum_sizes = 0;
848+
size_t partition_size = getCacheSize() / sum_ratios;
849+
for (auto& tier_config: memoryTierConfigs) {
850+
tier_config.setSize(partition_size * tier_config.getRatio());
851+
sum_sizes += tier_config.getSize();
852+
}
853+
if (getCacheSize() != sum_sizes) {
854+
// Adjust capacity of the last tier to account for rounding error
855+
memoryTierConfigs.back().setSize(memoryTierConfigs.back().getSize() + \
856+
(getCacheSize() - sum_sizes));
857+
sum_sizes = getCacheSize();
858+
}
859+
}
860+
} else if (sum_sizes) {
861+
if (getCacheSize() && sum_sizes != getCacheSize()) {
862+
throw std::invalid_argument(
863+
"Sum of tier sizes doesn't match total cache size. \
864+
Setting of cache total size is not required when per-tier \
865+
sizes are specified - it is calculated as sum of tier sizes.");
866+
}
867+
} else {
868+
throw std::invalid_argument(
869+
"Either sum of all memory tiers sizes or sum of all ratios \
870+
must be greater than 0.");
871+
}
872+
873+
if (sum_sizes && !getCacheSize()) {
874+
setCacheSize(sum_sizes);
875+
}
876+
877+
return *this;
878+
}
879+
880+
//const std::vector<MemoryTierCacheConfig>& CacheAllocatorConfig<T>::getMemoryTierConfigs() {
881+
template <typename T>
882+
const typename CacheAllocatorConfig<T>::MemoryTierConfigs& CacheAllocatorConfig<T>::getMemoryTierConfigs() {
883+
return memoryTierConfigs;
884+
}
885+
804886
template <typename T>
805887
CacheAllocatorConfig<T>& CacheAllocatorConfig<T>::disableCacheEviction() {
806888
disableEviction = true;
@@ -970,7 +1052,7 @@ std::map<std::string, std::string> CacheAllocatorConfig<T>::serialize() const {
9701052

9711053
configMap["size"] = std::to_string(size);
9721054
configMap["cacheDir"] = cacheDir;
973-
configMap["posixShm"] = usePosixShm ? "set" : "empty";
1055+
configMap["posixShm"] = isUsingPosixShm() ? "set" : "empty";
9741056

9751057
configMap["defaultAllocSizes"] = "";
9761058
// Stringify std::set
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) Intel Corporation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include <string>
20+
21+
namespace facebook {
22+
namespace cachelib {
23+
class MemoryTierCacheConfig {
24+
public:
25+
// Creates instance of MemoryTierCacheConfig for file-backed memory.
26+
// @param path to file which CacheLib will use to map memory from.
27+
// TODO: add fromDirectory, fromAnonymousMemory
28+
static MemoryTierCacheConfig fromFile(const std::string& _file) {
29+
MemoryTierCacheConfig config;
30+
config.path = _file;
31+
return config;
32+
}
33+
34+
// Specifies size of this memory tier. Sizes of tiers must be specified by
35+
// either setting size explicitly or using ratio, mixing of the two is not supported.
36+
MemoryTierCacheConfig& setSize(size_t _size) {
37+
size = _size;
38+
return *this;
39+
}
40+
41+
// Specifies ratio of this memory tier to other tiers. Absolute size
42+
// of each tier can be calculated as:
43+
// cacheSize * tierRatio / Sum of ratios for all tiers; the difference
44+
// between total cache size and sum of all tier sizes resulted from
45+
// round off error is accounted for when calculating the last tier's
46+
// size to make the totals equal.
47+
MemoryTierCacheConfig& setRatio(double _ratio) {
48+
ratio = _ratio;
49+
return *this;
50+
}
51+
52+
size_t getRatio() const noexcept { return ratio; }
53+
54+
size_t getSize() const noexcept { return size; }
55+
56+
const std::string& getPath() const noexcept { return path; }
57+
58+
bool isFileBacked() const {
59+
return !path.empty();
60+
}
61+
62+
// Size of this memory tiers
63+
size_t size{0};
64+
65+
// Ratio is a number of parts of the total cache size to be allocated for this tier.
66+
// E.g. if X is a total cache size, Yi are ratios specified for memory tiers,
67+
// then size of the i-th tier Xi = (X / (Y1 + Y2)) * Yi and X = sum(Xi)
68+
size_t ratio{0};
69+
70+
// Path to file for file system-backed memory tier
71+
// TODO: consider using variant<file, directory, NUMA> to support different
72+
// memory sources
73+
std::string path;
74+
75+
private:
76+
MemoryTierCacheConfig() = default;
77+
};
78+
} // namespace cachelib
79+
} // namespace facebook

cachelib/allocator/TempShmMapping.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ TempShmMapping::TempShmMapping(size_t size)
3434
TempShmMapping::~TempShmMapping() {
3535
try {
3636
if (addr_) {
37-
shmManager_->removeShm(detail::kTempShmCacheName.str());
37+
shmManager_->removeShm(detail::kTempShmCacheName.str(),
38+
PosixSysVSegmentOpts(false /* posix */));
3839
}
3940
if (shmManager_) {
4041
shmManager_.reset();
@@ -77,7 +78,8 @@ void* TempShmMapping::createShmMapping(ShmManager& shmManager,
7778
return shmAddr;
7879
} catch (...) {
7980
if (shmAddr) {
80-
shmManager.removeShm(detail::kTempShmCacheName.str());
81+
shmManager.removeShm(detail::kTempShmCacheName.str(),
82+
PosixSysVSegmentOpts(false /* posix */));
8183
} else {
8284
munmap(addr, size);
8385
}

cachelib/allocator/memory/tests/SlabAllocatorTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,7 @@ TEST_F(SlabAllocatorTest, AdviseRelease) {
584584
shmName += std::to_string(::getpid());
585585
shmManager.createShm(shmName, allocSize, memory);
586586

587-
SCOPE_EXIT { shmManager.removeShm(shmName); };
587+
SCOPE_EXIT { shmManager.removeShm(shmName, PosixSysVSegmentOpts(false)); };
588588

589589
memory = util::align(Slab::kSize, size, memory, allocSize);
590590

@@ -714,7 +714,7 @@ TEST_F(SlabAllocatorTest, AdviseSaveRestore) {
714714
ShmManager shmManager(cacheDir, false /* posix */);
715715
shmManager.createShm(shmName, allocSize, memory);
716716

717-
SCOPE_EXIT { shmManager.removeShm(shmName); };
717+
SCOPE_EXIT { shmManager.removeShm(shmName, PosixSysVSegmentOpts(false)); };
718718

719719
{
720720
SlabAllocator s(memory, size, config);

0 commit comments

Comments
 (0)