mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 23:07:18 +03:00
allow 1000 background FUSE requests
Summary: DurhamG discovered that setting max_background in fuse_init_out allows a larger number of concurrent FUSE requests. The documentation indicates it's intended to affect background requests like readahead, but empirically you can observe increased live FUSE requests with `rg -j200` and `eden top`. Default to 1000 because EdenFS can handle a large amount of concurrency and we want to avoid blob and tree fetches to block FUSE IO when not necessary. Reviewed By: xavierd Differential Revision: D27526032 fbshipit-source-id: 0d3fa383772f719524a9be84b73fa2eb599580d7
This commit is contained in:
parent
48b35a0a5e
commit
c5b895d7f2
@ -354,6 +354,18 @@ class EdenConfig : private ConfigSettingManager {
|
||||
|
||||
// [fuse]
|
||||
|
||||
/**
|
||||
* The maximum number of concurrent FUSE requests we allow the kernel to send
|
||||
* us.
|
||||
*
|
||||
* Linux FUSE defaults to 12, but EdenFS can handle a great deal of
|
||||
* concurrency.
|
||||
*/
|
||||
ConfigSetting<int32_t> fuseMaximumRequests{
|
||||
"fuse:max-concurrent-requests",
|
||||
1000,
|
||||
this};
|
||||
|
||||
/**
|
||||
* The maximum time duration allowed for a fuse request. If a request exceeds
|
||||
* this amount of time, an ETIMEDOUT error will be returned to the kernel to
|
||||
@ -412,6 +424,15 @@ class EdenConfig : private ConfigSettingManager {
|
||||
1000,
|
||||
this};
|
||||
|
||||
/**
|
||||
* The maximum number of concurrent requests allowed into userspace from the
|
||||
* kernel. This corresponds to fuse_init_out::max_background. The
|
||||
* documentation this applies to only readaheads and async direct IO, but
|
||||
* empirically we have observed the number of concurrent requests is limited
|
||||
* to 12 (FUSE_DEFAULT_MAX_BACKGROUND) unless this is set high.
|
||||
*/
|
||||
ConfigSetting<uint32_t> maximumFuseRequests{"fuse:max-requests", 1000, this};
|
||||
|
||||
/**
|
||||
* Buffer size for read and writes requests. Default to 1 MiB.
|
||||
*/
|
||||
|
@ -782,7 +782,8 @@ FuseChannel::FuseChannel(
|
||||
folly::Duration requestTimeout,
|
||||
Notifications* notifications,
|
||||
CaseSensitivity caseSensitive,
|
||||
bool requireUtf8Path)
|
||||
bool requireUtf8Path,
|
||||
int32_t maximumBackgroundRequests)
|
||||
: bufferSize_(std::max(size_t(getpagesize()) + 0x1000, MIN_BUFSIZE)),
|
||||
numThreads_(numThreads),
|
||||
dispatcher_(std::move(dispatcher)),
|
||||
@ -790,8 +791,9 @@ FuseChannel::FuseChannel(
|
||||
mountPath_(mountPath),
|
||||
requestTimeout_(requestTimeout),
|
||||
notifications_(notifications),
|
||||
caseSensitive_(caseSensitive),
|
||||
requireUtf8Path_(requireUtf8Path),
|
||||
caseSensitive_{caseSensitive},
|
||||
requireUtf8Path_{requireUtf8Path},
|
||||
maximumBackgroundRequests_{maximumBackgroundRequests},
|
||||
fuseDevice_(std::move(fuseDevice)),
|
||||
processAccessLog_(std::move(processNameCache)),
|
||||
traceDetailedArguments_(std::make_shared<std::atomic<size_t>>(0)),
|
||||
@ -1368,9 +1370,22 @@ void FuseChannel::readInitPacket() {
|
||||
connInfo.major = init.init.major;
|
||||
connInfo.minor = init.init.minor;
|
||||
connInfo.max_write = bufferSize_ - 4096;
|
||||
|
||||
connInfo.max_readahead = init.init.max_readahead;
|
||||
|
||||
int32_t max_background = maximumBackgroundRequests_;
|
||||
if (max_background > 65535) {
|
||||
max_background = 65535;
|
||||
} else if (max_background < 0) {
|
||||
max_background = 0;
|
||||
}
|
||||
// The libfuse documentation says this only applies to background
|
||||
// requests like readahead prefetches and direct I/O, but we have
|
||||
// empirically observed that, on Linux, without setting this value,
|
||||
// `rg -j 200` limits the number of active FUSE requests to 16.
|
||||
connInfo.max_background = static_cast<uint32_t>(max_background);
|
||||
// Allow the kernel to default connInfo.congestion_threshold. Linux
|
||||
// picks 3/4 of max_background.
|
||||
|
||||
const auto capable = init.init.flags;
|
||||
auto& want = connInfo.flags;
|
||||
|
||||
|
@ -228,7 +228,8 @@ class FuseChannel {
|
||||
folly::Duration requestTimeout,
|
||||
Notifications* FOLLY_NULLABLE notifications,
|
||||
CaseSensitivity caseSensitive,
|
||||
bool requireUtf8Path);
|
||||
bool requireUtf8Path,
|
||||
int32_t maximumBackgroundRequests);
|
||||
|
||||
/**
|
||||
* Destroy the FuseChannel.
|
||||
@ -742,6 +743,7 @@ class FuseChannel {
|
||||
Notifications* const notifications_;
|
||||
CaseSensitivity caseSensitive_;
|
||||
bool requireUtf8Path_;
|
||||
int32_t maximumBackgroundRequests_;
|
||||
|
||||
/*
|
||||
* connInfo_ is modified during the initialization process,
|
||||
|
@ -135,7 +135,8 @@ int main(int argc, char** argv) {
|
||||
std::chrono::seconds(60),
|
||||
nullptr,
|
||||
CaseSensitivity::Sensitive,
|
||||
true));
|
||||
true,
|
||||
12 /* the default on Linux */));
|
||||
|
||||
XLOG(INFO) << "Starting FUSE...";
|
||||
auto completionFuture = channel->initialize().get();
|
||||
|
@ -79,7 +79,8 @@ class FuseChannelTest : public ::testing::Test {
|
||||
std::chrono::seconds(60),
|
||||
nullptr,
|
||||
CaseSensitivity::Sensitive,
|
||||
true));
|
||||
true,
|
||||
12));
|
||||
}
|
||||
|
||||
FuseChannel::StopFuture performInit(
|
||||
|
@ -1280,7 +1280,8 @@ std::unique_ptr<FuseChannel, FuseChannelDeleter> makeFuseChannel(
|
||||
edenConfig->fuseRequestTimeout.getValue()),
|
||||
mount->getServerState()->getNotifications(),
|
||||
mount->getCheckoutConfig()->getCaseSensitive(),
|
||||
mount->getCheckoutConfig()->getRequireUtf8Path())};
|
||||
mount->getCheckoutConfig()->getRequireUtf8Path(),
|
||||
edenConfig->fuseMaximumRequests.getValue())};
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user