Skip to content

Commit d2988f5

Browse files
committed
Add "reactor" / "io_uring_ring_size" (unsigned int) config parameter.
This parameter specifies the number of entries used to size each io_uring instance (passed to io_uring_queue_init). Defaults to 16384. Specifying smaller values reduces the locked-memory footprint of each ring.
1 parent 1e9dd98 commit d2988f5

4 files changed

Lines changed: 49 additions & 16 deletions

File tree

include/asio/detail/impl/io_uring_service.ipp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ io_uring_service::io_uring_service(asio::execution_context& ctx)
8383
iowait_(config(ctx).get("reactor", "io_uring_iowait", true)),
8484
submit_batch_size_(
8585
config(ctx).get("reactor", "io_uring_submit_batch_size", 128)),
86+
ring_size_(config(ctx).get("reactor",
87+
"io_uring_ring_size", static_cast<unsigned int>(default_ring_size))),
8688
unflushed_submits_(0),
8789
timeout_(),
8890
registration_mutex_(
@@ -797,6 +799,8 @@ void io_uring_service::interrupt()
797799

798800
void io_uring_service::init_ring()
799801
{
802+
const unsigned int entries = ring_size_ != 0
803+
? ring_size_ : static_cast<unsigned int>(default_ring_size);
800804
for (std::size_t i = 0; i < rings_.size(); ++i)
801805
{
802806
// All rings share the same kernel worker pool.
@@ -808,7 +812,7 @@ void io_uring_service::init_ring()
808812
}
809813

810814
int result =
811-
::io_uring_queue_init_params(ring_size, &rings_[i].ring_, &params);
815+
::io_uring_queue_init_params(entries, &rings_[i].ring_, &params);
812816
if (result < 0)
813817
{
814818
rings_[i].ring_.ring_fd = -1;

include/asio/detail/io_uring_service.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,10 @@ class io_uring_service
206206
ASIO_DECL void interrupt();
207207

208208
private:
209-
// The hint to pass to io_uring_queue_init to size its data structures.
210-
enum { ring_size = 16384 };
209+
// The default hint to pass to io_uring_queue_init to size its data
210+
// structures, used when the "reactor" / "io_uring_ring_size" configuration
211+
// value is not set.
212+
enum { default_ring_size = 16384 };
211213

212214
// The number of operations to complete in a batch.
213215
enum { complete_batch_size = 128 };
@@ -316,6 +318,9 @@ class io_uring_service
316318
// The number of operations to submit in a batch.
317319
const int submit_batch_size_;
318320

321+
// The number of entries used to size each io_uring.
322+
const unsigned int ring_size_;
323+
319324
// A count of SQE submissions that are yet to be flushed.
320325
atomic_count unflushed_submits_;
321326

src/doc/overview/configuration.qbk

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,24 @@ below.
232232
Values that are less than one `1` are treated as `1`.
233233
]
234234
]
235+
[
236+
[`reactor`]
237+
[`io_uring_ring_size`]
238+
[`unsigned int`]
239+
[`16384`]
240+
[
241+
Linux [^io_uring] backend only.
242+
243+
The number of entries used to size each [^io_uring] instance, passed to
244+
[^io_uring_queue_init]. Larger values allow more operations to be in
245+
flight before submission queue entries must be flushed, at the cost of
246+
more locked memory per ring. Reducing this value lowers the per-ring
247+
memory footprint, which can matter in environments with a low
248+
`RLIMIT_MEMLOCK` limit.
249+
250+
A value of `0` selects the default.
251+
]
252+
]
235253
[
236254
[`reactor`]
237255
[`reset_edge_on_partial_read`]

src/tests/unit/connect.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
#include "asio/connect.hpp"
1818

1919
#include <functional>
20+
#include <string>
2021
#include <vector>
22+
#include "asio/config.hpp"
2123
#include "asio/detail/thread.hpp"
2224
#include "asio/ip/tcp.hpp"
2325
#include "unit_test.hpp"
@@ -26,11 +28,15 @@ namespace bindns = std;
2628
using bindns::placeholders::_1;
2729
using bindns::placeholders::_2;
2830

31+
asio::config_from_string io_context_config(
32+
"reactor.io_uring_ring_size=64\n");
33+
2934
class connection_sink
3035
{
3136
public:
3237
connection_sink()
33-
: acceptor_(io_context_,
38+
: io_context_(io_context_config),
39+
acceptor_(io_context_,
3440
asio::ip::tcp::endpoint(
3541
asio::ip::address_v4::loopback(), 0)),
3642
target_endpoint_(acceptor_.local_endpoint()),
@@ -129,7 +135,7 @@ void iter_handler(const asio::error_code& ec,
129135
void test_connect_range()
130136
{
131137
connection_sink sink;
132-
asio::io_context io_context;
138+
asio::io_context io_context(io_context_config);
133139
asio::ip::tcp::socket socket(io_context);
134140
std::vector<asio::ip::tcp::endpoint> endpoints;
135141
asio::ip::tcp::endpoint result;
@@ -163,7 +169,7 @@ void test_connect_range()
163169
void test_connect_range_ec()
164170
{
165171
connection_sink sink;
166-
asio::io_context io_context;
172+
asio::io_context io_context(io_context_config);
167173
asio::ip::tcp::socket socket(io_context);
168174
std::vector<asio::ip::tcp::endpoint> endpoints;
169175
asio::ip::tcp::endpoint result;
@@ -195,7 +201,7 @@ void test_connect_range_ec()
195201
void test_connect_range_cond()
196202
{
197203
connection_sink sink;
198-
asio::io_context io_context;
204+
asio::io_context io_context(io_context_config);
199205
asio::ip::tcp::socket socket(io_context);
200206
std::vector<asio::ip::tcp::endpoint> endpoints;
201207
asio::ip::tcp::endpoint result;
@@ -326,7 +332,7 @@ void test_connect_range_cond()
326332
void test_connect_range_cond_ec()
327333
{
328334
connection_sink sink;
329-
asio::io_context io_context;
335+
asio::io_context io_context(io_context_config);
330336
asio::ip::tcp::socket socket(io_context);
331337
std::vector<asio::ip::tcp::endpoint> endpoints;
332338
asio::ip::tcp::endpoint result;
@@ -422,7 +428,7 @@ void test_connect_range_cond_ec()
422428
void test_connect_iter()
423429
{
424430
connection_sink sink;
425-
asio::io_context io_context;
431+
asio::io_context io_context(io_context_config);
426432
asio::ip::tcp::socket socket(io_context);
427433
std::vector<asio::ip::tcp::endpoint> endpoints;
428434
const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
@@ -457,7 +463,7 @@ void test_connect_iter()
457463
void test_connect_iter_ec()
458464
{
459465
connection_sink sink;
460-
asio::io_context io_context;
466+
asio::io_context io_context(io_context_config);
461467
asio::ip::tcp::socket socket(io_context);
462468
std::vector<asio::ip::tcp::endpoint> endpoints;
463469
const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
@@ -494,7 +500,7 @@ void test_connect_iter_ec()
494500
void test_connect_iter_cond()
495501
{
496502
connection_sink sink;
497-
asio::io_context io_context;
503+
asio::io_context io_context(io_context_config);
498504
asio::ip::tcp::socket socket(io_context);
499505
std::vector<asio::ip::tcp::endpoint> endpoints;
500506
const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
@@ -646,7 +652,7 @@ void test_connect_iter_cond()
646652
void test_connect_iter_cond_ec()
647653
{
648654
connection_sink sink;
649-
asio::io_context io_context;
655+
asio::io_context io_context(io_context_config);
650656
asio::ip::tcp::socket socket(io_context);
651657
std::vector<asio::ip::tcp::endpoint> endpoints;
652658
const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
@@ -763,7 +769,7 @@ void test_connect_iter_cond_ec()
763769
void test_async_connect_range()
764770
{
765771
connection_sink sink;
766-
asio::io_context io_context;
772+
asio::io_context io_context(io_context_config);
767773
asio::ip::tcp::socket socket(io_context);
768774
std::vector<asio::ip::tcp::endpoint> endpoints;
769775
asio::ip::tcp::endpoint result;
@@ -814,7 +820,7 @@ void test_async_connect_range()
814820
void test_async_connect_range_cond()
815821
{
816822
connection_sink sink;
817-
asio::io_context io_context;
823+
asio::io_context io_context(io_context_config);
818824
asio::ip::tcp::socket socket(io_context);
819825
std::vector<asio::ip::tcp::endpoint> endpoints;
820826
asio::ip::tcp::endpoint result;
@@ -977,7 +983,7 @@ void test_async_connect_range_cond()
977983
void test_async_connect_iter()
978984
{
979985
connection_sink sink;
980-
asio::io_context io_context;
986+
asio::io_context io_context(io_context_config);
981987
asio::ip::tcp::socket socket(io_context);
982988
std::vector<asio::ip::tcp::endpoint> endpoints;
983989
const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;
@@ -1029,7 +1035,7 @@ void test_async_connect_iter()
10291035
void test_async_connect_iter_cond()
10301036
{
10311037
connection_sink sink;
1032-
asio::io_context io_context;
1038+
asio::io_context io_context(io_context_config);
10331039
asio::ip::tcp::socket socket(io_context);
10341040
std::vector<asio::ip::tcp::endpoint> endpoints;
10351041
const std::vector<asio::ip::tcp::endpoint>& cendpoints = endpoints;

0 commit comments

Comments
 (0)