[COMMIT seastar master] Merge 'scheduling groups: Add compile parameter for setting max scheduling groups count at compile time' from Eliran Sinvani

14 views
Skip to first unread message

Commit Bot

<bot@cloudius-systems.com>
unread,
Oct 13, 2021, 9:42:35 AM10/13/21
to seastar-dev@googlegroups.com, Nadav Har'El
From: Nadav Har'El <n...@scylladb.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

Merge 'scheduling groups: Add compile parameter for setting max scheduling groups count at compile time' from Eliran Sinvani

This patchset contains one significant change: adding the support for scheduling group count configuration at compile time.
It also contains a fix for existing unit test and additional unit test for validating the count.

Closes #953

* github.com:scylladb/seastar:
Scheduler: Add support for scheduling group count configuration
Scheduling groups: add a sg_count test
Scheduling group test: Add cleanup to sg_scheduling_group_inheritance_in_seastar_async_test

---
diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -73,6 +73,16 @@ set_property (CACHE Seastar_API_LEVEL
PROPERTY
STRINGS 2 3 4 5 6)

+set (Seastar_SCHEDULING_GROUPS_COUNT
+ "16"
+ CACHE
+ STRING
+ "A positive number to set Seastar's reactor number of allowed different scheduling groups.")
+
+if (NOT Seastar_SCHEDULING_GROUPS_COUNT MATCHES "^[1-9][0-9]*")
+ message(FATAL_ERROR "Seastar_SCHEDULING_GROUPS_COUNT must be a positive number (${Seastar_SCHEDULING_GROUPS_COUNT})")
+endif()
+
#
# Add a dev build type.
#
@@ -826,6 +836,9 @@ if (Seastar_ALLOC_PAGE_SIZE)
PUBLIC SEASTAR_OVERRIDE_ALLOCATOR_PAGE_SIZE=${Seastar_ALLOC_PAGE_SIZE})
endif ()

+target_compile_definitions (seastar
+ PUBLIC SEASTAR_SCHEDULING_GROUPS_COUNT=${Seastar_SCHEDULING_GROUPS_COUNT})
+
if (Seastar_CXX_FLAGS)
list (APPEND Seastar_PRIVATE_CXX_FLAGS ${Seastar_CXX_FLAGS})
endif ()
diff --git a/configure.py b/configure.py
--- a/configure.py
+++ b/configure.py
@@ -75,6 +75,9 @@ def dialect_supported(dialect, compiler='g++'):
arg_parser.add_argument('--cook', action='append', dest='cook', default=[],
help='Supply this dependency locally for development via `cmake-cooking` (can be repeated)')
arg_parser.add_argument('--verbose', dest='verbose', action='store_true', help='Make configure output more verbose.')
+arg_parser.add_argument('--scheduling-groups-count', action='store', dest='scheduling_groups_count', default='16',
+ help='Number of available scheduling groups in the reactor')
+
add_tristate(
arg_parser,
name = 'dpdk',
@@ -181,6 +184,7 @@ def configure_mode(mode):
'-DCMAKE_CXX_COMPILER={}'.format(args.cxx),
'-DCMAKE_INSTALL_PREFIX={}'.format(args.install_prefix),
'-DSeastar_API_LEVEL={}'.format(args.api_level),
+ '-DSeastar_SCHEDULING_GROUPS_COUNT={}'.format(args.scheduling_groups_count),
tr(args.exclude_tests, 'EXCLUDE_TESTS_FROM_ALL'),
tr(args.exclude_apps, 'EXCLUDE_APPS_FROM_ALL'),
tr(args.exclude_demos, 'EXCLUDE_DEMOS_FROM_ALL'),
diff --git a/include/seastar/core/reactor.hh b/include/seastar/core/reactor.hh
--- a/include/seastar/core/reactor.hh
+++ b/include/seastar/core/reactor.hh
@@ -172,6 +172,8 @@ public:
friend class reactor;
};

+size_t scheduling_group_count();
+
}

