From eb11575149358dbee7af95a9fa686e4c20d21a30 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 14 Nov 2025 14:48:30 +0100 Subject: [PATCH] dnsdist: Reuse the vector of packets between XSK recv rounds The existing code was allocating a new vector for every call to `XskSocket::recv()` which was just silly. Signed-off-by: Remi Gacogne --- pdns/dnsdistdist/dnsdist-xsk.cc | 3 ++- pdns/dnsdistdist/xsk.cc | 12 +++++------- pdns/dnsdistdist/xsk.hh | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-xsk.cc b/pdns/dnsdistdist/dnsdist-xsk.cc index 42e74bd966..9a8ebd6a4b 100644 --- a/pdns/dnsdistdist/dnsdist-xsk.cc +++ b/pdns/dnsdistdist/dnsdist-xsk.cc @@ -133,13 +133,14 @@ void XskRouter(std::shared_ptr xsk) const auto& fds = xsk->getDescriptors(); // list of workers that need to be notified std::set needNotify; + std::vector 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(); diff --git a/pdns/dnsdistdist/xsk.cc b/pdns/dnsdistdist/xsk.cc index 5e6eb4c7aa..430fcfb9b3 100644 --- a/pdns/dnsdistdist/xsk.cc +++ b/pdns/dnsdistdist/xsk.cc @@ -372,21 +372,21 @@ void XskSocket::send(std::vector& packets) } } -std::vector XskSocket::recv(uint32_t recvSizeMax, uint32_t* failedCount) +void XskSocket::recv(std::vector& packets, uint32_t recvSizeMax, uint32_t* failedCount) { + packets.clear(); uint32_t idx{0}; - std::vector 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(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 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 XskSocket::recv(uint32_t recvSizeMax, uint32_t* failedCou if (failedCount != nullptr) { *failedCount = failed; } - - return res; } void XskSocket::pickUpReadyPacket(std::vector& packets) diff --git a/pdns/dnsdistdist/xsk.hh b/pdns/dnsdistdist/xsk.hh index ff36be5ecd..79cb31b464 100644 --- a/pdns/dnsdistdist/xsk.hh +++ b/pdns/dnsdistdist/xsk.hh @@ -137,7 +137,7 @@ public: // add as many packets as possible to the rx queue for sending */ void send(std::vector& packets); // look at incoming packets in rx, return them if parsing succeeeded - [[nodiscard]] std::vector recv(uint32_t recvSizeMax, uint32_t* failedCount); + void recv(std::vector& packets, uint32_t recvSizeMax, uint32_t* failedCount); void addWorker(std::shared_ptr worker); void addWorkerRoute(const std::shared_ptr& worker, const ComboAddress& dest); void removeWorkerRoute(const ComboAddress& dest); -- 2.47.3