]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
master: Avoid high CPU usage when process_min_avail reaches process_limit
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 5 Aug 2021 14:53:58 +0000 (17:53 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 5 Aug 2021 17:26:46 +0000 (20:26 +0300)
process_min_avail handling always created a 0ms timeout to try to create the
missing processes. This timeout was supposed to stop when it couldn't launch
all the wanted processes, but the check wasn't done right. This ended up
causing the timeout to be called rapidly over and over again.

src/master/service-monitor.c

index a0921fa9f956380b4fa81cedacfd243a08db0914..3e838c9b813d5a594759605d1d5dd354f4821f76 100644 (file)
@@ -351,7 +351,7 @@ service_monitor_start_count(struct service *service, unsigned int limit)
                /* we created some processes, they'll do the listening now */
                service_monitor_listen_stop(service);
        }
-       return i == count;
+       return i >= limit;
 }
 
 static void service_monitor_prefork_timeout(struct service *service)
@@ -365,8 +365,12 @@ static void service_monitor_prefork_timeout(struct service *service)
        }
        if (service->process_avail < service->set->process_min_avail) {
                if (service_monitor_start_count(service, SERVICE_PREFORK_MAX_AT_ONCE) &&
-                   service->process_avail < service->set->process_min_avail)
+                   service->process_avail < service->set->process_min_avail) {
+                       /* All SERVICE_PREFORK_MAX_AT_ONCE were created, but
+                          it still wasn't enough. Launch more in the next
+                          timeout. */
                        return;
+               }
        }
        timeout_remove(&service->to_prefork);
 }