]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/queue: do not check if a request is ready multiple times in a single event
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 4 Jan 2024 15:13:40 +0000 (00:13 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 4 Jan 2024 16:37:42 +0000 (01:37 +0900)
Some checks are slightly heavy, and there may be huge number of
interfaces. So, prcessing whole queue multiple times in a single event
may decrease the performance. Let's process the queued requests once per
event.

src/network/networkd-queue.c

index 6fafe42c0f857b9c76bdb21698bd332953f653c7..7c6263096862b28da29970e893949fe2fb14f322 100644 (file)
@@ -215,52 +215,42 @@ int link_queue_request_full(
 }
 
 int manager_process_requests(Manager *manager) {
+        Request *req;
         int r;
 
         assert(manager);
 
-        for (;;) {
-                bool processed = false;
-                Request *req;
+        ORDERED_SET_FOREACH(req, manager->request_queue) {
+                _cleanup_(link_unrefp) Link *link = link_ref(req->link);
 
-                ORDERED_SET_FOREACH(req, manager->request_queue) {
-                        _cleanup_(link_unrefp) Link *link = link_ref(req->link);
+                assert(req->process);
 
-                        assert(req->process);
+                if (req->waiting_reply)
+                        continue; /* Waiting for netlink reply. */
 
-                        if (req->waiting_reply)
-                                continue; /* Waiting for netlink reply. */
+                /* Typically, requests send netlink message asynchronously. If there are many requests
+                 * queued, then this event may make reply callback queue in sd-netlink full. */
+                if (netlink_get_reply_callback_count(manager->rtnl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
+                    netlink_get_reply_callback_count(manager->genl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
+                    fw_ctx_get_reply_callback_count(manager->fw_ctx) >= REPLY_CALLBACK_COUNT_THRESHOLD)
+                        return 0;
 
-                        /* Typically, requests send netlink message asynchronously. If there are many requests
-                         * queued, then this event may make reply callback queue in sd-netlink full. */
-                        if (netlink_get_reply_callback_count(manager->rtnl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
-                            netlink_get_reply_callback_count(manager->genl) >= REPLY_CALLBACK_COUNT_THRESHOLD ||
-                            fw_ctx_get_reply_callback_count(manager->fw_ctx) >= REPLY_CALLBACK_COUNT_THRESHOLD)
-                                return 0;
+                r = req->process(req, link, req->userdata);
+                if (r == 0)
+                        continue; /* The request is not ready. */
 
-                        r = req->process(req, link, req->userdata);
-                        if (r == 0)
-                                continue;
+                /* If the request sends netlink message, e.g. for Address or so, the Request object is
+                 * referenced by the netlink slot, and will be detached later by its destroy callback.
+                 * Otherwise, e.g. for DHCP client or so, detach the request from queue now. */
+                if (!req->waiting_reply)
+                        request_detach(manager, req);
 
-                        processed = true;
-
-                        /* If the request sends netlink message, e.g. for Address or so, the Request object
-                         * is referenced by the netlink slot, and will be detached later by its destroy callback.
-                         * Otherwise, e.g. for DHCP client or so, detach the request from queue now. */
-                        if (!req->waiting_reply)
-                                request_detach(manager, req);
-
-                        if (r < 0 && link) {
-                                link_enter_failed(link);
-                                /* link_enter_failed() may remove multiple requests,
-                                 * hence we need to exit from the loop. */
-                                break;
-                        }
-                }
-
-                /* When at least one request is processed, then another request may be ready now. */
-                if (!processed)
+                if (r < 0 && link) {
+                        link_enter_failed(link);
+                        /* link_enter_failed() may remove multiple requests,
+                         * hence we need to exit from the loop. */
                         break;
+                }
         }
 
         return 0;