From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id CB91CA034E; Fri, 21 Jan 2022 11:32:46 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B859F4278B; Fri, 21 Jan 2022 11:31:47 +0100 (CET) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mails.dpdk.org (Postfix) with ESMTP id 7514C4276D for ; Fri, 21 Jan 2022 11:31:45 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1642761105; x=1674297105; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hbr2QB5kWiIwic2mWUsqcJy2y20Exh2SVWo0bnRLpa4=; b=THRX3bNt9iAEfx7g35dqGt/fCAlmwU8oT8XamLXgyW9MVqAvXW6iLaye CpYRDkIxCRPLy7k0B9erHgpgRNhD0c3Z+Z12FubmbDviDezcvoQixjOp/ 7nHTCHlOC+Up9atFKFOaA3Jp+ppdDb/UM3XAdEaQfEK8YvRS579eqMWLt YtTUEe/CxYwu74q0MfcHzCoeUvRVzggsRTp6NxqwjCNcdGPNDeLB5edZw 1Otzc52idttxmv1p1CHE65NIBFEt6M1/YKMTIDzyNBbl4zXXOQloDYNw9 hVXv902UJuqMMWNFovWkECw1idhC/5oX7gaWlAizEpQDw0B+RMcgnh+Zv Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10233"; a="270045140" X-IronPort-AV: E=Sophos;i="5.88,304,1635231600"; d="scan'208";a="270045140" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 21 Jan 2022 02:31:44 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,304,1635231600"; d="scan'208";a="533222785" Received: from silpixa00401120.ir.intel.com ([10.55.128.255]) by orsmga008.jf.intel.com with ESMTP; 21 Jan 2022 02:31:43 -0800 From: Ronan Randles To: dev@dpdk.org Cc: Ronan Randles Subject: [PATCH v2 12/15] examples/generator: line rate limiting Date: Fri, 21 Jan 2022 10:31:19 +0000 Message-Id: <20220121103122.2926856-13-ronan.randles@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220121103122.2926856-1-ronan.randles@intel.com> References: <20211214141242.3383831-1-ronan.randles@intel.com> <20220121103122.2926856-1-ronan.randles@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org This commit introduces line rate limiting using a token passing method. The target traffic rate default is currently hard coded, this can be set using telemetry. Signed-off-by: Ronan Randles --- examples/generator/main.c | 79 +++++++++++++++++++++++++-------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/examples/generator/main.c b/examples/generator/main.c index 0834a094a4..16292f06db 100644 --- a/examples/generator/main.c +++ b/examples/generator/main.c @@ -40,6 +40,7 @@ struct rte_gen *gen; struct gen_args { /* Inputs */ struct rte_gen *gen; + uint64_t target_tx_pps; /* Outputs */ uint64_t tx_total_packets; @@ -195,7 +196,6 @@ gen_wait_for_links_up(void) rte_delay_us_block(100); } } - /* The lcore main. This is the main thread that does the work, reading from * an input port and writing to an output port. */ @@ -217,43 +217,63 @@ lcore_producer(void *arg) "not be optimal.\n", port); uint64_t tsc_hz = rte_get_tsc_hz(); + float tsc_hz_f = (float)tsc_hz; uint64_t last_tsc_reading = 0; uint64_t last_tx_total = 0; uint16_t nb_tx = 0; + float tokens = 0; /* Wait for links to come up before generating packets */ gen_wait_for_links_up(); if (!done) printf("Generating packets...\n"); + uint64_t token_last_add_tsc = rte_rdtsc(); + /* Run until the application is quit or killed. */ while (!done) { - struct rte_mbuf *bufs[BURST_SIZE]; - /* Receive packets from gen and then tx them over port */ - - RTE_ETH_FOREACH_DEV(port) { - int nb_generated = rte_gen_rx_burst(gen, bufs, - BURST_SIZE); - - uint64_t start_tsc = rte_rdtsc(); - if (start_tsc > last_tsc_reading + tsc_hz) { - args->measured_tx_pps = args->tx_total_packets - - last_tx_total; - last_tx_total = args->tx_total_packets; - last_tsc_reading = start_tsc; + /* Track time since last token add and calculate number + * of tokens to give per second to implement line rate limiting + */ + uint64_t now = rte_rdtsc(); + uint64_t tsc_delta = now - token_last_add_tsc; + float token_scalar = (float)tsc_delta / tsc_hz_f; + float add_tokens = args->target_tx_pps * token_scalar; + /* If there are tokens to be added and we haven't exceeded + * the target rate then we add tokens + */ + if (add_tokens > 1.f) { + if (tokens < args->target_tx_pps) { + tokens += add_tokens; + token_last_add_tsc = now; } - nb_tx = rte_eth_tx_burst(port, 0, bufs, nb_generated); - args->tx_total_packets += nb_tx; - - uint64_t tx_failed = nb_generated - nb_tx; - if (nb_tx != nb_generated) { - rte_pktmbuf_free_bulk(&bufs[nb_tx], tx_failed); - args->tx_failed += tx_failed; + } + /* Receive packets from gen and then tx them over port */ + if (tokens >= BURST_SIZE) { + RTE_ETH_FOREACH_DEV(port) { + int nb_generated = rte_gen_rx_burst(gen, bufs, + BURST_SIZE); + + uint64_t start_tsc = rte_rdtsc(); + if (start_tsc > last_tsc_reading + tsc_hz) { + args->measured_tx_pps = + args->tx_total_packets - last_tx_total; + last_tx_total = args->tx_total_packets; + last_tsc_reading = start_tsc; + } + nb_tx = rte_eth_tx_burst(port, 0, bufs, + nb_generated); + args->tx_total_packets += nb_tx; + tokens -= nb_tx; + + uint64_t tx_failed = nb_generated - nb_tx; + if (nb_tx != nb_generated) { + rte_pktmbuf_free_bulk(&bufs[nb_tx], + tx_failed); + args->tx_failed += tx_failed; + } } - if (unlikely(nb_tx == 0)) - continue; - } } return 0; @@ -296,7 +316,6 @@ lcore_consumer(void *arg) BURST_SIZE); if (unlikely(nb_rx == 0)) continue; - args->rx_total_packets += nb_rx; int nb_sent = rte_gen_tx_burst(gen, bufs, @@ -320,12 +339,14 @@ static int tele_gen_mpps(const char *cmd, const char *params, struct rte_tel_data *d) { RTE_SET_USED(cmd); - RTE_SET_USED(params); struct gen_args *args = telemetry_userdata.prod; + if (params) { + args->target_tx_pps = atoi(params) * 1000000; + printf("Packet rate set: %li\n", args->target_tx_pps); + } rte_tel_data_start_dict(d); - rte_tel_data_add_dict_int(d, "pps", - (args->measured_tx_pps)); + rte_tel_data_add_dict_int(d, "pps", args->target_tx_pps); return 0; } @@ -412,6 +433,8 @@ main(int argc, char *argv[]) if (lcore_count == 0) { telemetry_userdata.prod = &core_launch_args[lcore_count]; + /* Default traffic rate */ + telemetry_userdata.prod->target_tx_pps = 20000000; rte_eal_remote_launch(lcore_producer, telemetry_userdata.prod, lcore_id); -- 2.25.1