network/queue: do not check if a request is ready multiple times in a single event

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.
This commit is contained in:
Yu Watanabe
2024-01-05 01:37:42 +09:00
parent 115d6abf87
commit 981278e144
+25 -35
View 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;