]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Reuse the vector of packets between XSK recv rounds 16511/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 14 Nov 2025 13:48:30 +0000 (14:48 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 14 Nov 2025 13:48:30 +0000 (14:48 +0100)
The existing code was allocating a new vector for every call
to `XskSocket::recv()` which was just silly.

Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist-xsk.cc
pdns/dnsdistdist/xsk.cc
pdns/dnsdistdist/xsk.hh

index 42e74bd966426912ac63b1fb3ba873d5d4e78589..9a8ebd6a4b9d090ad5fd94a06544a20a7e3156dc 100644 (file)
@@ -133,13 +133,14 @@ void XskRouter(std::shared_ptr<XskSocket> xsk)
   const auto& fds = xsk->getDescriptors();
   // list of workers that need to be notified
   std::set<int> needNotify;
+  std::vector<XskPacket> packets;
   while (true) {
     try {
       auto ready = xsk->wait(-1);
       dnsdist::configuration::refreshLocalRuntimeConfiguration();
       // descriptor 0 gets incoming AF_XDP packets
       if ((fds.at(0).revents & POLLIN) != 0) {
-        auto packets = xsk->recv(64, &failed);
+        xsk->recv(packets, 64, &failed);
         dnsdist::metrics::g_stats.nonCompliantQueries += failed;
         for (auto& packet : packets) {
           const auto dest = packet.getToAddr();
index 5e6eb4c7aafec4e02300ebafebce736c892661c0..430fcfb9b3f0d998a6250cb9573b13aea109231c 100644 (file)
@@ -372,21 +372,21 @@ void XskSocket::send(std::vector<XskPacket>& packets)
   }
 }
 
-std::vector<XskPacket> XskSocket::recv(uint32_t recvSizeMax, uint32_t* failedCount)
+void XskSocket::recv(std::vector<XskPacket>& packets, uint32_t recvSizeMax, uint32_t* failedCount)
 {
+  packets.clear();
   uint32_t idx{0};
-  std::vector<XskPacket> res;
   // how many descriptors to packets have been filled
   const auto recvSize = xsk_ring_cons__peek(&rx, recvSizeMax, &idx);
   if (recvSize == 0) {
-    return res;
+    return;
   }
 
   // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
   const auto baseAddr = reinterpret_cast<uint64_t>(umem.bufBase);
   uint32_t failed = 0;
   uint32_t processed = 0;
-  res.reserve(recvSize);
+  packets.reserve(recvSize);
   for (; processed < recvSize; processed++) {
     try {
       const auto* desc = xsk_ring_cons__rx_desc(&rx, idx++);
@@ -401,7 +401,7 @@ std::vector<XskPacket> XskSocket::recv(uint32_t recvSizeMax, uint32_t* failedCou
         markAsFree(packet);
       }
       else {
-        res.push_back(packet);
+        packets.push_back(packet);
       }
     }
     catch (const std::exception& exp) {
@@ -423,8 +423,6 @@ std::vector<XskPacket> XskSocket::recv(uint32_t recvSizeMax, uint32_t* failedCou
   if (failedCount != nullptr) {
     *failedCount = failed;
   }
-
-  return res;
 }
 
 void XskSocket::pickUpReadyPacket(std::vector<XskPacket>& packets)
index ff36be5ecd96c9d7d2a0b0026728a1d94f75ea7a..79cb31b464d2b654cd919d5fa2e3d6a1219bbf35 100644 (file)
@@ -137,7 +137,7 @@ public:
   // add as many packets as possible to the rx queue for sending */
   void send(std::vector<XskPacket>& packets);
   // look at incoming packets in rx, return them if parsing succeeeded
-  [[nodiscard]] std::vector<XskPacket> recv(uint32_t recvSizeMax, uint32_t* failedCount);
+  void recv(std::vector<XskPacket>& packets, uint32_t recvSizeMax, uint32_t* failedCount);
   void addWorker(std::shared_ptr<XskWorker> worker);
   void addWorkerRoute(const std::shared_ptr<XskWorker>& worker, const ComboAddress& dest);
   void removeWorkerRoute(const ComboAddress& dest);