From b0c90cfed89a767622f9c72cff96d782bd1767f2 Mon Sep 17 00:00:00 2001 From: Vladislav Abrosimov Date: Sun, 28 Jan 2024 17:53:55 +0300 Subject: [PATCH] Move tsc monitoring into cli --- cli/develop.h | 198 +++++++++++++++++++++++++++++++++++++++ cli/helper.h | 7 ++ cli/main.cpp | 1 + cli/show.h | 47 +++++----- common/config.release.h | 1 + common/tsc_deltas.h | 110 ++++++++++++++++++++++ dataplane/dataplane.cpp | 11 ++- dataplane/dataplane.h | 1 + dataplane/globalbase.cpp | 2 + dataplane/globalbase.h | 9 +- dataplane/tsc_deltas.h | 104 -------------------- dataplane/worker.cpp | 57 +++++------ dataplane/worker.h | 2 +- 13 files changed, 389 insertions(+), 161 deletions(-) create mode 100644 common/tsc_deltas.h delete mode 100644 dataplane/tsc_deltas.h diff --git a/cli/develop.h b/cli/develop.h index dc99a1e4..c45a39de 100644 --- a/cli/develop.h +++ b/cli/develop.h @@ -1,7 +1,15 @@ #pragma once +#include +#include +#include +#include +#include +#include + #include "common/icontrolplane.h" #include "common/idataplane.h" +#include "common/tsc_deltas.h" #include "helper.h" @@ -160,6 +168,196 @@ void counter(const uint32_t& counter_id, table.print(); } +using namespace ::dataplane::perf; +class tsc_monitoring_t +{ +public: + void connect_shm() + { + interface::dataPlane dataplane; + const auto response = dataplane.get_shm_tsc_info(); + std::map ipc_cache; + + for (const auto& [core, socket, ipc_key, offset] : response) + { + (void)socket; + if (ipc_cache.find(ipc_key) == ipc_cache.end()) + { + auto shmid = shmget(ipc_key, 0, 0); + if (shmid == -1) + { + throw std::string("shmget(") + std::to_string(ipc_key) + ", 0, 0) = " + std::strerror(errno); + } + auto shmaddr = shmat(shmid, NULL, SHM_RDONLY); + if (shmaddr == (void*)-1) + { + throw std::string("shmat(") + std::to_string(ipc_key) + ", NULL, 0) = " + std::strerror(errno); + } + + ipc_cache[ipc_key] = shmaddr; + } + + auto counter_addr = (tsc_deltas*)((intptr_t)ipc_cache[ipc_key] + offset); + worker_counters.emplace_back(core, counter_addr, tsc_deltas{}, overflow_store{}); + } + } + + void monitor() + { + connect_shm(); + for (auto iter = 0;; iter++) + { + if (iter % 4 == 0) + { + insert_header(); + } + + for (auto& [core_id, counter, previous_value, overflow_store] : worker_counters) + { + const auto& counter_copy = *counter; + for (auto bin = 0; bin < YANET_TSC_BINS_N; bin++) + { + overflow_store.handle_overflow(counter_copy, previous_value, bin); + if (iter % 4 == 0) + { + insert_bin(counter_copy, overflow_store, bin, core_id); + } + } + + previous_value = counter_copy; + } + + if (iter % 4 == 0) + { + table.render(); + } + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + } + +protected: + struct overflow_store; + + void insert_header() + { + table.insert("core_id", + "iter_num", + "logicalPort_ingress", + "acl_ingress4", + "acl_ingress6", + "tun64_ipv4", + "tun64_ipv6", + "route4", + "route6", + "decap", + "nat64stateful_lan", + "nat64stateful_wan", + "nat64stateless_egress", + "nat64stateless_ingress", + "balancer", + "balancer_icmp_reply", + "balancer_icmp_forward", + "route_tunnel4", + "route_tunnel6", + "acl_egress4", + "acl_egress6", + "logicalPort_egress", + "controlPlane"); + } + + void insert_bin(const tsc_deltas& cnt, const overflow_store& of_store, int bin, uint32_t core_id) + { + table.insert(bin == 0 ? std::to_string(core_id) : std::string{}, + bin == 0 ? std::to_string(cnt.iter_num) : std::string{}, + of_store.logicalPort_ingress_handle[bin] + cnt.logicalPort_ingress_handle[bin], + of_store.acl_ingress_handle4[bin] + cnt.acl_ingress_handle4[bin], + of_store.acl_ingress_handle6[bin] + cnt.acl_ingress_handle6[bin], + of_store.tun64_ipv4_handle[bin] + cnt.tun64_ipv4_handle[bin], + of_store.tun64_ipv6_handle[bin] + cnt.tun64_ipv6_handle[bin], + of_store.route_handle4[bin] + cnt.route_handle4[bin], + of_store.route_handle6[bin] + cnt.route_handle6[bin], + + of_store.decap_handle[bin] + cnt.decap_handle[bin], + of_store.nat64stateful_lan_handle[bin] + cnt.nat64stateful_lan_handle[bin], + of_store.nat64stateful_wan_handle[bin] + cnt.nat64stateful_wan_handle[bin], + of_store.nat64stateless_egress_handle[bin] + cnt.nat64stateless_egress_handle[bin], + of_store.nat64stateless_ingress_handle[bin] + cnt.nat64stateless_ingress_handle[bin], + of_store.balancer_handle[bin] + cnt.balancer_handle[bin], + of_store.balancer_icmp_reply_handle[bin] + cnt.balancer_icmp_reply_handle[bin], + + of_store.balancer_icmp_forward_handle[bin] + cnt.balancer_icmp_forward_handle[bin], + of_store.route_tunnel_handle4[bin] + cnt.route_tunnel_handle4[bin], + of_store.route_tunnel_handle6[bin] + cnt.route_tunnel_handle6[bin], + of_store.acl_egress_handle4[bin] + cnt.acl_egress_handle4[bin], + of_store.acl_egress_handle6[bin] + cnt.acl_egress_handle6[bin], + of_store.logicalPort_egress_handle[bin] + cnt.logicalPort_egress_handle[bin], + of_store.controlPlane_handle[bin] + cnt.controlPlane_handle[bin]); + } + + struct overflow_store + { + uint64_t logicalPort_ingress_handle[YANET_TSC_BINS_N]; + uint64_t acl_ingress_handle4[YANET_TSC_BINS_N]; + uint64_t acl_ingress_handle6[YANET_TSC_BINS_N]; + uint64_t tun64_ipv4_handle[YANET_TSC_BINS_N]; + uint64_t tun64_ipv6_handle[YANET_TSC_BINS_N]; + uint64_t route_handle4[YANET_TSC_BINS_N]; + uint64_t route_handle6[YANET_TSC_BINS_N]; + + uint64_t decap_handle[YANET_TSC_BINS_N]; + uint64_t nat64stateful_lan_handle[YANET_TSC_BINS_N]; + uint64_t nat64stateful_wan_handle[YANET_TSC_BINS_N]; + uint64_t nat64stateless_egress_handle[YANET_TSC_BINS_N]; + uint64_t nat64stateless_ingress_handle[YANET_TSC_BINS_N]; + uint64_t balancer_handle[YANET_TSC_BINS_N]; + uint64_t balancer_icmp_reply_handle[YANET_TSC_BINS_N]; + uint64_t balancer_icmp_forward_handle[YANET_TSC_BINS_N]; + + uint64_t route_tunnel_handle4[YANET_TSC_BINS_N]; + uint64_t route_tunnel_handle6[YANET_TSC_BINS_N]; + uint64_t acl_egress_handle4[YANET_TSC_BINS_N]; + uint64_t acl_egress_handle6[YANET_TSC_BINS_N]; + uint64_t logicalPort_egress_handle[YANET_TSC_BINS_N]; + uint64_t controlPlane_handle[YANET_TSC_BINS_N]; + + void handle_overflow(const tsc_deltas& cnt, const tsc_deltas& prev, int bin) + { + logicalPort_ingress_handle[bin] += (prev.logicalPort_ingress_handle[bin] > cnt.logicalPort_ingress_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + acl_ingress_handle4[bin] += (prev.acl_ingress_handle4[bin] > cnt.acl_ingress_handle4[bin]) << sizeof(uint16_t) * CHAR_BIT; + acl_ingress_handle6[bin] += (prev.acl_ingress_handle6[bin] > cnt.acl_ingress_handle6[bin]) << sizeof(uint16_t) * CHAR_BIT; + tun64_ipv4_handle[bin] += (prev.tun64_ipv4_handle[bin] > cnt.tun64_ipv4_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + tun64_ipv6_handle[bin] += (prev.tun64_ipv6_handle[bin] > cnt.tun64_ipv6_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + route_handle4[bin] += (prev.route_handle4[bin] > cnt.route_handle4[bin]) << sizeof(uint16_t) * CHAR_BIT; + route_handle6[bin] += (prev.route_handle6[bin] > cnt.route_handle6[bin]) << sizeof(uint16_t) * CHAR_BIT; + + decap_handle[bin] += (prev.decap_handle[bin] > cnt.decap_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + nat64stateful_lan_handle[bin] += (prev.nat64stateful_lan_handle[bin] > cnt.nat64stateful_lan_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + nat64stateful_wan_handle[bin] += (prev.nat64stateful_wan_handle[bin] > cnt.nat64stateful_wan_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + nat64stateless_egress_handle[bin] += (prev.nat64stateless_egress_handle[bin] > cnt.nat64stateless_egress_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + nat64stateless_ingress_handle[bin] += (prev.nat64stateless_ingress_handle[bin] > cnt.nat64stateless_ingress_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + balancer_handle[bin] += (prev.balancer_handle[bin] > cnt.balancer_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + balancer_icmp_reply_handle[bin] += (prev.balancer_icmp_reply_handle[bin] > cnt.balancer_icmp_reply_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + balancer_icmp_forward_handle[bin] += (prev.balancer_icmp_forward_handle[bin] > cnt.balancer_icmp_forward_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + + route_tunnel_handle4[bin] += (prev.route_tunnel_handle4[bin] > cnt.route_tunnel_handle4[bin]) << sizeof(uint16_t) * CHAR_BIT; + route_tunnel_handle6[bin] += (prev.route_tunnel_handle6[bin] > cnt.route_tunnel_handle6[bin]) << sizeof(uint16_t) * CHAR_BIT; + acl_egress_handle4[bin] += (prev.acl_egress_handle4[bin] > cnt.acl_egress_handle4[bin]) << sizeof(uint16_t) * CHAR_BIT; + acl_egress_handle6[bin] += (prev.acl_egress_handle6[bin] > cnt.acl_egress_handle6[bin]) << sizeof(uint16_t) * CHAR_BIT; + logicalPort_egress_handle[bin] += (prev.logicalPort_egress_handle[bin] > cnt.logicalPort_egress_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + controlPlane_handle[bin] += (prev.controlPlane_handle[bin] > cnt.controlPlane_handle[bin]) << sizeof(uint16_t) * CHAR_BIT; + } + }; + + std::vector> worker_counters; + table_t table; +}; + +void tsc_monitoring() +{ + tsc_monitoring_t monitoring{}; + monitoring.monitor(); +} + } } diff --git a/cli/helper.h b/cli/helper.h index b7d4a3ea..88b9b146 100644 --- a/cli/helper.h +++ b/cli/helper.h @@ -439,6 +439,13 @@ class table_t } } + void render() + { + printf("\033[2J\033[H"); + print_default(); + table.clear(); + } + protected: converter::config_t config; std::vector> table; diff --git a/cli/main.cpp b/cli/main.cpp index 88c11733..fb5e219e 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -109,6 +109,7 @@ std::vector ", [](const auto& args) { call(rib::clear, args); }}, + {"dontdoit podumoi tsc monitoring", "", [](const auto& args) { call(develop::dataplane::tsc_monitoring, args); }}, {}, {"telegraf unsafe", "", [](const auto& args) { call(telegraf::unsafe, args); }}, {"telegraf ports", "", [](const auto& args) { call(telegraf::ports_stats, args); }}, diff --git a/cli/show.h b/cli/show.h index 44ea6ce8..5810304a 100644 --- a/cli/show.h +++ b/cli/show.h @@ -6,9 +6,9 @@ #include "common/icontrolplane.h" #include "common/idataplane.h" +#include "common/tsc_deltas.h" #include "common/version.h" -#include "dataplane/tsc_deltas.h" #include "helper.h" namespace show @@ -879,28 +879,29 @@ void shm_tsc_set_state(bool state) dataplane.updateGlobalBase(globalbase); } -static const std::map counter_name_to_offset = { - {"logicalPort_ingress_handle", offsetof(dataplane::perf::tsc_base_values, logicalPort_ingress_handle)}, - {"acl_ingress_handle4", offsetof(dataplane::perf::tsc_base_values, acl_ingress_handle4)}, - {"acl_ingress_handle6", offsetof(dataplane::perf::tsc_base_values, acl_ingress_handle6)}, - {"tun64_ipv4_handle", offsetof(dataplane::perf::tsc_base_values, tun64_ipv4_handle)}, - {"tun64_ipv6_handle", offsetof(dataplane::perf::tsc_base_values, tun64_ipv6_handle)}, - {"route_handle4", offsetof(dataplane::perf::tsc_base_values, route_handle4)}, - {"route_handle6", offsetof(dataplane::perf::tsc_base_values, route_handle6)}, - {"decap_handle", offsetof(dataplane::perf::tsc_base_values, decap_handle)}, - {"nat64stateful_lan_handle", offsetof(dataplane::perf::tsc_base_values, nat64stateful_lan_handle)}, - {"nat64stateful_wan_handle", offsetof(dataplane::perf::tsc_base_values, nat64stateful_wan_handle)}, - {"nat64stateless_egress_handle", offsetof(dataplane::perf::tsc_base_values, nat64stateless_egress_handle)}, - {"nat64stateless_ingress_handle", offsetof(dataplane::perf::tsc_base_values, nat64stateless_ingress_handle)}, - {"balancer_handle", offsetof(dataplane::perf::tsc_base_values, balancer_handle)}, - {"balancer_icmp_reply_handle", offsetof(dataplane::perf::tsc_base_values, balancer_icmp_reply_handle)}, - {"balancer_icmp_forward_handle", offsetof(dataplane::perf::tsc_base_values, balancer_icmp_forward_handle)}, - {"route_tunnel_handle4", offsetof(dataplane::perf::tsc_base_values, route_tunnel_handle4)}, - {"route_tunnel_handle6", offsetof(dataplane::perf::tsc_base_values, route_tunnel_handle6)}, - {"acl_egress_handle4", offsetof(dataplane::perf::tsc_base_values, acl_egress_handle4)}, - {"acl_egress_handle6", offsetof(dataplane::perf::tsc_base_values, acl_egress_handle6)}, - {"logicalPort_egress_handle", offsetof(dataplane::perf::tsc_base_values, logicalPort_egress_handle)}, - {"controlPlane_handle", offsetof(dataplane::perf::tsc_base_values, controlPlane_handle)}, +using dataplane::perf::tsc_base_values; +static const std::map counter_name_to_offset = { + {"logicalPort_ingress_handle", offsetof(tsc_base_values, logicalPort_ingress_handle)}, + {"acl_ingress_handle4", offsetof(tsc_base_values, acl_ingress_handle4)}, + {"acl_ingress_handle6", offsetof(tsc_base_values, acl_ingress_handle6)}, + {"tun64_ipv4_handle", offsetof(tsc_base_values, tun64_ipv4_handle)}, + {"tun64_ipv6_handle", offsetof(tsc_base_values, tun64_ipv6_handle)}, + {"route_handle4", offsetof(tsc_base_values, route_handle4)}, + {"route_handle6", offsetof(tsc_base_values, route_handle6)}, + {"decap_handle", offsetof(tsc_base_values, decap_handle)}, + {"nat64stateful_lan_handle", offsetof(tsc_base_values, nat64stateful_lan_handle)}, + {"nat64stateful_wan_handle", offsetof(tsc_base_values, nat64stateful_wan_handle)}, + {"nat64stateless_egress_handle", offsetof(tsc_base_values, nat64stateless_egress_handle)}, + {"nat64stateless_ingress_handle", offsetof(tsc_base_values, nat64stateless_ingress_handle)}, + {"balancer_handle", offsetof(tsc_base_values, balancer_handle)}, + {"balancer_icmp_reply_handle", offsetof(tsc_base_values, balancer_icmp_reply_handle)}, + {"balancer_icmp_forward_handle", offsetof(tsc_base_values, balancer_icmp_forward_handle)}, + {"route_tunnel_handle4", offsetof(tsc_base_values, route_tunnel_handle4)}, + {"route_tunnel_handle6", offsetof(tsc_base_values, route_tunnel_handle6)}, + {"acl_egress_handle4", offsetof(tsc_base_values, acl_egress_handle4)}, + {"acl_egress_handle6", offsetof(tsc_base_values, acl_egress_handle6)}, + {"logicalPort_egress_handle", offsetof(tsc_base_values, logicalPort_egress_handle)}, + {"controlPlane_handle", offsetof(tsc_base_values, controlPlane_handle)}, }; void shm_tsc_set_base_value(std::string counter_name, uint32_t value) diff --git a/common/config.release.h b/common/config.release.h index c6615481..cad85cc2 100644 --- a/common/config.release.h +++ b/common/config.release.h @@ -73,3 +73,4 @@ #define YANET_CONFIG_SHARED_RINGS_NUMBER (32) #define YANET_DEFAULT_IPC_SHMKEY (12345) #define YANET_CONFIG_KERNEL_INTERFACE_QUEUE_SIZE (4096) +#define YANET_CONFIG_TSC_ACTIVE_STATE (0) diff --git a/common/tsc_deltas.h b/common/tsc_deltas.h new file mode 100644 index 00000000..b12910f5 --- /dev/null +++ b/common/tsc_deltas.h @@ -0,0 +1,110 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "common/define.h" + +#define YANET_TSC_BINS_SHIFT 2 +#define YANET_TSC_BINS_N 4 + +namespace dataplane +{ + +namespace perf +{ + +struct tsc_base_values +{ + uint32_t logicalPort_ingress_handle = 18; + uint32_t acl_ingress_handle4 = 0; + uint32_t acl_ingress_handle6 = 124; + uint32_t tun64_ipv4_handle = 0; + uint32_t tun64_ipv6_handle = 0; + uint32_t route_handle4 = 0; + uint32_t route_handle6 = 81; + uint32_t decap_handle = 0; + + uint32_t nat64stateful_lan_handle = 0; + uint32_t nat64stateful_wan_handle = 0; + uint32_t nat64stateless_egress_handle = 0; + uint32_t nat64stateless_ingress_handle = 0; + uint32_t balancer_handle = 259; + uint32_t balancer_icmp_reply_handle = 0; + uint32_t balancer_icmp_forward_handle = 0; + uint32_t route_tunnel_handle4 = 0; + + uint32_t route_tunnel_handle6 = 0; + uint32_t acl_egress_handle4 = 0; + uint32_t acl_egress_handle6 = 0; + uint32_t logicalPort_egress_handle = 0; + uint32_t controlPlane_handle = 0; +} __attribute__((__aligned__(2 * RTE_CACHE_LINE_SIZE))); + +struct tsc_deltas +{ + uint64_t iter_num; + uint16_t logicalPort_ingress_handle[YANET_TSC_BINS_N]; + uint16_t acl_ingress_handle4[YANET_TSC_BINS_N]; + uint16_t acl_ingress_handle6[YANET_TSC_BINS_N]; + uint16_t tun64_ipv4_handle[YANET_TSC_BINS_N]; + uint16_t tun64_ipv6_handle[YANET_TSC_BINS_N]; + uint16_t route_handle4[YANET_TSC_BINS_N]; + uint16_t route_handle6[YANET_TSC_BINS_N]; + + uint16_t decap_handle[YANET_TSC_BINS_N]; + uint16_t nat64stateful_lan_handle[YANET_TSC_BINS_N]; + uint16_t nat64stateful_wan_handle[YANET_TSC_BINS_N]; + uint16_t nat64stateless_egress_handle[YANET_TSC_BINS_N]; + uint16_t nat64stateless_ingress_handle[YANET_TSC_BINS_N]; + uint16_t balancer_handle[YANET_TSC_BINS_N]; + uint16_t balancer_icmp_reply_handle[YANET_TSC_BINS_N]; + uint16_t balancer_icmp_forward_handle[YANET_TSC_BINS_N]; + + uint16_t route_tunnel_handle4[YANET_TSC_BINS_N]; + uint16_t route_tunnel_handle6[YANET_TSC_BINS_N]; + uint16_t acl_egress_handle4[YANET_TSC_BINS_N]; + uint16_t acl_egress_handle6[YANET_TSC_BINS_N]; + uint16_t logicalPort_egress_handle[YANET_TSC_BINS_N]; + uint16_t controlPlane_handle[YANET_TSC_BINS_N]; + + YANET_ALWAYS_INLINE void write(uint64_t& tsc_start, uint32_t stack_size, uint16_t bins[YANET_TSC_BINS_N], uint32_t base) + { + if (!tsc_start || unlikely(stack_size == 0)) + { + return; + } + + auto tsc_end = rte_get_tsc_cycles(); + auto shifted_delta = (int64_t)((tsc_end - tsc_start) / stack_size) - base; + + if (shifted_delta > 0) + { + int floor_log_4 = (sizeof(uint64_t) * CHAR_BIT - _lzcnt_u64(shifted_delta) - 1) >> 1; + int bin_idx = std::min(std::max(floor_log_4 - YANET_TSC_BINS_SHIFT, 0), 4 - 1); + bins[bin_idx]++; + } + else + { + bins[0]++; + } + + tsc_start = tsc_end; + } + +} __attribute__((__aligned__(2 * RTE_CACHE_LINE_SIZE))); + +static_assert(sizeof(tsc_deltas) <= 8 * RTE_CACHE_LINE_SIZE, + "too many deltas"); + +static_assert(std::is_pod_v == true, + "tsc structure is not pod"); + +} + +} diff --git a/dataplane/dataplane.cpp b/dataplane/dataplane.cpp index 9897a743..14f7271c 100644 --- a/dataplane/dataplane.cpp +++ b/dataplane/dataplane.cpp @@ -30,10 +30,10 @@ #include "common.h" #include "common/idp.h" #include "common/result.h" +#include "common/tsc_deltas.h" #include "dataplane.h" #include "report.h" #include "sock_dev.h" -#include "tsc_deltas.h" #include "worker.h" common::log::LogPriority common::log::logPriority = common::log::TLOG_INFO; @@ -89,7 +89,8 @@ cDataPlane::cDataPlane() : {eConfigType::acl_values_size, YANET_CONFIG_ACL_VALUES_SIZE}, {eConfigType::master_mempool_size, 8192}, {eConfigType::nat64stateful_states_size, YANET_CONFIG_NAT64STATEFUL_HT_SIZE}, - {eConfigType::kernel_interface_queue_size, YANET_CONFIG_KERNEL_INTERFACE_QUEUE_SIZE}}; + {eConfigType::kernel_interface_queue_size, YANET_CONFIG_KERNEL_INTERFACE_QUEUE_SIZE}, + {eConfigType::tsc_active_state, YANET_CONFIG_TSC_ACTIVE_STATE}}; } cDataPlane::~cDataPlane() @@ -1272,6 +1273,7 @@ eResult cDataPlane::allocateSharedMemory() // deleting old shared memory if exists if (int shmid = shmget(key, 0, 0) != -1) { + YADECAP_LOG_INFO("IPC segment with key=%d marked for deletion.", key); shmctl(shmid, IPC_RMID, NULL); } @@ -1778,6 +1780,11 @@ eResult cDataPlane::parseConfigValues(const nlohmann::json& json) configValues[eConfigType::kernel_interface_queue_size] = json["kernel_interface_queue_size"]; } + if (exist(json, "tsc_active_state")) + { + configValues[eConfigType::tsc_active_state] = json["tsc_active_state"]; + } + return eResult::success; } diff --git a/dataplane/dataplane.h b/dataplane/dataplane.h index 06129e3b..e52fca5e 100644 --- a/dataplane/dataplane.h +++ b/dataplane/dataplane.h @@ -57,6 +57,7 @@ enum class eConfigType master_mempool_size, nat64stateful_states_size, kernel_interface_queue_size, + tsc_active_state, }; struct tDataPlaneConfig diff --git a/dataplane/globalbase.cpp b/dataplane/globalbase.cpp index fee4956c..1cbb5e03 100644 --- a/dataplane/globalbase.cpp +++ b/dataplane/globalbase.cpp @@ -28,6 +28,8 @@ atomic::atomic(cDataPlane* dataPlane, memset(physicalPort_flags, 0, sizeof(physicalPort_flags)); memset(counter_shifts, 0, sizeof(counter_shifts)); memset(gc_counter_shifts, 0, sizeof(gc_counter_shifts)); + + tsc_active_state = dataPlane->getConfigValue(eConfigType::tsc_active_state); } atomic::~atomic() diff --git a/dataplane/globalbase.h b/dataplane/globalbase.h index d6fc543b..cf328e1f 100644 --- a/dataplane/globalbase.h +++ b/dataplane/globalbase.h @@ -10,13 +10,13 @@ #include "common/counters.h" #include "common/idp.h" #include "common/result.h" +#include "common/tsc_deltas.h" #include "common.h" #include "dynamic_table.h" #include "flat.h" #include "hashtable.h" #include "lpm.h" -#include "tsc_deltas.h" #include "type.h" /// @todo: move @@ -53,9 +53,9 @@ struct transport_layer_t struct { /** @todo: - flat type; - flat code; - */ + flat type; + flat code; + */ flat type_code; flat identifier; } icmp; @@ -122,6 +122,7 @@ class atomic YANET_CONFIG_BALANCER_STATE_HT_SIZE, 16> balancer_state; + bool tsc_active_state; }; // diff --git a/dataplane/tsc_deltas.h b/dataplane/tsc_deltas.h deleted file mode 100644 index 5362bcd3..00000000 --- a/dataplane/tsc_deltas.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#define YANET_TSC_BINS_SHIFT 4 - -namespace dataplane -{ - -namespace perf -{ - -struct tsc_base_values -{ - uint32_t logicalPort_ingress_handle = 18; - uint32_t acl_ingress_handle4 = 0; - uint32_t acl_ingress_handle6 = 124; - uint32_t tun64_ipv4_handle = 0; - uint32_t tun64_ipv6_handle = 0; - uint32_t route_handle4 = 0; - uint32_t route_handle6 = 81; - uint32_t decap_handle = 0; - - uint32_t nat64stateful_lan_handle = 0; - uint32_t nat64stateful_wan_handle = 0; - uint32_t nat64stateless_egress_handle = 0; - uint32_t nat64stateless_ingress_handle = 0; - uint32_t balancer_handle = 259; - uint32_t balancer_icmp_reply_handle = 0; - uint32_t balancer_icmp_forward_handle = 0; - uint32_t route_tunnel_handle4 = 0; - - uint32_t route_tunnel_handle6 = 0; - uint32_t acl_egress_handle4 = 0; - uint32_t acl_egress_handle6 = 0; - uint32_t logicalPort_egress_handle = 0; - uint32_t controlPlane_handle = 0; -} __attribute__((__aligned__(2 * RTE_CACHE_LINE_SIZE))); - -struct tsc_deltas -{ - uint64_t iter_num; - uint16_t logicalPort_ingress_handle[4]; - uint16_t acl_ingress_handle4[4]; - uint16_t acl_ingress_handle6[4]; - uint16_t tun64_ipv4_handle[4]; - uint16_t tun64_ipv6_handle[4]; - uint16_t route_handle4[4]; - uint16_t route_handle6[4]; - - uint16_t decap_handle[4]; - uint16_t nat64stateful_lan_handle[4]; - uint16_t nat64stateful_wan_handle[4]; - uint16_t nat64stateless_egress_handle[4]; - uint16_t nat64stateless_ingress_handle[4]; - uint16_t balancer_handle[4]; - uint16_t balancer_icmp_reply_handle[4]; - uint16_t balancer_icmp_forward_handle[4]; - - uint16_t route_tunnel_handle4[4]; - uint16_t route_tunnel_handle6[4]; - uint16_t acl_egress_handle4[4]; - uint16_t acl_egress_handle6[4]; - uint16_t logicalPort_egress_handle[4]; - uint16_t controlPlane_handle[4]; - uint64_t tsc_start; - - inline void write(uint32_t stack_size, uint16_t bins[4], uint32_t base) - { - if (!tsc_start || unlikely(stack_size == 0)) - { - return; - } - - auto tsc_end = rte_get_tsc_cycles(); - auto shifted_delta = (int64_t)((tsc_end - tsc_start) / stack_size) - base; - - if (shifted_delta > 0) - { - int floor_log_2 = sizeof(uint64_t) * CHAR_BIT - _lzcnt_u64(shifted_delta) - 1; - int bin_idx = std::min(std::max(floor_log_2 - YANET_TSC_BINS_SHIFT, 0), 4 - 1); - bins[bin_idx]++; - } - - tsc_start = tsc_end; - } - -} __attribute__((__aligned__(2 * RTE_CACHE_LINE_SIZE))); - -static_assert(sizeof(tsc_deltas) <= 4 * RTE_CACHE_LINE_SIZE, - "too much deltas"); - -static_assert(std::is_pod_v == true, "tsc structure is not pod"); - -} - -} diff --git a/dataplane/worker.cpp b/dataplane/worker.cpp index d08ef30d..1aa1239b 100644 --- a/dataplane/worker.cpp +++ b/dataplane/worker.cpp @@ -510,22 +510,25 @@ inline void cWorker::handlePackets() const auto& base = bases[localBaseId & 1]; const auto& globalbase = *base.globalBase; - const auto& base_values = globalbase.tsc_base_values; - if (globalbase.tscs_active) + auto& base_values = globalbase.tsc_base_values; + auto tsc_start = globalbase.tscs_active || basePermanently.globalBaseAtomic->tsc_active_state ? rte_get_tsc_cycles() : 0; + + if (tsc_start) { - tsc_deltas->tsc_start = rte_get_tsc_cycles(); + tsc_deltas->iter_num++; } - auto stack_size = acl_ingress_stack4.mbufsCount; + + auto stack_size = logicalPort_ingress_stack.mbufsCount; logicalPort_ingress_handle(); - tsc_deltas->write(stack_size, tsc_deltas->logicalPort_ingress_handle, base_values.logicalPort_ingress_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->logicalPort_ingress_handle, base_values.logicalPort_ingress_handle); stack_size = acl_ingress_stack4.mbufsCount; acl_ingress_handle4(); - tsc_deltas->write(stack_size, tsc_deltas->acl_ingress_handle4, base_values.acl_ingress_handle4); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->acl_ingress_handle4, base_values.acl_ingress_handle4); stack_size = acl_ingress_stack6.mbufsCount; acl_ingress_handle6(); - tsc_deltas->write(stack_size, tsc_deltas->acl_ingress_handle6, base_values.acl_ingress_handle6); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->acl_ingress_handle6, base_values.acl_ingress_handle6); if (globalbase.early_decap_enabled) { @@ -536,7 +539,7 @@ inline void cWorker::handlePackets() stack_size = acl_ingress_stack4.mbufsCount; acl_ingress_handle4(); - tsc_deltas->write(stack_size, tsc_deltas->acl_ingress_handle4, base_values.acl_ingress_handle4); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->acl_ingress_handle4, base_values.acl_ingress_handle4); } if (after_early_decap_stack6.mbufsCount > 0) @@ -546,7 +549,7 @@ inline void cWorker::handlePackets() stack_size = acl_ingress_stack6.mbufsCount; acl_ingress_handle6(); - tsc_deltas->write(stack_size, tsc_deltas->acl_ingress_handle6, base_values.acl_ingress_handle6); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->acl_ingress_handle6, base_values.acl_ingress_handle6); } } @@ -554,91 +557,91 @@ inline void cWorker::handlePackets() { stack_size = tun64_stack4.mbufsCount; tun64_ipv4_handle(); - tsc_deltas->write(stack_size, tsc_deltas->tun64_ipv4_handle, base_values.tun64_ipv4_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->tun64_ipv4_handle, base_values.tun64_ipv4_handle); stack_size = tun64_stack6.mbufsCount; tun64_ipv6_handle(); - tsc_deltas->write(stack_size, tsc_deltas->tun64_ipv6_handle, base_values.tun64_ipv6_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->tun64_ipv6_handle, base_values.tun64_ipv6_handle); } if (globalbase.decap_enabled) { stack_size = decap_stack.mbufsCount; decap_handle(); - tsc_deltas->write(stack_size, tsc_deltas->decap_handle, base_values.decap_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->decap_handle, base_values.decap_handle); } if (globalbase.nat64stateful_enabled) { stack_size = nat64stateful_lan_stack.mbufsCount; nat64stateful_lan_handle(); - tsc_deltas->write(stack_size, tsc_deltas->nat64stateful_lan_handle, base_values.nat64stateful_lan_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->nat64stateful_lan_handle, base_values.nat64stateful_lan_handle); stack_size = nat64stateful_wan_stack.mbufsCount; nat64stateful_wan_handle(); - tsc_deltas->write(stack_size, tsc_deltas->nat64stateful_wan_handle, base_values.nat64stateful_wan_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->nat64stateful_wan_handle, base_values.nat64stateful_wan_handle); } if (globalbase.nat64stateless_enabled) { stack_size = nat64stateless_ingress_stack.mbufsCount; nat64stateless_ingress_handle(); - tsc_deltas->write(stack_size, tsc_deltas->nat64stateless_ingress_handle, base_values.nat64stateless_ingress_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->nat64stateless_ingress_handle, base_values.nat64stateless_ingress_handle); stack_size = nat64stateless_egress_stack.mbufsCount; nat64stateless_egress_handle(); - tsc_deltas->write(stack_size, tsc_deltas->nat64stateless_egress_handle, base_values.nat64stateless_egress_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->nat64stateless_egress_handle, base_values.nat64stateless_egress_handle); } if (globalbase.balancer_enabled) { stack_size = balancer_stack.mbufsCount; balancer_handle(); - tsc_deltas->write(stack_size, tsc_deltas->balancer_handle, base_values.balancer_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->balancer_handle, base_values.balancer_handle); stack_size = balancer_icmp_reply_stack.mbufsCount; balancer_icmp_reply_handle(); // balancer replies instead of real (when client pings VS) - tsc_deltas->write(stack_size, tsc_deltas->balancer_icmp_reply_handle, base_values.balancer_icmp_reply_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->balancer_icmp_reply_handle, base_values.balancer_icmp_reply_handle); stack_size = balancer_icmp_forward_stack.mbufsCount; balancer_icmp_forward_handle(); // forward icmp message to other balancers (if not sent to one of this balancer's reals) - tsc_deltas->write(stack_size, tsc_deltas->balancer_icmp_forward_handle, base_values.balancer_icmp_forward_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->balancer_icmp_forward_handle, base_values.balancer_icmp_forward_handle); } stack_size = route_stack4.mbufsCount; route_handle4(); - tsc_deltas->write(stack_size, tsc_deltas->route_handle4, base_values.route_handle4); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->route_handle4, base_values.route_handle4); stack_size = route_stack6.mbufsCount; route_handle6(); - tsc_deltas->write(stack_size, tsc_deltas->route_handle6, base_values.route_handle6); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->route_handle6, base_values.route_handle6); stack_size = route_tunnel_stack4.mbufsCount; route_tunnel_handle4(); - tsc_deltas->write(stack_size, tsc_deltas->route_tunnel_handle4, base_values.route_tunnel_handle4); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->route_tunnel_handle4, base_values.route_tunnel_handle4); stack_size = route_tunnel_stack6.mbufsCount; route_tunnel_handle6(); - tsc_deltas->write(stack_size, tsc_deltas->route_tunnel_handle6, base_values.route_tunnel_handle6); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->route_tunnel_handle6, base_values.route_tunnel_handle6); if (globalbase.acl_egress_enabled) { stack_size = acl_egress_stack4.mbufsCount; acl_egress_handle4(); - tsc_deltas->write(stack_size, tsc_deltas->acl_egress_handle4, base_values.acl_egress_handle4); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->acl_egress_handle4, base_values.acl_egress_handle4); stack_size = acl_egress_stack6.mbufsCount; acl_egress_handle6(); - tsc_deltas->write(stack_size, tsc_deltas->acl_egress_handle6, base_values.acl_egress_handle6); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->acl_egress_handle6, base_values.acl_egress_handle6); } stack_size = logicalPort_egress_stack.mbufsCount; logicalPort_egress_handle(); - tsc_deltas->write(stack_size, tsc_deltas->logicalPort_egress_handle, base_values.logicalPort_egress_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->logicalPort_egress_handle, base_values.logicalPort_egress_handle); stack_size = controlPlane_stack.mbufsCount; controlPlane_handle(); - tsc_deltas->write(stack_size, tsc_deltas->controlPlane_handle, base_values.controlPlane_handle); + tsc_deltas->write(tsc_start, stack_size, tsc_deltas->controlPlane_handle, base_values.controlPlane_handle); physicalPort_egress_handle(); } diff --git a/dataplane/worker.h b/dataplane/worker.h index 3f1477e6..5a9c78be 100644 --- a/dataplane/worker.h +++ b/dataplane/worker.h @@ -9,6 +9,7 @@ #include #include "common/result.h" +#include "common/tsc_deltas.h" #include "common/type.h" #include "base.h" @@ -16,7 +17,6 @@ #include "globalbase.h" #include "samples.h" #include "sharedmemory.h" -#include "tsc_deltas.h" class cDataPlane; class mControlPlane;