]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: be more memory efficient handling RPZ reloads 13462/head
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 8 Nov 2023 10:05:49 +0000 (11:05 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 8 Nov 2023 10:47:20 +0000 (11:47 +0100)
There were two things non-optimal:

- The old zone contents is being kept in memory during a sleep for the
next iteration and then thrown away. Fix: throw away before the sleep.

- The Lua config is kept alive. This causes refs to old config
data to stay around until all RPZ threads have cleared that config.
Fix that by making the config loop-local and load it after the sleep
call.

Above claims confirmed by adding some debug code showing the ref counts
for a config with many RPZs.

pdns/recursordist/rpzloader.cc

index fb6eb04463cd52700cf643cf7183070761884158..9ebae34c21741bc1c72999dd3dad14f55c3e31f4 100644 (file)
@@ -389,12 +389,10 @@ void RPZIXFRTracker(const std::vector<ComboAddress>& primaries, const boost::opt
 {
   setThreadName("rec/rpzixfr");
   bool isPreloaded = sr != nullptr;
-  auto luaconfsLocal = g_luaconfs.getLocal();
-
   auto logger = g_slog->withName("rpz");
 
   /* we can _never_ modify this zone directly, we need to do a full copy then replace the existing zone */
-  std::shared_ptr<DNSFilterEngine::Zone> oldZone = luaconfsLocal->dfe.getZone(zoneIdx);
+  std::shared_ptr<DNSFilterEngine::Zone> oldZone = g_luaconfs.getLocal()->dfe.getZone(zoneIdx);
   if (!oldZone) {
     SLOG(g_log << Logger::Error << "Unable to retrieve RPZ zone with index " << zoneIdx << " from the configuration, exiting" << endl,
          logger->error(Logr::Error, "Unable to retrieve RPZ zone from configuration", "index", Logging::Loggable(zoneIdx)));
@@ -444,7 +442,8 @@ void RPZIXFRTracker(const std::vector<ComboAddress>& primaries, const boost::opt
         incRPZFailedTransfers(polName);
       }
     }
-
+    // Release newZone before (long) sleep to reduce memory usage
+    newZone = nullptr;
     if (!sr) {
       sleep(refresh);
     }
@@ -453,6 +452,8 @@ void RPZIXFRTracker(const std::vector<ComboAddress>& primaries, const boost::opt
   bool skipRefreshDelay = isPreloaded;
 
   for (;;) {
+    // Don't hold on to oldZone, it well be re-assigned after sleep in the try block
+    oldZone = nullptr;
     DNSRecord dr;
     dr.setContent(sr);
 
@@ -462,6 +463,7 @@ void RPZIXFRTracker(const std::vector<ComboAddress>& primaries, const boost::opt
     else {
       sleep(refresh);
     }
+    auto luaconfsLocal = g_luaconfs.getLocal();
 
     if (luaconfsLocal->generation != configGeneration) {
       /* the configuration has been reloaded, meaning that a new thread