summaryrefslogtreecommitdiffstats
path: root/daemon/worker.c
diff options
context:
space:
mode:
authorOto Šťáva <oto.stava@nic.cz>2024-05-22 15:18:30 +0200
committerOto Šťáva <oto.stava@nic.cz>2024-06-04 13:05:00 +0200
commit9f6042c38851ebd3494810e2227ea4ffa0534648 (patch)
tree15c844111a027673ddfbf7d1e09bbd814cc69b65 /daemon/worker.c
parentdaemon/proxyv2: move PROXY protocol into its own layer (diff)
downloadknot-resolver-9f6042c38851ebd3494810e2227ea4ffa0534648.tar.xz
knot-resolver-9f6042c38851ebd3494810e2227ea4ffa0534648.zip
daemon/session2: optimize allocations
A) Context-specific allocations ------------------------------- There were two problems: 1) Some payloads are short-lived (e.g. allocated on stack) and we need to make a copy of them if the iteration over protocol layers becomes asynchronous. 2) The `pl_dns_stream_wrap` function used a mempool belonging to its session-wide context. Some sessions may live for a long time, which could potentially lead to needlessly long-lived memory allocations. Both of these problems are solved in this commit by using a new `knot_mm_t pool` field in `struct protolayer_iter_ctx`, which lives only for a single submit (and survives asynchronicity). The whole pool is then freed all at once when the `struct protolayer_iter_ctx` is finalized. B) Merging `struct protolayer_manager` into `struct session2` ------------------------------------------------------------- It actually made no real sense to have the two separated. It only introduced an extra layer of indirection and many layers actually needed to access both anyway. This should simplify things considerably.
Diffstat (limited to 'daemon/worker.c')
-rw-r--r--daemon/worker.c63
1 files changed, 15 insertions, 48 deletions
diff --git a/daemon/worker.c b/daemon/worker.c
index 31070f0d..5473c8b8 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -1710,12 +1710,11 @@ static inline knot_pkt_t *produce_packet(uint8_t *buf, size_t buf_len)
static enum protolayer_event_cb_result pl_dns_dgram_event_unwrap(
enum protolayer_event_type event, void **baton,
- struct protolayer_manager *manager, void *sess_data)
+ struct session2 *session, void *sess_data)
{
if (event != PROTOLAYER_EVENT_GENERAL_TIMEOUT)
return PROTOLAYER_EVENT_PROPAGATE;
- struct session2 *session = manager->session;
if (session2_tasklist_get_len(session) != 1 ||
!session2_waitinglist_is_empty(session))
return PROTOLAYER_EVENT_PROPAGATE;
@@ -1753,7 +1752,7 @@ static size_t pl_dns_dgram_wire_buf_overhead(bool outgoing)
static enum protolayer_iter_cb_result pl_dns_dgram_unwrap(
void *sess_data, void *iter_data, struct protolayer_iter_ctx *ctx)
{
- struct session2 *session = ctx->manager->session;
+ struct session2 *session = ctx->session;
if (ctx->payload.type == PROTOLAYER_PAYLOAD_IOVEC) {
int ret = kr_ok();
@@ -1823,41 +1822,24 @@ struct pl_dns_stream_sess_data {
bool connected : 1; /**< True: The stream is connected */
};
-struct pl_dns_stream_iter_data {
- struct protolayer_data h;
- struct {
- knot_mm_t *pool;
- void *mem;
- } sent;
-};
-
-static int pl_dns_stream_sess_init(struct protolayer_manager *manager,
- void *sess_data, void *param)
+static int pl_dns_stream_sess_init(struct session2 *session,
+ void *sess_data, void *param)
{
/* _UNSIZED_STREAM and _MULTI_STREAM - don't forget to split if needed
* at some point */
- manager->session->stream = true;
+ session->stream = true;
return kr_ok();
}
-static int pl_dns_single_stream_sess_init(struct protolayer_manager *manager,
+static int pl_dns_single_stream_sess_init(struct session2 *session,
void *sess_data, void *param)
{
- manager->session->stream = true;
+ session->stream = true;
struct pl_dns_stream_sess_data *stream = sess_data;
stream->single = true;
return kr_ok();
}
-static int pl_dns_stream_iter_deinit(struct protolayer_manager *manager,
- struct protolayer_iter_ctx *ctx,
- void *iter_data)
-{
- struct pl_dns_stream_iter_data *stream = iter_data;
- mm_free(stream->sent.pool, stream->sent.mem);
- return kr_ok();
-}
-
static enum protolayer_event_cb_result pl_dns_stream_resolution_timeout(
struct session2 *s)
{
@@ -2046,9 +2028,8 @@ static enum protolayer_event_cb_result pl_dns_stream_disconnected(
static enum protolayer_event_cb_result pl_dns_stream_event_unwrap(
enum protolayer_event_type event, void **baton,
- struct protolayer_manager *manager, void *sess_data)
+ struct session2 *session, void *sess_data)
{
- struct session2 *session = manager->session;
if (session->closing)
return PROTOLAYER_EVENT_PROPAGATE;
@@ -2056,10 +2037,10 @@ static enum protolayer_event_cb_result pl_dns_stream_event_unwrap(
switch (event) {
case PROTOLAYER_EVENT_GENERAL_TIMEOUT:
- return pl_dns_stream_resolution_timeout(manager->session);
+ return pl_dns_stream_resolution_timeout(session);
case PROTOLAYER_EVENT_CONNECT_TIMEOUT:
- return pl_dns_stream_connection_fail(manager->session,
+ return pl_dns_stream_connection_fail(session,
KR_SELECTION_TCP_CONNECT_TIMEOUT);
case PROTOLAYER_EVENT_CONNECT:
@@ -2069,7 +2050,7 @@ static enum protolayer_event_cb_result pl_dns_stream_event_unwrap(
enum kr_selection_error err = (*baton)
? *(enum kr_selection_error *)baton
: KR_SELECTION_TCP_CONNECT_FAILED;
- return pl_dns_stream_connection_fail(manager->session, err);
+ return pl_dns_stream_connection_fail(session, err);
case PROTOLAYER_EVENT_DISCONNECT:
case PROTOLAYER_EVENT_CLOSE:
@@ -2171,7 +2152,7 @@ static enum protolayer_iter_cb_result pl_dns_stream_unwrap(
}
int status = kr_ok();
- struct session2 *session = ctx->manager->session;
+ struct session2 *session = ctx->session;
struct pl_dns_stream_sess_data *stream_sess = sess_data;
struct wire_buf *wb = ctx->payload.wire_buf;
@@ -2235,18 +2216,12 @@ struct sized_iovs {
static enum protolayer_iter_cb_result pl_dns_stream_wrap(
void *sess_data, void *iter_data, struct protolayer_iter_ctx *ctx)
{
- struct pl_dns_stream_iter_data *stream = iter_data;
- struct session2 *s = ctx->manager->session;
-
- if (kr_fails_assert(!stream->sent.mem))
- return protolayer_break(ctx, kr_error(EINVAL));
-
if (ctx->payload.type == PROTOLAYER_PAYLOAD_BUFFER) {
if (kr_fails_assert(ctx->payload.buffer.len <= UINT16_MAX))
return protolayer_break(ctx, kr_error(EMSGSIZE));
const int iovcnt = 2;
- struct sized_iovs *siov = mm_alloc(&s->pool,
+ struct sized_iovs *siov = mm_alloc(&ctx->pool,
sizeof(*siov) + iovcnt * sizeof(struct iovec));
kr_require(siov);
knot_wire_write_u16(siov->nlen, ctx->payload.buffer.len);
@@ -2259,14 +2234,11 @@ static enum protolayer_iter_cb_result pl_dns_stream_wrap(
.iov_len = ctx->payload.buffer.len
};
- stream->sent.mem = siov;
- stream->sent.pool = &s->pool;
-
ctx->payload = protolayer_payload_iovec(siov->iovs, iovcnt, false);
return protolayer_continue(ctx);
} else if (ctx->payload.type == PROTOLAYER_PAYLOAD_IOVEC) {
const int iovcnt = 1 + ctx->payload.iovec.cnt;
- struct sized_iovs *siov = mm_alloc(&s->pool,
+ struct sized_iovs *siov = mm_alloc(&ctx->pool,
sizeof(*siov) + iovcnt * sizeof(struct iovec));
kr_require(siov);
@@ -2285,9 +2257,6 @@ static enum protolayer_iter_cb_result pl_dns_stream_wrap(
.iov_len = sizeof(siov->nlen)
};
- stream->sent.mem = siov;
- stream->sent.pool = &s->pool;
-
ctx->payload = protolayer_payload_iovec(siov->iovs, iovcnt, false);
return protolayer_continue(ctx);
} else {
@@ -2296,7 +2265,7 @@ static enum protolayer_iter_cb_result pl_dns_stream_wrap(
}
}
-static void pl_dns_stream_request_init(struct protolayer_manager *manager,
+static void pl_dns_stream_request_init(struct session2 *session,
struct kr_request *req,
void *sess_data)
{
@@ -2326,10 +2295,8 @@ int worker_init(void)
};
const struct protolayer_globals stream_common = {
.sess_size = sizeof(struct pl_dns_stream_sess_data),
- .iter_size = sizeof(struct pl_dns_stream_iter_data),
.wire_buf_overhead = KNOT_WIRE_MAX_PKTSIZE,
.sess_init = NULL, /* replaced in specific layers below */
- .iter_deinit = pl_dns_stream_iter_deinit,
.unwrap = pl_dns_stream_unwrap,
.wrap = pl_dns_stream_wrap,
.event_unwrap = pl_dns_stream_event_unwrap,