summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faulet <cfaulet@haproxy.com>2023-05-16 18:28:57 +0200
committerChristopher Faulet <cfaulet@haproxy.com>2023-05-17 16:48:33 +0200
commit06e9c81bd078b14dfc7d728b027fe42e5dc4755c (patch)
treec5dd1d70572162e89b22b4a049744e8dcfd7068d
parent8bca3cc8c766cada51805631fb1f72475b89bc44 (diff)
downloadhaproxy-06e9c81bd078b14dfc7d728b027fe42e5dc4755c.tar.gz
MEDIUM: resolvers: Stop scheduling resolution during stopping stage
When the process is stopping, the server resolutions are suspended. However the task is still periodically woken up for nothing. If there is a huge number of resolution, it may lead to a noticeable CPU consumption for no reason. To avoid this extra CPU cost, we stop to schedule the the resolution tasks during the stopping stage. Of course, it is only true for server resolutinos. Dynamic ones, via do-resolve actions, are not concerned. These ones must still be triggered during stopping stage. Concretly, during the stopping stage, the resolvers task is no longer scheduled if there is no running resolutions. In this case, if a do-resolve action is evaluated, the task is woken up. This patch should partially solve the issue #2145.
-rw-r--r--src/resolvers.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/resolvers.c b/src/resolvers.c
index add9a25ab..c820d9cfb 100644
--- a/src/resolvers.c
+++ b/src/resolvers.c
@@ -459,7 +459,7 @@ void resolv_trigger_resolution(struct resolv_requester *req)
/* The resolution must not be triggered yet. Use the cached response, if
* valid */
exp = tick_add(res->last_resolution, resolvers->hold.valid);
- if (resolvers->t && (res->status != RSLV_STATUS_VALID ||
+ if (resolvers->t && (!tick_isset(resolvers->t->expire) || res->status != RSLV_STATUS_VALID ||
!tick_isset(res->last_resolution) || tick_is_expired(exp, now_ms))) {
/* If the resolution is not running and the requester is a
* server, reset the resolution timer to force a quick
@@ -2457,6 +2457,9 @@ struct task *process_resolvers(struct task *t, void *context, unsigned int state
if (unlikely(stopping)) {
struct dns_nameserver *ns;
+ if (LIST_ISEMPTY(&resolvers->resolutions.curr))
+ t->expire = TICK_ETERNITY;
+
list_for_each_entry(ns, &resolvers->nameservers, list) {
if (ns->stream)
task_wakeup(ns->stream->task_idle, TASK_WOKEN_MSG);