[resource_quota] Move experiments to the experiments framework (#30830)

* fix

* fix tests

* fix

* Automated change: Fix sanity tests

* better expansion

* bleh

* fix

Co-authored-by: ctiller <ctiller@users.noreply.github.com>
pull/30076/head
Craig Tiller 2 years ago committed by GitHub
parent 6ee7a647bf
commit e705b2e3c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      BUILD
  2. 122
      CMakeLists.txt
  3. 5
      bazel/experiments.bzl
  4. 110
      bazel/grpc_build_system.bzl
  5. 298
      build_autogenerated.yaml
  6. 5
      src/core/ext/transport/chttp2/transport/flow_control.cc
  7. 12
      src/core/lib/experiments/experiments.cc
  8. 11
      src/core/lib/experiments/experiments.h
  9. 21
      src/core/lib/experiments/experiments.yaml
  10. 27
      src/core/lib/resource_quota/memory_quota.cc
  11. 25
      src/core/lib/resource_quota/memory_quota.h
  12. 4
      test/core/promise/BUILD
  13. 6
      test/core/promise/arena_promise_test.cc
  14. 16
      test/core/resource_quota/BUILD
  15. 11
      test/core/resource_quota/arena_test.cc
  16. 8
      test/core/resource_quota/memory_quota_stress_test.cc
  17. 10
      test/core/resource_quota/memory_quota_test.cc
  18. 6
      test/core/resource_quota/resource_quota_test.cc

@ -1920,6 +1920,7 @@ grpc_cc_library(
"activity", "activity",
"event_engine_memory_allocator", "event_engine_memory_allocator",
"exec_ctx_wakeup_scheduler", "exec_ctx_wakeup_scheduler",
"experiments",
"gpr", "gpr",
"grpc_trace", "grpc_trace",
"loop", "loop",
@ -6609,6 +6610,7 @@ grpc_cc_library(
deps = [ deps = [
"bdp_estimator", "bdp_estimator",
"exec_ctx", "exec_ctx",
"experiments",
"gpr", "gpr",
"grpc_trace", "grpc_trace",
"memory_quota", "memory_quota",

122
CMakeLists.txt generated

@ -5796,28 +5796,6 @@ endif()
if(gRPC_BUILD_TESTS) if(gRPC_BUILD_TESTS)
add_executable(arena_promise_test add_executable(arena_promise_test
src/core/ext/upb-generated/google/protobuf/any.upb.c
src/core/ext/upb-generated/google/rpc/status.upb.c
src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/error.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/iomgr_internal.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/arena.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/periodic_update.cc
src/core/lib/resource_quota/resource_quota.cc
src/core/lib/resource_quota/thread_quota.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
test/core/promise/arena_promise_test.cc test/core/promise/arena_promise_test.cc
third_party/googletest/googletest/src/gtest-all.cc third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc third_party/googletest/googlemock/src/gmock-all.cc
@ -5845,13 +5823,7 @@ target_include_directories(arena_promise_test
target_link_libraries(arena_promise_test target_link_libraries(arena_promise_test
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
absl::any_invocable grpc_test_util_unsecure
absl::function_ref
absl::type_traits
absl::statusor
absl::utility
gpr
upb
) )
@ -5887,6 +5859,7 @@ target_link_libraries(arena_test
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
grpc grpc
grpc_test_util_unsecure
) )
@ -7565,6 +7538,8 @@ add_executable(chunked_vector_test
src/core/ext/upb-generated/google/rpc/status.upb.c src/core/ext/upb-generated/google/rpc/status.upb.c
src/core/lib/debug/trace.cc src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc src/core/lib/event_engine/memory_allocator.cc
src/core/lib/experiments/config.cc
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/status_helper.cc src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc src/core/lib/gprpp/time.cc
src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/combiner.cc
@ -10053,6 +10028,8 @@ add_executable(flow_control_test
src/core/ext/upb-generated/google/rpc/status.upb.c src/core/ext/upb-generated/google/rpc/status.upb.c
src/core/lib/debug/trace.cc src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc src/core/lib/event_engine/memory_allocator.cc
src/core/lib/experiments/config.cc
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/status_helper.cc src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc src/core/lib/gprpp/time.cc
src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/combiner.cc
@ -10117,6 +10094,8 @@ add_executable(for_each_test
src/core/ext/upb-generated/google/rpc/status.upb.c src/core/ext/upb-generated/google/rpc/status.upb.c
src/core/lib/debug/trace.cc src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc src/core/lib/event_engine/memory_allocator.cc
src/core/lib/experiments/config.cc
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/status_helper.cc src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc src/core/lib/gprpp/time.cc
src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/combiner.cc
@ -13308,25 +13287,6 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
add_executable(memory_quota_stress_test add_executable(memory_quota_stress_test
src/core/ext/upb-generated/google/protobuf/any.upb.c
src/core/ext/upb-generated/google/rpc/status.upb.c
src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/error.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/iomgr_internal.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/periodic_update.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
test/core/resource_quota/memory_quota_stress_test.cc test/core/resource_quota/memory_quota_stress_test.cc
third_party/googletest/googletest/src/gtest-all.cc third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc third_party/googletest/googlemock/src/gmock-all.cc
@ -13354,13 +13314,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX)
target_link_libraries(memory_quota_stress_test target_link_libraries(memory_quota_stress_test
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
absl::any_invocable grpc_test_util_unsecure
absl::function_ref
absl::type_traits
absl::statusor
absl::utility
gpr
upb
) )
@ -13369,25 +13323,6 @@ endif()
if(gRPC_BUILD_TESTS) if(gRPC_BUILD_TESTS)
add_executable(memory_quota_test add_executable(memory_quota_test
src/core/ext/upb-generated/google/protobuf/any.upb.c
src/core/ext/upb-generated/google/rpc/status.upb.c
src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/error.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/iomgr_internal.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/periodic_update.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
test/core/resource_quota/memory_quota_test.cc test/core/resource_quota/memory_quota_test.cc
third_party/googletest/googletest/src/gtest-all.cc third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc third_party/googletest/googlemock/src/gmock-all.cc
@ -13415,13 +13350,7 @@ target_include_directories(memory_quota_test
target_link_libraries(memory_quota_test target_link_libraries(memory_quota_test
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
absl::any_invocable grpc_test_util_unsecure
absl::function_ref
absl::type_traits
absl::statusor
absl::utility
gpr
upb
) )
@ -14440,6 +14369,8 @@ add_executable(pipe_test
src/core/ext/upb-generated/google/rpc/status.upb.c src/core/ext/upb-generated/google/rpc/status.upb.c
src/core/lib/debug/trace.cc src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc src/core/lib/event_engine/memory_allocator.cc
src/core/lib/experiments/config.cc
src/core/lib/experiments/experiments.cc
src/core/lib/gprpp/status_helper.cc src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc src/core/lib/gprpp/time.cc
src/core/lib/iomgr/combiner.cc src/core/lib/iomgr/combiner.cc
@ -15471,27 +15402,6 @@ endif()
if(gRPC_BUILD_TESTS) if(gRPC_BUILD_TESTS)
add_executable(resource_quota_test add_executable(resource_quota_test
src/core/ext/upb-generated/google/protobuf/any.upb.c
src/core/ext/upb-generated/google/rpc/status.upb.c
src/core/lib/debug/trace.cc
src/core/lib/event_engine/memory_allocator.cc
src/core/lib/gprpp/status_helper.cc
src/core/lib/gprpp/time.cc
src/core/lib/iomgr/combiner.cc
src/core/lib/iomgr/error.cc
src/core/lib/iomgr/exec_ctx.cc
src/core/lib/iomgr/executor.cc
src/core/lib/iomgr/iomgr_internal.cc
src/core/lib/promise/activity.cc
src/core/lib/resource_quota/memory_quota.cc
src/core/lib/resource_quota/periodic_update.cc
src/core/lib/resource_quota/resource_quota.cc
src/core/lib/resource_quota/thread_quota.cc
src/core/lib/resource_quota/trace.cc
src/core/lib/slice/percent_encoding.cc
src/core/lib/slice/slice.cc
src/core/lib/slice/slice_refcount.cc
src/core/lib/slice/slice_string_helpers.cc
test/core/resource_quota/resource_quota_test.cc test/core/resource_quota/resource_quota_test.cc
third_party/googletest/googletest/src/gtest-all.cc third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc third_party/googletest/googlemock/src/gmock-all.cc
@ -15519,13 +15429,7 @@ target_include_directories(resource_quota_test
target_link_libraries(resource_quota_test target_link_libraries(resource_quota_test
${_gRPC_PROTOBUF_LIBRARIES} ${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES} ${_gRPC_ALLTARGETS_LIBRARIES}
absl::any_invocable grpc_test_util_unsecure
absl::function_ref
absl::type_traits
absl::statusor
absl::utility
gpr
upb
) )

@ -27,6 +27,11 @@ EXPERIMENTS = {
"tcp_rcv_lowat", "tcp_rcv_lowat",
"tcp_read_chunks", "tcp_read_chunks",
], ],
"resource_quota_test": [
"memory_pressure_controller",
"periodic_resource_quota_reclamation",
"unconstrained_max_quota_buffer_size",
],
} }
NEGATED_EXPERIMENTS = { NEGATED_EXPERIMENTS = {

@ -260,7 +260,7 @@ def ios_cc_test(
deps = ios_test_deps, deps = ios_test_deps,
) )
def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_event_engine): def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_polling, uses_event_engine):
"""Common logic used to parameterize tests for every poller and EventEngine and experiment. """Common logic used to parameterize tests for every poller and EventEngine and experiment.
Args: Args:
@ -270,6 +270,7 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_event_engin
tags: base tags tags: base tags
args: base args args: base args
exclude_pollers: list of poller names to exclude for this set of tests. exclude_pollers: list of poller names to exclude for this set of tests.
uses_polling: set to False if the test is not sensitive to polling methodology.
uses_event_engine: set to False if the test is not sensitive to uses_event_engine: set to False if the test is not sensitive to
EventEngine implementation differences EventEngine implementation differences
@ -278,30 +279,9 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_event_engin
""" """
poller_config = [] poller_config = []
# On linux we run the same test with the default EventEngine, once for each if not uses_polling:
# poller tags = tags + ["no_uses_polling"]
for poller in POLLERS:
if poller in exclude_pollers:
continue
poller_config.append({
"name": name + "@poller=" + poller,
"srcs": srcs,
"deps": deps,
"tags": (tags + EVENT_ENGINES["default"]["tags"] + [
"no_windows",
"no_mac",
"bazel_only",
]),
"args": args + ["--poller=" + poller],
})
# Now generate one test for each subsequent EventEngine, all using the
# default poller. These tests will have `@engine=<name>` appended to the
# test target name. If a test target name has no `@engine=<name>` component,
# that indicates that the default EventEngine is being used.
if not uses_event_engine:
# The poller tests exercise the default engine on Linux. This test
# handles other platforms.
poller_config.append({ poller_config.append({
"name": name, "name": name,
"srcs": srcs, "srcs": srcs,
@ -310,23 +290,55 @@ def expand_tests(name, srcs, deps, tags, args, exclude_pollers, uses_event_engin
"args": args, "args": args,
}) })
else: else:
for engine_name, engine in EVENT_ENGINES.items(): # On linux we run the same test with the default EventEngine, once for each
test_name = name + "@engine=" + engine_name # poller
test_tags = tags + engine["tags"] + ["bazel_only"] for poller in POLLERS:
test_args = args + ["--engine=" + engine_name] if poller in exclude_pollers:
if engine_name == "default": continue
# The poller tests exercise the default engine on Linux. poller_config.append({
# This test handles other platforms. "name": name + "@poller=" + poller,
test_name = name "srcs": srcs,
test_tags = tags + engine["tags"] + ["no_linux"] "deps": deps,
test_args = args "tags": (tags + EVENT_ENGINES["default"]["tags"] + [
"no_windows",
"no_mac",
"bazel_only",
]),
"args": args + ["--poller=" + poller],
})
# Now generate one test for each subsequent EventEngine, all using the
# default poller. These tests will have `@engine=<name>` appended to the
# test target name. If a test target name has no `@engine=<name>` component,
# that indicates that the default EventEngine is being used.
if not uses_event_engine:
# The poller tests exercise the default engine on Linux. This test
# handles other platforms.
poller_config.append({ poller_config.append({
"name": test_name, "name": name,
"srcs": srcs, "srcs": srcs,
"deps": deps, "deps": deps,
"tags": test_tags, "tags": tags + ["no_linux"],
"args": test_args, "args": args,
}) })
else:
for engine_name, engine in EVENT_ENGINES.items():
test_name = name + "@engine=" + engine_name
test_tags = tags + engine["tags"] + ["bazel_only"]
test_args = args + ["--engine=" + engine_name]
if engine_name == "default":
# The poller tests exercise the default engine on Linux.
# This test handles other platforms.
test_name = name
test_tags = tags + engine["tags"] + ["no_linux"]
test_args = args
poller_config.append({
"name": test_name,
"srcs": srcs,
"deps": deps,
"tags": test_tags,
"args": test_args,
})
experiments = {} experiments = {}
for tag in tags: for tag in tags:
@ -441,19 +453,8 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
args = args, args = args,
**test_args **test_args
) )
if not uses_polling:
# the test behavior doesn't depend on polling, just generate the test
native.cc_test(
name = name,
srcs = srcs,
tags = tags + ["no_uses_polling"],
deps = core_deps,
args = args,
**test_args
)
return
for poller_config in expand_tests(name, srcs, core_deps, tags, args, exclude_pollers, uses_event_engine): for poller_config in expand_tests(name, srcs, core_deps, tags, args, exclude_pollers, uses_polling, uses_event_engine):
native.cc_test( native.cc_test(
name = poller_config["name"], name = poller_config["name"],
srcs = poller_config["srcs"], srcs = poller_config["srcs"],
@ -545,17 +546,8 @@ def grpc_sh_test(name, srcs = [], args = [], data = [], uses_polling = True, siz
"shard_count": shard_count, "shard_count": shard_count,
"flaky": flaky, "flaky": flaky,
} }
if not uses_polling:
native.sh_test(
name = name,
srcs = srcs,
args = args,
tags = tags,
**test_args
)
return
for poller_config in expand_tests(name, srcs, [], tags, args, exclude_pollers, uses_event_engine): for poller_config in expand_tests(name, srcs, [], tags, args, exclude_pollers, uses_polling, uses_event_engine):
native.sh_test( native.sh_test(
name = poller_config["name"], name = poller_config["name"],
srcs = poller_config["srcs"], srcs = poller_config["srcs"],

@ -4053,83 +4053,11 @@ targets:
build: test build: test
language: c++ language: c++
headers: headers:
- src/core/ext/upb-generated/google/protobuf/any.upb.h
- src/core/ext/upb-generated/google/rpc/status.upb.h
- src/core/lib/debug/trace.h
- src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/cpp_impl_of.h
- src/core/lib/gprpp/debug_location.h
- src/core/lib/gprpp/no_destruct.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
- src/core/lib/gprpp/time.h
- src/core/lib/iomgr/closure.h
- src/core/lib/iomgr/combiner.h
- src/core/lib/iomgr/error.h
- src/core/lib/iomgr/exec_ctx.h
- src/core/lib/iomgr/executor.h
- src/core/lib/iomgr/iomgr_internal.h
- src/core/lib/promise/activity.h
- src/core/lib/promise/arena_promise.h
- src/core/lib/promise/context.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/detail/status.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/arena.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/periodic_update.h
- src/core/lib/resource_quota/resource_quota.h
- src/core/lib/resource_quota/thread_quota.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/slice/percent_encoding.h
- src/core/lib/slice/slice.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
- src/core/lib/slice/slice_string_helpers.h
- test/core/promise/test_context.h - test/core/promise/test_context.h
src: src:
- src/core/ext/upb-generated/google/protobuf/any.upb.c
- src/core/ext/upb-generated/google/rpc/status.upb.c
- src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/combiner.cc
- src/core/lib/iomgr/error.cc
- src/core/lib/iomgr/exec_ctx.cc
- src/core/lib/iomgr/executor.cc
- src/core/lib/iomgr/iomgr_internal.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/arena.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/periodic_update.cc
- src/core/lib/resource_quota/resource_quota.cc
- src/core/lib/resource_quota/thread_quota.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- test/core/promise/arena_promise_test.cc - test/core/promise/arena_promise_test.cc
deps: deps:
- absl/functional:any_invocable - grpc_test_util_unsecure
- absl/functional:function_ref
- absl/meta:type_traits
- absl/status:statusor
- absl/utility:utility
- gpr
- upb
uses_polling: false uses_polling: false
- name: arena_test - name: arena_test
gtest: true gtest: true
@ -4140,6 +4068,7 @@ targets:
- test/core/resource_quota/arena_test.cc - test/core/resource_quota/arena_test.cc
deps: deps:
- grpc - grpc
- grpc_test_util_unsecure
uses_polling: false uses_polling: false
- name: async_end2end_test - name: async_end2end_test
gtest: true gtest: true
@ -4903,6 +4832,8 @@ targets:
- src/core/ext/upb-generated/google/protobuf/any.upb.h - src/core/ext/upb-generated/google/protobuf/any.upb.h
- src/core/ext/upb-generated/google/rpc/status.upb.h - src/core/ext/upb-generated/google/rpc/status.upb.h
- src/core/lib/debug/trace.h - src/core/lib/debug/trace.h
- src/core/lib/experiments/config.h
- src/core/lib/experiments/experiments.h
- src/core/lib/gprpp/atomic_utils.h - src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h - src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/chunked_vector.h - src/core/lib/gprpp/chunked_vector.h
@ -4949,6 +4880,8 @@ targets:
- src/core/ext/upb-generated/google/rpc/status.upb.c - src/core/ext/upb-generated/google/rpc/status.upb.c
- src/core/lib/debug/trace.cc - src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc - src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/experiments/config.cc
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/status_helper.cc - src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc - src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/combiner.cc
@ -6133,6 +6066,8 @@ targets:
- src/core/ext/upb-generated/google/protobuf/any.upb.h - src/core/ext/upb-generated/google/protobuf/any.upb.h
- src/core/ext/upb-generated/google/rpc/status.upb.h - src/core/ext/upb-generated/google/rpc/status.upb.h
- src/core/lib/debug/trace.h - src/core/lib/debug/trace.h
- src/core/lib/experiments/config.h
- src/core/lib/experiments/experiments.h
- src/core/lib/gprpp/atomic_utils.h - src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h - src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/cpp_impl_of.h - src/core/lib/gprpp/cpp_impl_of.h
@ -6180,6 +6115,8 @@ targets:
- src/core/ext/upb-generated/google/rpc/status.upb.c - src/core/ext/upb-generated/google/rpc/status.upb.c
- src/core/lib/debug/trace.cc - src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc - src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/experiments/config.cc
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/status_helper.cc - src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc - src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/combiner.cc
@ -6217,6 +6154,8 @@ targets:
- src/core/ext/upb-generated/google/protobuf/any.upb.h - src/core/ext/upb-generated/google/protobuf/any.upb.h
- src/core/ext/upb-generated/google/rpc/status.upb.h - src/core/ext/upb-generated/google/rpc/status.upb.h
- src/core/lib/debug/trace.h - src/core/lib/debug/trace.h
- src/core/lib/experiments/config.h
- src/core/lib/experiments/experiments.h
- src/core/lib/gprpp/atomic_utils.h - src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h - src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/cpp_impl_of.h - src/core/lib/gprpp/cpp_impl_of.h
@ -6270,6 +6209,8 @@ targets:
- src/core/ext/upb-generated/google/rpc/status.upb.c - src/core/ext/upb-generated/google/rpc/status.upb.c
- src/core/lib/debug/trace.cc - src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc - src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/experiments/config.cc
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/status_helper.cc - src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc - src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/combiner.cc
@ -7732,75 +7673,11 @@ targets:
gtest: true gtest: true
build: test build: test
language: c++ language: c++
headers: headers: []
- src/core/ext/upb-generated/google/protobuf/any.upb.h
- src/core/ext/upb-generated/google/rpc/status.upb.h
- src/core/lib/debug/trace.h
- src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/debug_location.h
- src/core/lib/gprpp/no_destruct.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
- src/core/lib/gprpp/time.h
- src/core/lib/iomgr/closure.h
- src/core/lib/iomgr/combiner.h
- src/core/lib/iomgr/error.h
- src/core/lib/iomgr/exec_ctx.h
- src/core/lib/iomgr/executor.h
- src/core/lib/iomgr/iomgr_internal.h
- src/core/lib/promise/activity.h
- src/core/lib/promise/context.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/detail/status.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/periodic_update.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/slice/percent_encoding.h
- src/core/lib/slice/slice.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
- src/core/lib/slice/slice_string_helpers.h
src: src:
- src/core/ext/upb-generated/google/protobuf/any.upb.c
- src/core/ext/upb-generated/google/rpc/status.upb.c
- src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/combiner.cc
- src/core/lib/iomgr/error.cc
- src/core/lib/iomgr/exec_ctx.cc
- src/core/lib/iomgr/executor.cc
- src/core/lib/iomgr/iomgr_internal.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/periodic_update.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- test/core/resource_quota/memory_quota_stress_test.cc - test/core/resource_quota/memory_quota_stress_test.cc
deps: deps:
- absl/functional:any_invocable - grpc_test_util_unsecure
- absl/functional:function_ref
- absl/meta:type_traits
- absl/status:statusor
- absl/utility:utility
- gpr
- upb
platforms: platforms:
- linux - linux
- posix - posix
@ -7810,75 +7687,11 @@ targets:
build: test build: test
language: c++ language: c++
headers: headers:
- src/core/ext/upb-generated/google/protobuf/any.upb.h
- src/core/ext/upb-generated/google/rpc/status.upb.h
- src/core/lib/debug/trace.h
- src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/debug_location.h
- src/core/lib/gprpp/no_destruct.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
- src/core/lib/gprpp/time.h
- src/core/lib/iomgr/closure.h
- src/core/lib/iomgr/combiner.h
- src/core/lib/iomgr/error.h
- src/core/lib/iomgr/exec_ctx.h
- src/core/lib/iomgr/executor.h
- src/core/lib/iomgr/iomgr_internal.h
- src/core/lib/promise/activity.h
- src/core/lib/promise/context.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/detail/status.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/periodic_update.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/slice/percent_encoding.h
- src/core/lib/slice/slice.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
- src/core/lib/slice/slice_string_helpers.h
- test/core/resource_quota/call_checker.h - test/core/resource_quota/call_checker.h
src: src:
- src/core/ext/upb-generated/google/protobuf/any.upb.c
- src/core/ext/upb-generated/google/rpc/status.upb.c
- src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/combiner.cc
- src/core/lib/iomgr/error.cc
- src/core/lib/iomgr/exec_ctx.cc
- src/core/lib/iomgr/executor.cc
- src/core/lib/iomgr/iomgr_internal.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/periodic_update.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- test/core/resource_quota/memory_quota_test.cc - test/core/resource_quota/memory_quota_test.cc
deps: deps:
- absl/functional:any_invocable - grpc_test_util_unsecure
- absl/functional:function_ref
- absl/meta:type_traits
- absl/status:statusor
- absl/utility:utility
- gpr
- upb
uses_polling: false uses_polling: false
- name: message_allocator_end2end_test - name: message_allocator_end2end_test
gtest: true gtest: true
@ -8332,6 +8145,8 @@ targets:
- src/core/ext/upb-generated/google/protobuf/any.upb.h - src/core/ext/upb-generated/google/protobuf/any.upb.h
- src/core/ext/upb-generated/google/rpc/status.upb.h - src/core/ext/upb-generated/google/rpc/status.upb.h
- src/core/lib/debug/trace.h - src/core/lib/debug/trace.h
- src/core/lib/experiments/config.h
- src/core/lib/experiments/experiments.h
- src/core/lib/gprpp/atomic_utils.h - src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h - src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/cpp_impl_of.h - src/core/lib/gprpp/cpp_impl_of.h
@ -8383,6 +8198,8 @@ targets:
- src/core/ext/upb-generated/google/rpc/status.upb.c - src/core/ext/upb-generated/google/rpc/status.upb.c
- src/core/lib/debug/trace.cc - src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc - src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/experiments/config.cc
- src/core/lib/experiments/experiments.cc
- src/core/lib/gprpp/status_helper.cc - src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc - src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/combiner.cc - src/core/lib/iomgr/combiner.cc
@ -8883,80 +8700,11 @@ targets:
gtest: true gtest: true
build: test build: test
language: c++ language: c++
headers: headers: []
- src/core/ext/upb-generated/google/protobuf/any.upb.h
- src/core/ext/upb-generated/google/rpc/status.upb.h
- src/core/lib/debug/trace.h
- src/core/lib/gprpp/atomic_utils.h
- src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/cpp_impl_of.h
- src/core/lib/gprpp/debug_location.h
- src/core/lib/gprpp/no_destruct.h
- src/core/lib/gprpp/orphanable.h
- src/core/lib/gprpp/ref_counted.h
- src/core/lib/gprpp/ref_counted_ptr.h
- src/core/lib/gprpp/status_helper.h
- src/core/lib/gprpp/time.h
- src/core/lib/iomgr/closure.h
- src/core/lib/iomgr/combiner.h
- src/core/lib/iomgr/error.h
- src/core/lib/iomgr/exec_ctx.h
- src/core/lib/iomgr/executor.h
- src/core/lib/iomgr/iomgr_internal.h
- src/core/lib/promise/activity.h
- src/core/lib/promise/context.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/detail/status.h
- src/core/lib/promise/exec_ctx_wakeup_scheduler.h
- src/core/lib/promise/loop.h
- src/core/lib/promise/map.h
- src/core/lib/promise/poll.h
- src/core/lib/promise/race.h
- src/core/lib/promise/seq.h
- src/core/lib/resource_quota/memory_quota.h
- src/core/lib/resource_quota/periodic_update.h
- src/core/lib/resource_quota/resource_quota.h
- src/core/lib/resource_quota/thread_quota.h
- src/core/lib/resource_quota/trace.h
- src/core/lib/slice/percent_encoding.h
- src/core/lib/slice/slice.h
- src/core/lib/slice/slice_internal.h
- src/core/lib/slice/slice_refcount.h
- src/core/lib/slice/slice_refcount_base.h
- src/core/lib/slice/slice_string_helpers.h
src: src:
- src/core/ext/upb-generated/google/protobuf/any.upb.c
- src/core/ext/upb-generated/google/rpc/status.upb.c
- src/core/lib/debug/trace.cc
- src/core/lib/event_engine/memory_allocator.cc
- src/core/lib/gprpp/status_helper.cc
- src/core/lib/gprpp/time.cc
- src/core/lib/iomgr/combiner.cc
- src/core/lib/iomgr/error.cc
- src/core/lib/iomgr/exec_ctx.cc
- src/core/lib/iomgr/executor.cc
- src/core/lib/iomgr/iomgr_internal.cc
- src/core/lib/promise/activity.cc
- src/core/lib/resource_quota/memory_quota.cc
- src/core/lib/resource_quota/periodic_update.cc
- src/core/lib/resource_quota/resource_quota.cc
- src/core/lib/resource_quota/thread_quota.cc
- src/core/lib/resource_quota/trace.cc
- src/core/lib/slice/percent_encoding.cc
- src/core/lib/slice/slice.cc
- src/core/lib/slice/slice_refcount.cc
- src/core/lib/slice/slice_string_helpers.cc
- test/core/resource_quota/resource_quota_test.cc - test/core/resource_quota/resource_quota_test.cc
deps: deps:
- absl/functional:any_invocable - grpc_test_util_unsecure
- absl/functional:function_ref
- absl/meta:type_traits
- absl/status:statusor
- absl/utility:utility
- gpr
- upb
uses_polling: false uses_polling: false
- name: retry_throttle_test - name: retry_throttle_test
gtest: true gtest: true

@ -35,6 +35,7 @@
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include "src/core/lib/experiments/experiments.h"
#include "src/core/lib/gpr/useful.h" #include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/global_config_env.h" #include "src/core/lib/gprpp/global_config_env.h"
#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/exec_ctx.h"
@ -288,15 +289,13 @@ void TransportFlowControl::UpdateSetting(
} }
FlowControlAction TransportFlowControl::PeriodicUpdate() { FlowControlAction TransportFlowControl::PeriodicUpdate() {
static const bool kSmoothMemoryPressure =
GPR_GLOBAL_CONFIG_GET(grpc_experimental_smooth_memory_presure);
FlowControlAction action; FlowControlAction action;
if (enable_bdp_probe_) { if (enable_bdp_probe_) {
// get bdp estimate and update initial_window accordingly. // get bdp estimate and update initial_window accordingly.
// target might change based on how much memory pressure we are under // target might change based on how much memory pressure we are under
// TODO(ncteisen): experiment with setting target to be huge under low // TODO(ncteisen): experiment with setting target to be huge under low
// memory pressure. // memory pressure.
double target = kSmoothMemoryPressure double target = IsMemoryPressureControllerEnabled()
? TargetInitialWindowSizeBasedOnMemoryPressureAndBdp() ? TargetInitialWindowSizeBasedOnMemoryPressureAndBdp()
: pow(2, SmoothLogBdp(TargetLogBdp())); : pow(2, SmoothLogBdp(TargetLogBdp()));
if (g_test_only_transport_target_window_estimates_mocker != nullptr) { if (g_test_only_transport_target_window_estimates_mocker != nullptr) {

@ -29,6 +29,12 @@ const char* const description_tcp_read_chunks =
"malloc to recycle arbitrary large blocks."; "malloc to recycle arbitrary large blocks.";
const char* const description_tcp_rcv_lowat = const char* const description_tcp_rcv_lowat =
"Use SO_RCVLOWAT to avoid wakeups on the read path."; "Use SO_RCVLOWAT to avoid wakeups on the read path.";
const char* const description_memory_pressure_controller =
"New memory pressure controller";
const char* const description_periodic_resource_quota_reclamation =
"Periodically return memory to the resource quota";
const char* const description_unconstrained_max_quota_buffer_size =
"Discard the cap on the max free pool size for one memory allocator";
} // namespace } // namespace
namespace grpc_core { namespace grpc_core {
@ -37,6 +43,12 @@ const ExperimentMetadata g_experiment_metadata[] = {
{"tcp_frame_size_tuning", description_tcp_frame_size_tuning, false}, {"tcp_frame_size_tuning", description_tcp_frame_size_tuning, false},
{"tcp_read_chunks", description_tcp_read_chunks, false}, {"tcp_read_chunks", description_tcp_read_chunks, false},
{"tcp_rcv_lowat", description_tcp_rcv_lowat, false}, {"tcp_rcv_lowat", description_tcp_rcv_lowat, false},
{"memory_pressure_controller", description_memory_pressure_controller,
false},
{"periodic_resource_quota_reclamation",
description_periodic_resource_quota_reclamation, false},
{"unconstrained_max_quota_buffer_size",
description_unconstrained_max_quota_buffer_size, false},
}; };
} // namespace grpc_core } // namespace grpc_core

@ -28,6 +28,15 @@ namespace grpc_core {
inline bool IsTcpFrameSizeTuningEnabled() { return IsExperimentEnabled(0); } inline bool IsTcpFrameSizeTuningEnabled() { return IsExperimentEnabled(0); }
inline bool IsTcpReadChunksEnabled() { return IsExperimentEnabled(1); } inline bool IsTcpReadChunksEnabled() { return IsExperimentEnabled(1); }
inline bool IsTcpRcvLowatEnabled() { return IsExperimentEnabled(2); } inline bool IsTcpRcvLowatEnabled() { return IsExperimentEnabled(2); }
inline bool IsMemoryPressureControllerEnabled() {
return IsExperimentEnabled(3);
}
inline bool IsPeriodicResourceQuotaReclamationEnabled() {
return IsExperimentEnabled(4);
}
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() {
return IsExperimentEnabled(5);
}
struct ExperimentMetadata { struct ExperimentMetadata {
const char* name; const char* name;
@ -35,7 +44,7 @@ struct ExperimentMetadata {
bool default_value; bool default_value;
}; };
constexpr const size_t kNumExperiments = 3; constexpr const size_t kNumExperiments = 6;
extern const ExperimentMetadata g_experiment_metadata[kNumExperiments]; extern const ExperimentMetadata g_experiment_metadata[kNumExperiments];
} // namespace grpc_core } // namespace grpc_core

@ -50,3 +50,24 @@
expiry: 2022/10/01 expiry: 2022/10/01
owner: ctiller@google.com owner: ctiller@google.com
test_tags: ["endpoint_test", "core_end2end_test"] test_tags: ["endpoint_test", "core_end2end_test"]
- name: memory_pressure_controller
description:
New memory pressure controller
default: false
expiry: 2022/10/01
owner: ctiller@google.com
test_tags: [resource_quota_test]
- name: periodic_resource_quota_reclamation
description:
Periodically return memory to the resource quota
default: false
expiry: 2022/10/01
owner: ctiller@google.com
test_tags: [resource_quota_test]
- name: unconstrained_max_quota_buffer_size
description:
Discard the cap on the max free pool size for one memory allocator
default: false
expiry: 2022/10/01
owner: ctiller@google.com
test_tags: [resource_quota_test]

@ -27,7 +27,6 @@
#include "src/core/lib/debug/trace.h" #include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/useful.h" #include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/global_config_env.h"
#include "src/core/lib/gprpp/mpscq.h" #include "src/core/lib/gprpp/mpscq.h"
#include "src/core/lib/promise/exec_ctx_wakeup_scheduler.h" #include "src/core/lib/promise/exec_ctx_wakeup_scheduler.h"
#include "src/core/lib/promise/loop.h" #include "src/core/lib/promise/loop.h"
@ -36,18 +35,6 @@
#include "src/core/lib/promise/seq.h" #include "src/core/lib/promise/seq.h"
#include "src/core/lib/resource_quota/trace.h" #include "src/core/lib/resource_quota/trace.h"
GPR_GLOBAL_CONFIG_DEFINE_BOOL(grpc_experimental_smooth_memory_presure, false,
"smooth the value of memory pressure over time");
GPR_GLOBAL_CONFIG_DEFINE_BOOL(
grpc_experimental_enable_periodic_resource_quota_reclamation, false,
"Enable experimental feature to reclaim resource quota periodically");
GPR_GLOBAL_CONFIG_DEFINE_INT32(
grpc_experimental_max_quota_buffer_size, 1024 * 1024,
"Maximum size for one memory allocators buffer size against a quota");
GPR_GLOBAL_CONFIG_DEFINE_INT32(
grpc_experimental_resource_quota_set_point, 95,
"Ask the resource quota to target this percentage of total quota usage.");
namespace grpc_core { namespace grpc_core {
// Maximum number of bytes an allocator will request from a quota in one step. // Maximum number of bytes an allocator will request from a quota in one step.
@ -261,10 +248,11 @@ void GrpcMemoryAllocatorImpl::MaybeDonateBack() {
size_t free = free_bytes_.load(std::memory_order_relaxed); size_t free = free_bytes_.load(std::memory_order_relaxed);
while (free > 0) { while (free > 0) {
size_t ret = 0; size_t ret = 0;
if (max_quota_buffer_size() > 0 && free > max_quota_buffer_size() / 2) { if (!IsUnconstrainedMaxQuotaBufferSizeEnabled() &&
ret = std::max(ret, free - max_quota_buffer_size() / 2); free > kMaxQuotaBufferSize / 2) {
ret = std::max(ret, free - kMaxQuotaBufferSize / 2);
} }
if (periodic_donate_back()) { if (IsPeriodicResourceQuotaReclamationEnabled()) {
ret = std::max(ret, free > 8192 ? free / 2 : free); ret = std::max(ret, free > 8192 ? free / 2 : free);
} }
const size_t new_free = free - ret; const size_t new_free = free - ret;
@ -462,8 +450,6 @@ void BasicMemoryQuota::Return(size_t amount) {
} }
BasicMemoryQuota::PressureInfo BasicMemoryQuota::GetPressureInfo() { BasicMemoryQuota::PressureInfo BasicMemoryQuota::GetPressureInfo() {
static const bool kSmoothMemoryPressure =
GPR_GLOBAL_CONFIG_GET(grpc_experimental_smooth_memory_presure);
double free = free_bytes_.load(); double free = free_bytes_.load();
if (free < 0) free = 0; if (free < 0) free = 0;
size_t quota_size = quota_size_.load(); size_t quota_size = quota_size_.load();
@ -471,7 +457,7 @@ BasicMemoryQuota::PressureInfo BasicMemoryQuota::GetPressureInfo() {
if (size < 1) return PressureInfo{1, 1, 1}; if (size < 1) return PressureInfo{1, 1, 1};
PressureInfo pressure_info; PressureInfo pressure_info;
pressure_info.instantaneous_pressure = std::max(0.0, (size - free) / size); pressure_info.instantaneous_pressure = std::max(0.0, (size - free) / size);
if (kSmoothMemoryPressure) { if (IsMemoryPressureControllerEnabled()) {
pressure_info.pressure_control_value = pressure_info.pressure_control_value =
pressure_tracker_.AddSampleAndGetControlValue( pressure_tracker_.AddSampleAndGetControlValue(
pressure_info.instantaneous_pressure); pressure_info.instantaneous_pressure);
@ -562,8 +548,7 @@ std::string PressureController::DebugString() const {
} }
double PressureTracker::AddSampleAndGetControlValue(double sample) { double PressureTracker::AddSampleAndGetControlValue(double sample) {
static const double kSetPoint = static const double kSetPoint = 95.0;
GPR_GLOBAL_CONFIG_GET(grpc_experimental_resource_quota_set_point) / 100.0;
double max_so_far = max_this_round_.load(std::memory_order_relaxed); double max_so_far = max_this_round_.load(std::memory_order_relaxed);
if (sample > max_so_far) { if (sample > max_so_far) {

@ -34,7 +34,7 @@
#include <grpc/event_engine/memory_request.h> #include <grpc/event_engine/memory_request.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include "src/core/lib/gprpp/global_config_generic.h" #include "src/core/lib/experiments/experiments.h"
#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/sync.h"
@ -43,11 +43,6 @@
#include "src/core/lib/promise/poll.h" #include "src/core/lib/promise/poll.h"
#include "src/core/lib/resource_quota/periodic_update.h" #include "src/core/lib/resource_quota/periodic_update.h"
GPR_GLOBAL_CONFIG_DECLARE_BOOL(grpc_experimental_smooth_memory_presure);
GPR_GLOBAL_CONFIG_DECLARE_BOOL(
grpc_experimental_enable_periodic_resource_quota_reclamation);
GPR_GLOBAL_CONFIG_DECLARE_INT32(grpc_experimental_max_quota_buffer_size);
namespace grpc_core { namespace grpc_core {
class BasicMemoryQuota; class BasicMemoryQuota;
@ -370,9 +365,10 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl {
// from 0 to non-zero, then we have more to do, otherwise, we're actually // from 0 to non-zero, then we have more to do, otherwise, we're actually
// done. // done.
size_t prev_free = free_bytes_.fetch_add(n, std::memory_order_release); size_t prev_free = free_bytes_.fetch_add(n, std::memory_order_release);
if ((max_quota_buffer_size() > 0 && if ((!IsUnconstrainedMaxQuotaBufferSizeEnabled() &&
prev_free + n > max_quota_buffer_size()) || prev_free + n > kMaxQuotaBufferSize) ||
(periodic_donate_back() && donate_back_.Tick([](Duration) {}))) { (IsPeriodicResourceQuotaReclamationEnabled() &&
donate_back_.Tick([](Duration) {}))) {
// Try to immediately return some free'ed memory back to the total quota. // Try to immediately return some free'ed memory back to the total quota.
MaybeDonateBack(); MaybeDonateBack();
} }
@ -400,16 +396,7 @@ class GrpcMemoryAllocatorImpl final : public EventEngineMemoryAllocatorImpl {
absl::string_view name() const { return name_; } absl::string_view name() const { return name_; }
private: private:
static bool periodic_donate_back() { static constexpr size_t kMaxQuotaBufferSize = 1024 * 1024;
static const bool value = GPR_GLOBAL_CONFIG_GET(
grpc_experimental_enable_periodic_resource_quota_reclamation);
return value;
}
static size_t max_quota_buffer_size() {
static const size_t value =
GPR_GLOBAL_CONFIG_GET(grpc_experimental_max_quota_buffer_size);
return value;
}
// Primitive reservation function. // Primitive reservation function.
absl::optional<size_t> TryReserve(MemoryRequest request) GRPC_MUST_USE_RESULT; absl::optional<size_t> TryReserve(MemoryRequest request) GRPC_MUST_USE_RESULT;
// This function may be invoked during a memory release operation. // This function may be invoked during a memory release operation.

@ -82,12 +82,16 @@ grpc_cc_test(
srcs = ["arena_promise_test.cc"], srcs = ["arena_promise_test.cc"],
external_deps = ["gtest"], external_deps = ["gtest"],
language = "c++", language = "c++",
tags = [
"resource_quota_test",
],
uses_event_engine = False, uses_event_engine = False,
uses_polling = False, uses_polling = False,
deps = [ deps = [
":test_context", ":test_context",
"//:arena_promise", "//:arena_promise",
"//:resource_quota", "//:resource_quota",
"//test/core/util:grpc_test_util_unsecure",
], ],
) )

@ -22,9 +22,11 @@
#include <grpc/event_engine/memory_allocator.h> #include <grpc/event_engine/memory_allocator.h>
#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/resource_quota/resource_quota.h"
#include "test/core/promise/test_context.h" #include "test/core/promise/test_context.h"
#include "test/core/util/test_config.h"
namespace grpc_core { namespace grpc_core {
@ -32,6 +34,7 @@ static auto* g_memory_allocator = new MemoryAllocator(
ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator("test")); ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator("test"));
TEST(ArenaPromiseTest, AllocatedWorks) { TEST(ArenaPromiseTest, AllocatedWorks) {
ExecCtx exec_ctx;
auto arena = MakeScopedArena(1024, g_memory_allocator); auto arena = MakeScopedArena(1024, g_memory_allocator);
TestContext<Arena> context(arena.get()); TestContext<Arena> context(arena.get());
int x = 42; int x = 42;
@ -42,6 +45,7 @@ TEST(ArenaPromiseTest, AllocatedWorks) {
} }
TEST(ArenaPromiseTest, DestructionWorks) { TEST(ArenaPromiseTest, DestructionWorks) {
ExecCtx exec_ctx;
auto arena = MakeScopedArena(1024, g_memory_allocator); auto arena = MakeScopedArena(1024, g_memory_allocator);
TestContext<Arena> context(arena.get()); TestContext<Arena> context(arena.get());
auto x = std::make_shared<int>(42); auto x = std::make_shared<int>(42);
@ -51,6 +55,7 @@ TEST(ArenaPromiseTest, DestructionWorks) {
} }
TEST(ArenaPromiseTest, MoveAssignmentWorks) { TEST(ArenaPromiseTest, MoveAssignmentWorks) {
ExecCtx exec_ctx;
auto arena = MakeScopedArena(1024, g_memory_allocator); auto arena = MakeScopedArena(1024, g_memory_allocator);
TestContext<Arena> context(arena.get()); TestContext<Arena> context(arena.get());
auto x = std::make_shared<int>(42); auto x = std::make_shared<int>(42);
@ -61,6 +66,7 @@ TEST(ArenaPromiseTest, MoveAssignmentWorks) {
} // namespace grpc_core } // namespace grpc_core
int main(int argc, char** argv) { int main(int argc, char** argv) {
grpc::testing::TestEnvironment give_me_a_name(&argc, argv);
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

@ -28,6 +28,9 @@ grpc_cc_test(
"gtest", "gtest",
], ],
language = "C++", language = "C++",
tags = [
"resource_quota_test",
],
uses_event_engine = False, uses_event_engine = False,
uses_polling = False, uses_polling = False,
deps = [ deps = [
@ -36,6 +39,7 @@ grpc_cc_test(
"//:grpc", "//:grpc",
"//:ref_counted_ptr", "//:ref_counted_ptr",
"//:resource_quota", "//:resource_quota",
"//test/core/util:grpc_test_util_unsecure",
], ],
) )
@ -54,6 +58,7 @@ grpc_cc_test(
language = "c++", language = "c++",
tags = [ tags = [
"cpu:10", "cpu:10",
"resource_quota_test",
], ],
uses_event_engine = False, uses_event_engine = False,
uses_polling = False, uses_polling = False,
@ -62,6 +67,7 @@ grpc_cc_test(
"//:exec_ctx", "//:exec_ctx",
"//:memory_quota", "//:memory_quota",
"//:slice_refcount", "//:slice_refcount",
"//test/core/util:grpc_test_util_unsecure",
], ],
) )
@ -98,9 +104,15 @@ grpc_cc_test(
srcs = ["resource_quota_test.cc"], srcs = ["resource_quota_test.cc"],
external_deps = ["gtest"], external_deps = ["gtest"],
language = "c++", language = "c++",
tags = [
"resource_quota_test",
],
uses_event_engine = False, uses_event_engine = False,
uses_polling = False, uses_polling = False,
deps = ["//:resource_quota"], deps = [
"//:resource_quota",
"//test/core/util:grpc_test_util_unsecure",
],
) )
grpc_cc_test( grpc_cc_test(
@ -118,6 +130,7 @@ grpc_cc_test(
tags = [ tags = [
"no_mac", "no_mac",
"no_windows", "no_windows",
"resource_quota_test",
], ],
uses_event_engine = False, uses_event_engine = False,
uses_polling = False, uses_polling = False,
@ -126,6 +139,7 @@ grpc_cc_test(
"//:exec_ctx", "//:exec_ctx",
"//:gpr", "//:gpr",
"//:memory_quota", "//:memory_quota",
"//test/core/util:grpc_test_util_unsecure",
], ],
) )

@ -36,17 +36,24 @@
#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/thd.h" #include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/resource_quota/resource_quota.h"
#include "test/core/util/test_config.h"
using grpc_core::Arena; using grpc_core::Arena;
using grpc_core::ExecCtx;
static auto* g_memory_allocator = new grpc_core::MemoryAllocator( static auto* g_memory_allocator = new grpc_core::MemoryAllocator(
grpc_core::ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator( grpc_core::ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator(
"test")); "test"));
TEST(ArenaTest, NoOp) { Arena::Create(1, g_memory_allocator)->Destroy(); } TEST(ArenaTest, NoOp) {
ExecCtx exec_ctx;
Arena::Create(1, g_memory_allocator)->Destroy();
}
TEST(ArenaTest, ManagedNew) { TEST(ArenaTest, ManagedNew) {
ExecCtx exec_ctx;
Arena* arena = Arena::Create(1, g_memory_allocator); Arena* arena = Arena::Create(1, g_memory_allocator);
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
arena->ManagedNew<std::unique_ptr<int>>(absl::make_unique<int>(i)); arena->ManagedNew<std::unique_ptr<int>>(absl::make_unique<int>(i));
@ -68,6 +75,7 @@ std::ostream& operator<<(std::ostream& out, const AllocShape& shape) {
class AllocTest : public ::testing::TestWithParam<AllocShape> {}; class AllocTest : public ::testing::TestWithParam<AllocShape> {};
TEST_P(AllocTest, Works) { TEST_P(AllocTest, Works) {
ExecCtx exec_ctx;
Arena* a = Arena::Create(GetParam().initial_size, g_memory_allocator); Arena* a = Arena::Create(GetParam().initial_size, g_memory_allocator);
std::vector<void*> allocated; std::vector<void*> allocated;
for (auto alloc : GetParam().allocs) { for (auto alloc : GetParam().allocs) {
@ -166,6 +174,7 @@ TEST(ArenaTest, ConcurrentManagedNew) {
} }
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
grpc::testing::TestEnvironment give_me_a_name(&argc, argv);
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

@ -36,6 +36,7 @@
#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/resource_quota/memory_quota.h" #include "src/core/lib/resource_quota/memory_quota.h"
#include "test/core/util/test_config.h"
namespace grpc_core { namespace grpc_core {
@ -55,6 +56,12 @@ class StressTest {
} }
} }
~StressTest() {
ExecCtx exec_ctx;
allocators_.clear();
quotas_.clear();
}
// Run the thread for some period of time. // Run the thread for some period of time.
void Run(int seconds) { void Run(int seconds) {
std::vector<std::thread> threads; std::vector<std::thread> threads;
@ -234,6 +241,7 @@ TEST(MemoryQuotaStressTest, MainTest) {
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
grpc::testing::TestEnvironment give_me_a_name(&argc, argv);
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

@ -28,6 +28,7 @@
#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/slice/slice_refcount.h" #include "src/core/lib/slice/slice_refcount.h"
#include "test/core/resource_quota/call_checker.h" #include "test/core/resource_quota/call_checker.h"
#include "test/core/util/test_config.h"
namespace grpc_core { namespace grpc_core {
namespace testing { namespace testing {
@ -70,6 +71,7 @@ TEST(MemoryQuotaTest, CreateAllocatorNoOp) {
} }
TEST(MemoryQuotaTest, CreateObjectFromAllocator) { TEST(MemoryQuotaTest, CreateObjectFromAllocator) {
ExecCtx exec_ctx;
MemoryQuota memory_quota("foo"); MemoryQuota memory_quota("foo");
auto memory_allocator = memory_quota.CreateMemoryAllocator("bar"); auto memory_allocator = memory_quota.CreateMemoryAllocator("bar");
auto object = memory_allocator.MakeUnique<Sized<4096>>(); auto object = memory_allocator.MakeUnique<Sized<4096>>();
@ -113,6 +115,7 @@ TEST(MemoryQuotaTest, ReserveRangeNoPressure) {
auto memory_allocator = memory_quota.CreateMemoryAllocator("bar"); auto memory_allocator = memory_quota.CreateMemoryAllocator("bar");
size_t total = 0; size_t total = 0;
for (int i = 0; i < 10000; i++) { for (int i = 0; i < 10000; i++) {
ExecCtx exec_ctx;
auto n = memory_allocator.Reserve(MemoryRequest(100, 40000)); auto n = memory_allocator.Reserve(MemoryRequest(100, 40000));
EXPECT_EQ(n, 40000); EXPECT_EQ(n, 40000);
total += n; total += n;
@ -125,16 +128,19 @@ TEST(MemoryQuotaTest, MakeSlice) {
auto memory_allocator = memory_quota.CreateMemoryAllocator("bar"); auto memory_allocator = memory_quota.CreateMemoryAllocator("bar");
std::vector<grpc_slice> slices; std::vector<grpc_slice> slices;
for (int i = 1; i < 1000; i++) { for (int i = 1; i < 1000; i++) {
ExecCtx exec_ctx;
int min = i; int min = i;
int max = 10 * i - 9; int max = 10 * i - 9;
slices.push_back(memory_allocator.MakeSlice(MemoryRequest(min, max))); slices.push_back(memory_allocator.MakeSlice(MemoryRequest(min, max)));
} }
ExecCtx exec_ctx;
for (grpc_slice slice : slices) { for (grpc_slice slice : slices) {
grpc_slice_unref_internal(slice); grpc_slice_unref_internal(slice);
} }
} }
TEST(MemoryQuotaTest, ContainerAllocator) { TEST(MemoryQuotaTest, ContainerAllocator) {
ExecCtx exec_ctx;
MemoryQuota memory_quota("foo"); MemoryQuota memory_quota("foo");
auto memory_allocator = memory_quota.CreateMemoryAllocator("bar"); auto memory_allocator = memory_quota.CreateMemoryAllocator("bar");
Vector<int> vec(&memory_allocator); Vector<int> vec(&memory_allocator);
@ -260,10 +266,8 @@ TEST(PressureTrackerTest, ManyThreads) {
} // namespace grpc_core } // namespace grpc_core
// Hook needed to run ExecCtx outside of iomgr.
void grpc_set_default_iomgr_platform() {}
int main(int argc, char** argv) { int main(int argc, char** argv) {
grpc::testing::TestEnvironment give_me_a_name(&argc, argv);
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
gpr_log_verbosity_init(); gpr_log_verbosity_init();
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();

@ -16,6 +16,8 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "test/core/util/test_config.h"
namespace grpc_core { namespace grpc_core {
namespace testing { namespace testing {
@ -28,10 +30,8 @@ TEST(ResourceQuotaTest, Works) {
} // namespace testing } // namespace testing
} // namespace grpc_core } // namespace grpc_core
// Hook needed to run ExecCtx outside of iomgr.
void grpc_set_default_iomgr_platform() {}
int main(int argc, char** argv) { int main(int argc, char** argv) {
grpc::testing::TestEnvironment give_me_a_name(&argc, argv);
::testing::InitGoogleTest(&argc, argv); ::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS(); return RUN_ALL_TESTS();
} }

Loading…
Cancel
Save