]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/defer: improve time measuring
authorLukáš Ondráček <lukas.ondracek@nic.cz>
Thu, 5 Dec 2024 18:50:57 +0000 (19:50 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Wed, 11 Dec 2024 13:20:16 +0000 (14:20 +0100)
daemon/defer.c
daemon/defer.h
daemon/session2.c
daemon/worker.c

index df2566bedb8ca9fec8197f94d8cd07ff229eb61c..aa29d2f1c8b8f1ddd78d6830175c7543e0a392bc 100644 (file)
@@ -552,9 +552,11 @@ static enum protolayer_event_cb_result pl_defer_event_unwrap(
                // disable accounting only for events that cannot occur during incoming data processing
                phase_accounting = false;
        }
-       if (!defer || session->outgoing)
+       if (!defer || !session->stream || session->outgoing)
                return PROTOLAYER_EVENT_PROPAGATE;
 
+       defer_sample_addr((const union kr_sockaddr *)session->comm_storage.src_addr, session->stream);
+
        struct pl_defer_sess_data *sdata = sess_data;
        if ((event == PROTOLAYER_EVENT_EOF) && (queue_len(sdata->queue) > 0)) {
                // defer EOF event if unprocessed data remain, baton is dropped if any
index 5a26faa67b6045070ac9d92ade498e2cf9af4e60..b24ee70ecad92b00b9b18653e3094ac6d4ec2dee 100644 (file)
@@ -102,6 +102,11 @@ static inline void defer_sample_stop_stamp(uint64_t stamp)
        defer_charge(elapsed, &defer_sample_state.addr, defer_sample_state.stream);
 }
 
+static inline bool defer_sample_is_accounting(void)
+{
+       return defer_sample_state.is_accounting;
+}
+
 /// Start accounting work; optionally save state of current accounting.
 /// Current state can be saved only after having an address assigned.
 static inline void defer_sample_start(defer_sample_state_t *prev_state_out) {
index c1c0d7ceedc816ea6b8e2a9469181a632d99a6f2..faca57bfe564a3ce9b40894c470ac2df4a8df700 100644 (file)
@@ -980,10 +980,8 @@ uv_handle_t *session2_get_handle(struct session2 *s)
 
 static void session2_on_timeout(uv_timer_t *timer)
 {
-       defer_sample_start(NULL);
        struct session2 *s = timer->data;
        session2_event(s, s->timer_event, NULL);
-       defer_sample_stop(NULL, false);
 }
 
 int session2_timer_start(struct session2 *s, enum protolayer_event_type event, uint64_t timeout, uint64_t repeat)
@@ -1347,7 +1345,19 @@ static void session2_event_unwrap(struct session2 *s, ssize_t start_ix, enum pro
 
 void session2_event(struct session2 *s, enum protolayer_event_type event, void *baton)
 {
+       /* Events may be sent from inside or outside of already measured code.
+        * From inside: close by us, statistics, ...
+        * From outside: timeout, EOF, close by external reasons, ... */
+       bool defer_accounting_here = false;
+       if (!defer_sample_is_accounting() && s->stream && !s->outgoing) {
+               defer_sample_start(NULL);
+               defer_accounting_here = true;
+       }
+
        session2_event_unwrap(s, 0, event, baton);
+
+       if (defer_accounting_here)
+               defer_sample_stop(NULL, false);
 }
 
 void session2_event_after(struct session2 *s, enum protolayer_type protocol,
index 55c91690498970ecbdfdf4347fedc6f0b796ce38..ece3fd95396a06f7a9bd5dc3c9f717b37f287711 100644 (file)
@@ -703,10 +703,18 @@ static struct kr_query *task_get_last_pending_query(struct qr_task *task)
 
 static int send_waiting(struct session2 *session)
 {
+       if (session2_waitinglist_is_empty(session))
+               return 0;
+
+       defer_sample_state_t defer_prev_sample_state;
+       defer_sample_start(&defer_prev_sample_state);
        int ret = 0;
-       while (!session2_waitinglist_is_empty(session)) {
+       do {
                struct qr_task *t = session2_waitinglist_get(session);
+               if (t->ctx->source.session)
+                       defer_sample_addr(&t->ctx->source.addr, t->ctx->source.session->stream);
                ret = qr_task_send(t, session, NULL, NULL);
+               defer_sample_restart();
                if (ret != 0) {
                        struct sockaddr *peer = session2_get_peer(session);
                        session2_waitinglist_finalize(session, KR_STATE_FAIL);
@@ -716,7 +724,9 @@ static int send_waiting(struct session2 *session)
                        break;
                }
                session2_waitinglist_pop(session, true);
-       }
+       } while (!session2_waitinglist_is_empty(session));
+       defer_sample_stop(&defer_prev_sample_state, true);
+
        return ret;
 }
 
@@ -1878,13 +1888,19 @@ static enum protolayer_event_cb_result pl_dns_stream_resolution_timeout(
        } else {
                /* Normally it should not happen,
                 * but better to check if there anything in this list. */
-               while (!session2_waitinglist_is_empty(s)) {
-                       struct qr_task *t = session2_waitinglist_pop(s, false);
-                       worker_task_finalize(t, KR_STATE_FAIL);
-                       worker_task_unref(t);
-                       the_worker->stats.timeout += 1;
-                       if (s->closing)
-                               return PROTOLAYER_EVENT_PROPAGATE;
+               if (!session2_waitinglist_is_empty(s)) {
+                       defer_sample_state_t defer_prev_sample_state;
+                       defer_sample_start(&defer_prev_sample_state);
+                       do {
+                               struct qr_task *t = session2_waitinglist_pop(s, false);
+                               worker_task_finalize(t, KR_STATE_FAIL);
+                               worker_task_unref(t);
+                               the_worker->stats.timeout += 1;
+                               if (s->closing)
+                                       return PROTOLAYER_EVENT_PROPAGATE;
+                               defer_sample_restart();
+                       } while (!session2_waitinglist_is_empty(s));
+                       defer_sample_stop(&defer_prev_sample_state, true);
                }
                uint64_t idle_in_timeout = the_network->tcp.in_idle_timeout;
                uint64_t idle_time = kr_now() - s->last_activity;
@@ -1997,6 +2013,13 @@ static enum protolayer_event_cb_result pl_dns_stream_disconnected(
 
        stream->connected = false;
 
+       if (session2_is_empty(session))
+               return PROTOLAYER_EVENT_PROPAGATE;
+
+       defer_sample_state_t defer_prev_sample_state;
+       if (session->outgoing)
+               defer_sample_start(&defer_prev_sample_state);
+
        while (!session2_waitinglist_is_empty(session)) {
                struct qr_task *task = session2_waitinglist_pop(session, false);
                kr_assert(task->refs > 1);
@@ -2013,6 +2036,7 @@ static enum protolayer_event_cb_result pl_dns_stream_disconnected(
                                qry->flags.TCP = false;
                        }
                        qr_task_step(task, NULL, NULL);
+                       defer_sample_restart();
                } else {
                        kr_assert(task->ctx->source.session == session);
                        task->ctx->source.session = NULL;
@@ -2029,6 +2053,7 @@ static enum protolayer_event_cb_result pl_dns_stream_disconnected(
                                qry->flags.TCP = false;
                        }
                        qr_task_step(task, NULL, NULL);
+                       defer_sample_restart();
                } else {
                        kr_assert(task->ctx->source.session == session);
                        task->ctx->source.session = NULL;
@@ -2036,6 +2061,9 @@ static enum protolayer_event_cb_result pl_dns_stream_disconnected(
                worker_task_unref(task);
        }
 
+       if (session->outgoing)
+               defer_sample_stop(&defer_prev_sample_state, true);
+
        return PROTOLAYER_EVENT_PROPAGATE;
 }