class kernel_completion;
@@ -190,7 +192,7 @@ public:
class reactor {
private:
struct task_queue;
- using task_queue_list = circular_buffer_fixed_capacity<task_queue*, max_scheduling_groups()>;
+ using task_queue_list = circular_buffer_fixed_capacity<task_queue*, 1 << log2ceil(max_scheduling_groups())>;
using pollfn = seastar::pollfn;

class signal_pollfn;
@@ -215,6 +217,7 @@ private:
friend class reactor_backend_aio;
friend class reactor_backend_selector;
friend class aio_storage_context;
+ friend size_t scheduling_group_count();
public:
using poller = internal::poller;
using idle_cpu_handler_result = seastar::idle_cpu_handler_result;
diff --git a/include/seastar/core/scheduling.hh b/include/seastar/core/scheduling.hh
--- a/include/seastar/core/scheduling.hh
+++ b/include/seastar/core/scheduling.hh
@@ -31,7 +31,7 @@

namespace seastar {

-constexpr unsigned max_scheduling_groups() { return 16; }
+constexpr unsigned max_scheduling_groups() { return SEASTAR_SCHEDULING_GROUPS_COUNT; }

#if SEASTAR_API_LEVEL < 6
#define SEASTAR_ELLIPSIS ...
diff --git a/src/core/reactor.cc b/src/core/reactor.cc
--- a/src/core/reactor.cc
+++ b/src/core/reactor.cc
@@ -4640,6 +4640,11 @@ std::ostream& operator<<(std::ostream& os, const stall_report& sr) {
return os << format("{} stalls, {} ms stall time, {} ms run time", sr.kernel_stalls, to_ms(sr.stall_time), to_ms(sr.run_wall_time));
}

+size_t scheduling_group_count() {
+ auto b = s_used_scheduling_group_ids_bitmap.load(std::memory_order_relaxed);
+ return __builtin_popcountl(b);
+}
+
}

#ifdef SEASTAR_TASK_BACKTRACE
diff --git a/tests/unit/scheduling_group_test.cc b/tests/unit/scheduling_group_test.cc
--- a/tests/unit/scheduling_group_test.cc
+++ b/tests/unit/scheduling_group_test.cc
@@ -33,6 +33,7 @@
#include <seastar/core/scheduling_specific.hh>
#include <seastar/core/smp.hh>
#include <seastar/core/with_scheduling_group.hh>
+#include <seastar/core/reactor.hh>
#include <seastar/util/later.hh>
#include <seastar/util/defer.hh>

@@ -221,6 +222,7 @@ SEASTAR_THREAD_TEST_CASE(sg_specific_values_define_before_and_after_sg_create) {
*/
SEASTAR_THREAD_TEST_CASE(sg_scheduling_group_inheritance_in_seastar_async_test) {
scheduling_group sg = create_scheduling_group("sg0", 100).get0();
+ auto cleanup = defer([&] () noexcept { destroy_scheduling_group(sg).get(); });
thread_attributes attr = {};
attr.sched_group = sg;
seastar::async(attr, [attr] {
@@ -250,3 +252,33 @@ SEASTAR_THREAD_TEST_CASE(later_preserves_sg) {
});
}).get();
}
+
+SEASTAR_THREAD_TEST_CASE(sg_count) {
+ class scheduling_group_destroyer {
+ scheduling_group _sg;
+ public:
+ scheduling_group_destroyer(scheduling_group sg) : _sg(sg) {}
+ ~scheduling_group_destroyer() {
+ destroy_scheduling_group(_sg).get();
+ }
+ };
+
+ std::vector<scheduling_group_destroyer> scheduling_groups_deferred_cleanup;
+ // The line below is necessary in order to skip support of copy and move construction of scheduling_group_destroyer.
+ scheduling_groups_deferred_cleanup.reserve(max_scheduling_groups());
+ // try to create 3 groups too many.
+ for (auto i = internal::scheduling_group_count(); i < max_scheduling_groups() + 3; i++) {
+ try {
+ BOOST_REQUIRE_LE(internal::scheduling_group_count(), max_scheduling_groups());
+ scheduling_groups_deferred_cleanup.emplace_back(create_scheduling_group(format("sg_{}", i), 10).get());
+ } catch (std::runtime_error& e) {
+ // make sure it is the right exception.
+ BOOST_REQUIRE_EQUAL(e.what(), "Scheduling group limit exceeded");
+ // make sure that the scheduling group count makes sense
+ BOOST_REQUIRE_EQUAL(internal::scheduling_group_count(), max_scheduling_groups());
+ // make sure that we expect this exception at this point
+ BOOST_REQUIRE_GE(i, max_scheduling_groups());
+ }
+ }
+ BOOST_REQUIRE_EQUAL(internal::scheduling_group_count(), max_scheduling_groups());
+}
Reply all
Reply to author
Forward
0 new messages