-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Use Envoy cpuset size to set the default number or worker threads #5975
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9c96541
aa2955c
61516d2
da9cff6
dd5b915
736a028
7cfab2b
d2c2235
1986a39
cdff7ba
7e33c82
af55037
c9eb033
d00e04e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #pragma once | ||
|
|
||
| #include <memory> | ||
| #include <string> | ||
|
|
||
| namespace Envoy { | ||
| namespace Api { | ||
| /** | ||
| * SysCallResult holds the rc and errno values resulting from a system call. | ||
| */ | ||
| template <typename T> struct SysCallResult { | ||
|
|
||
| /** | ||
| * The return code from the system call. | ||
| */ | ||
| T rc_; | ||
|
|
||
| /** | ||
| * The errno value as captured after the system call. | ||
| */ | ||
| int errno_; | ||
| }; | ||
|
|
||
| typedef SysCallResult<int> SysCallIntResult; | ||
| typedef SysCallResult<ssize_t> SysCallSizeResult; | ||
| typedef SysCallResult<void*> SysCallPtrResult; | ||
| typedef SysCallResult<std::string> SysCallStringResult; | ||
| typedef SysCallResult<bool> SysCallBoolResult; | ||
|
|
||
| } // namespace Api | ||
| } // namespace Envoy |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| #pragma once | ||
|
|
||
| #if !defined(__linux__) | ||
| #error "Linux platform file is part of non-Linux build." | ||
| #endif | ||
|
|
||
| #include <sched.h> | ||
|
|
||
| #include "envoy/api/os_sys_calls_common.h" | ||
| #include "envoy/common/pure.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Api { | ||
|
|
||
| class LinuxOsSysCalls { | ||
| public: | ||
| virtual ~LinuxOsSysCalls() {} | ||
|
|
||
| /** | ||
| * @see sched_getaffinity (man 2 sched_getaffinity) | ||
| */ | ||
| virtual SysCallIntResult sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t* mask) PURE; | ||
| }; | ||
|
|
||
| typedef std::unique_ptr<LinuxOsSysCalls> LinuxOsSysCallsPtr; | ||
|
|
||
| } // namespace Api | ||
| } // namespace Envoy | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,8 +22,16 @@ envoy_cc_library( | |
|
|
||
| envoy_cc_library( | ||
| name = "os_sys_calls_lib", | ||
| srcs = ["os_sys_calls_impl.cc"], | ||
| hdrs = ["os_sys_calls_impl.h"], | ||
| srcs = ["os_sys_calls_impl.cc"] + select({ | ||
| "@bazel_tools//src/conditions:linux_x86_64": ["os_sys_calls_impl_linux.cc"], | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FTR, this breaks the Google import since we don't have |
||
| "@bazel_tools//src/conditions:linux_aarch64": ["os_sys_calls_impl_linux.cc"], | ||
| "//conditions:default": [], | ||
| }), | ||
| hdrs = ["os_sys_calls_impl.h"] + select({ | ||
| "@bazel_tools//src/conditions:linux_x86_64": ["os_sys_calls_impl_linux.h"], | ||
| "@bazel_tools//src/conditions:linux_aarch64": ["os_sys_calls_impl_linux.h"], | ||
| "//conditions:default": [], | ||
| }), | ||
| deps = [ | ||
| "//include/envoy/api:os_sys_calls_interface", | ||
| "//source/common/singleton:threadsafe_singleton", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| #if !defined(__linux__) | ||
| #error "Linux platform file is part of non-Linux build." | ||
| #endif | ||
|
|
||
| #include "common/api/os_sys_calls_impl_linux.h" | ||
|
|
||
| #include <errno.h> | ||
| #include <sched.h> | ||
|
|
||
| namespace Envoy { | ||
| namespace Api { | ||
|
|
||
| SysCallIntResult LinuxOsSysCallsImpl::sched_getaffinity(pid_t pid, size_t cpusetsize, | ||
| cpu_set_t* mask) { | ||
| const int rc = ::sched_getaffinity(pid, cpusetsize, mask); | ||
| return {rc, errno}; | ||
| } | ||
|
|
||
| } // namespace Api | ||
| } // namespace Envoy |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| #pragma once | ||
|
|
||
| #if !defined(__linux__) | ||
| #error "Linux platform file is part of non-Linux build." | ||
| #endif | ||
|
|
||
| #include "envoy/api/os_sys_calls_linux.h" | ||
|
|
||
| #include "common/singleton/threadsafe_singleton.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Api { | ||
|
|
||
| class LinuxOsSysCallsImpl : public LinuxOsSysCalls { | ||
| public: | ||
| // Api::LinuxOsSysCalls | ||
| SysCallIntResult sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t* mask) override; | ||
| }; | ||
|
|
||
| typedef ThreadSafeSingleton<LinuxOsSysCallsImpl> LinuxOsSysCallsSingleton; | ||
|
|
||
| } // namespace Api | ||
| } // namespace Envoy |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,8 @@ | |
| #include "common/common/version.h" | ||
| #include "common/protobuf/utility.h" | ||
|
|
||
| #include "server/options_impl_platform.h" | ||
|
|
||
| #include "absl/strings/str_split.h" | ||
| #include "spdlog/spdlog.h" | ||
| #include "tclap/CmdLine.h" | ||
|
|
@@ -117,6 +119,8 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv, | |
| "Disable hot restart functionality", cmd, false); | ||
| TCLAP::SwitchArg enable_mutex_tracing( | ||
| "", "enable-mutex-tracing", "Enable mutex contention tracing functionality", cmd, false); | ||
| TCLAP::SwitchArg cpuset_threads( | ||
| "", "cpuset-threads", "Get the default # of worker threads from cpuset size", cmd, false); | ||
|
|
||
| cmd.setExceptionHandling(false); | ||
| try { | ||
|
|
@@ -154,6 +158,8 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv, | |
|
|
||
| mutex_tracing_enabled_ = enable_mutex_tracing.getValue(); | ||
|
|
||
| cpuset_threads_ = cpuset_threads.getValue(); | ||
|
|
||
| log_level_ = default_log_level; | ||
| for (size_t i = 0; i < ARRAY_SIZE(spdlog::level::level_string_views); i++) { | ||
| if (log_level.getValue() == spdlog::level::level_string_views[i]) { | ||
|
|
@@ -188,7 +194,20 @@ OptionsImpl::OptionsImpl(int argc, const char* const* argv, | |
|
|
||
| // For base ID, scale what the user inputs by 10 so that we have spread for domain sockets. | ||
| base_id_ = base_id.getValue() * 10; | ||
| concurrency_ = std::max(1U, concurrency.getValue()); | ||
|
|
||
| if (!concurrency.isSet() && cpuset_threads_) { | ||
| // The 'concurrency' command line option wasn't set but the 'cpuset-threads' | ||
|
||
| // option was set. Use the number of CPUs assigned to the process cpuset, if | ||
| // that can be known. | ||
| concurrency_ = OptionsImplPlatform::getCpuCount(); | ||
| } else { | ||
| if (concurrency.isSet() && cpuset_threads_ && cpuset_threads.isSet()) { | ||
|
||
| ENVOY_LOG(warn, "Both --concurrency and --cpuset-threads options are set; not applying " | ||
| "--cpuset-threads."); | ||
| } | ||
| concurrency_ = std::max(1U, concurrency.getValue()); | ||
| } | ||
|
|
||
| config_path_ = config_path.getValue(); | ||
| config_yaml_ = config_yaml.getValue(); | ||
| allow_unknown_fields_ = allow_unknown_fields.getValue(); | ||
|
|
@@ -291,6 +310,7 @@ Server::CommandLineOptionsPtr OptionsImpl::toCommandLineOptions() const { | |
| command_line_options->set_max_obj_name_len(statsOptions().maxObjNameLength()); | ||
| command_line_options->set_disable_hot_restart(hotRestartDisabled()); | ||
| command_line_options->set_enable_mutex_tracing(mutexTracingEnabled()); | ||
| command_line_options->set_cpuset_threads(cpusetThreadsEnabled()); | ||
| command_line_options->set_restart_epoch(restartEpoch()); | ||
| return command_line_options; | ||
| } | ||
|
|
@@ -303,6 +323,6 @@ OptionsImpl::OptionsImpl(const std::string& service_cluster, const std::string& | |
| service_cluster_(service_cluster), service_node_(service_node), service_zone_(service_zone), | ||
| file_flush_interval_msec_(10000), drain_time_(600), parent_shutdown_time_(900), | ||
| mode_(Server::Mode::Serve), max_stats_(ENVOY_DEFAULT_MAX_STATS), hot_restart_disabled_(false), | ||
| signal_handling_enabled_(true), mutex_tracing_enabled_(false) {} | ||
| signal_handling_enabled_(true), mutex_tracing_enabled_(false), cpuset_threads_(false) {} | ||
|
|
||
| } // namespace Envoy | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #pragma once | ||
|
|
||
| #include <cstdint> | ||
|
|
||
| #include "common/common/logger.h" | ||
|
|
||
| namespace Envoy { | ||
| class OptionsImplPlatform : protected Logger::Loggable<Logger::Id::config> { | ||
| public: | ||
| static uint32_t getCpuCount(); | ||
| }; | ||
| } // namespace Envoy |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| #include <thread> | ||
|
|
||
| #include "common/common/logger.h" | ||
|
|
||
| #include "server/options_impl_platform.h" | ||
|
|
||
| namespace Envoy { | ||
|
|
||
| uint32_t OptionsImplPlatform::getCpuCount() { | ||
| ENVOY_LOG(warn, "CPU number provided by HW thread count (instead of cpuset)."); | ||
| return std::thread::hardware_concurrency(); | ||
| } | ||
|
|
||
| } // namespace Envoy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add something like:
(or something like that). Same for the impl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, done.