From patchwork Mon Dec 11 16:00:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Github ODP bot X-Patchwork-Id: 121431 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp2983529qgn; Mon, 11 Dec 2017 08:11:01 -0800 (PST) X-Google-Smtp-Source: ACJfBounFZXndIfS7mhcwbomtHXSjWqrgT8I8t5KQtSfiwIGAC25MzEZZJHC55BOQSZ9/PU3rMRU X-Received: by 10.200.27.200 with SMTP id m8mr1253502qtk.102.1513008660890; Mon, 11 Dec 2017 08:11:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513008660; cv=none; d=google.com; s=arc-20160816; b=wk1DuuWQJKNEUJGsiAocJGUC4SF2JeXHWRoIlHuxzNJvcB2gA0vMeSHv+1w7iBl5n3 jswFA9VfnkN617ofgsuO3ld72mIXiH6zluaXHBiAFnHRTbYB6hKq7SCxLDIpp+fe0MoN MFS/43k16McBZQVMUEElhEwNNe/LXYWfsDTQr8oXQuetma66uHZ1Xsr18bMpcjTXd99O PzUIB8H89cmwre39cVoKutBAcf4qCdPJl9Xl32cQPRXMNh/m4EDAxZxWTZMH6rxrxSLa fKvbIbcQCoyVdg/Ta0QqY4MfBzXhC/xfYfHprmrB33t7yldHO8wgWnM1DhbzeDrsQUR/ /vVQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:github-pr-num :references:in-reply-to:message-id:date:to:from:delivered-to :arc-authentication-results; bh=ljBvkVi0q9MNfnxg+Ql4e+bP0vqtYk91GFlqGLo47QQ=; b=g4qINZ/femZtCnUEUH3k42A3OLrrqH+ZDiSK/OO5jvs/TMJZrTrdyIDiMIrNBvdIrw L3hDAgvjNqrWwmlJ1LDO8Ym6HeZUECxTyyC36VqsyoeSLFWaw2LVRxdHOActOqbvSXDw YTak5RDgeB2Wh1sVDYfI1Pcvlb5ayjiRxT1fSx7HhY33s6VUzf6QJCwS6XtAsQJUzcIy vLvqrTXNW6Xbg/N/JM8IbEnf6jZwz52SvZd1mRoa87IFmXlv/4H0u6bj0NoInj+PNEy2 3lI/gZn5S08m0B7Y7VQcTYJ2r/p97wXu8JPBMBQyRj3j3vZznQu8dj4FmwmE1MySXNBg 3Qdw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.197.127.237 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Return-Path: Received: from lists.linaro.org (ec2-54-197-127-237.compute-1.amazonaws.com. [54.197.127.237]) by mx.google.com with ESMTP id n39si5860528qtc.319.2017.12.11.08.11.00; Mon, 11 Dec 2017 08:11:00 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.197.127.237 as permitted sender) client-ip=54.197.127.237; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.197.127.237 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=yandex.ru Received: by lists.linaro.org (Postfix, from userid 109) id 93E286097D; Mon, 11 Dec 2017 16:11:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 341186092C; Mon, 11 Dec 2017 16:01:40 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 4AFC36096B; Mon, 11 Dec 2017 16:00:47 +0000 (UTC) Received: from forward106j.mail.yandex.net (forward106j.mail.yandex.net [5.45.198.249]) by lists.linaro.org (Postfix) with ESMTPS id 3127560958 for ; Mon, 11 Dec 2017 16:00:23 +0000 (UTC) Received: from mxback20j.mail.yandex.net (mxback20j.mail.yandex.net [IPv6:2a02:6b8:0:1619::114]) by forward106j.mail.yandex.net (Yandex) with ESMTP id 3E76E1801D5C for ; Mon, 11 Dec 2017 19:00:21 +0300 (MSK) Received: from smtp1p.mail.yandex.net (smtp1p.mail.yandex.net [2a02:6b8:0:1472:2741:0:8b6:6]) by mxback20j.mail.yandex.net (nwsmtp/Yandex) with ESMTP id iKv5TF6EEN-0Lqq71EC; Mon, 11 Dec 2017 19:00:21 +0300 Received: by smtp1p.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id BifhbGdIDb-0KT8IA7M; Mon, 11 Dec 2017 19:00:20 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) From: Github ODP bot To: lng-odp@lists.linaro.org Date: Mon, 11 Dec 2017 19:00:12 +0300 Message-Id: <1513008012-9231-15-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513008012-9231-1-git-send-email-odpbot@yandex.ru> References: <1513008012-9231-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 335 Subject: [lng-odp] [PATCH API-NEXT v1 14/14] example: generator: replace atomic counter with per worker counters X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" From: Bogdan Pricope Use of atomic counters reduces total packet throughput. Signed-off-by: Bogdan Pricope Reviewed-by: Ilias Apalodimas Signed-off-by: Maxim Uvarov --- /** Email created from pull request 335 (muvarov:devel/api-next_master_merge) ** https://github.com/Linaro/odp/pull/335 ** Patch: https://github.com/Linaro/odp/pull/335.patch ** Base sha: 630d8422564ebf4991b468cb38a29e9483fc2ec2 ** Merge commit sha: 2de2af9eca01b713e51c66fee7a5c7e535502f85 **/ example/generator/odp_generator.c | 266 +++++++++++++++++++++++--------------- 1 file changed, 165 insertions(+), 101 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index 0a81cdeb3..861e98369 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -34,6 +34,9 @@ #define APPL_MODE_PING 1 /**< ping mode */ #define APPL_MODE_RCV 2 /**< receive mode */ +#define PING_THR_TX 0 +#define PING_THR_RX 1 + /** print appl mode */ #define PRINT_APPL_MODE(x) printf("%s(%i)\n", #x, (x)) @@ -82,18 +85,21 @@ typedef struct { /** * counters */ -static struct { - odp_atomic_u64_t seq; /**< ip seq to be send */ - odp_atomic_u64_t ip; /**< ip packets */ - odp_atomic_u64_t udp; /**< udp packets */ - odp_atomic_u64_t icmp; /**< icmp packets */ - odp_atomic_u64_t cnt; /**< sent packets*/ - odp_atomic_u64_t tx_drops; /**< packets dropped in transmit */ -} counters; +typedef struct { + uint64_t ctr_pkt_snd; /**< sent packets*/ + uint64_t ctr_pkt_snd_drop; /**< packets dropped in transmit */ + + uint64_t ctr_pkt_rcv; /**< recv packets */ + uint64_t ctr_seq; /**< ip seq to be send */ + uint64_t ctr_udp_rcv; /**< udp packets */ + uint64_t ctr_icmp_reply_rcv; /**< icmp reply packets */ +} counters_t; /** * Thread specific arguments */ typedef struct { + counters_t counters; /**< Packet conters */ + odp_bool_t stop; /**< Stop packet processing */ union { struct { odp_pktout_queue_t pktout; /**< Packet output queue */ @@ -120,6 +126,9 @@ typedef struct { appl_args_t appl; /** Thread specific arguments */ thread_args_t thread[MAX_WORKERS]; + /** Global arguments */ + int thread_cnt; + int tx_burst_size; } args_t; /** Global pointer to args */ @@ -131,7 +140,8 @@ static odp_barrier_t barrier; /** Packet processing function types */ typedef odp_packet_t (*setup_pkt_ref_fn_t)(odp_pool_t, odp_pktout_config_opt_t *); -typedef int (*setup_pkt_fn_t)(odp_packet_t, odp_pktout_config_opt_t *); +typedef int (*setup_pkt_fn_t)(odp_packet_t, odp_pktout_config_opt_t *, + counters_t *); /* helper funcs */ static void parse_args(int argc, char *argv[], appl_args_t *appl_args); @@ -245,6 +255,7 @@ static int setup_pkt_ref_array(odp_pool_t pool, * @return 0 success, -1 failed */ static int setup_pkt_array(odp_pktout_config_opt_t *pktout_cfg, + counters_t *counters, odp_packet_t *pkt_ref_array, odp_packet_t *pkt_array, int pkt_array_size, @@ -253,7 +264,7 @@ static int setup_pkt_array(odp_pktout_config_opt_t *pktout_cfg, int i; for (i = 0; i < pkt_array_size; i++) { - if ((*setup_pkt)(pkt_ref_array[i], pktout_cfg)) + if ((*setup_pkt)(pkt_ref_array[i], pktout_cfg, counters)) break; pkt_array[i] = odp_packet_ref_static(pkt_ref_array[i]); @@ -342,7 +353,8 @@ static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool, * @return Success/Failed * @retval 0 on success, -1 on fail */ -static int setup_udp_pkt(odp_packet_t pkt, odp_pktout_config_opt_t *pktout_cfg) +static int setup_udp_pkt(odp_packet_t pkt, odp_pktout_config_opt_t *pktout_cfg, + counters_t *counters) { char *buf; odph_ipv4hdr_t *ip; @@ -352,7 +364,8 @@ static int setup_udp_pkt(odp_packet_t pkt, odp_pktout_config_opt_t *pktout_cfg) /*Update IP ID and checksum*/ ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); - seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xFFFF; + seq = counters->ctr_seq % 0xFFFF; + counters->ctr_seq++; ip->id = odp_cpu_to_be_16(seq); if (!pktout_cfg->bit.ipv4_chksum) { ip->chksum = 0; @@ -437,7 +450,8 @@ static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool, * @retval 0 on success, -1 on fail */ static int setup_icmp_pkt(odp_packet_t pkt, - odp_pktout_config_opt_t *pktout_cfg) + odp_pktout_config_opt_t *pktout_cfg, + counters_t *counters) { char *buf; odph_ipv4hdr_t *ip; @@ -450,7 +464,8 @@ static int setup_icmp_pkt(odp_packet_t pkt, /* ip */ ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); - seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xffff; + seq = counters->ctr_seq % 0xffff; + counters->ctr_seq++; ip->id = odp_cpu_to_be_16(seq); if (!pktout_cfg->bit.ipv4_chksum) { ip->chksum = 0; @@ -607,30 +622,39 @@ static int gen_send_thread(void *arg) odp_pktout_config_opt_t *pktout_cfg; odp_packet_t pkt_ref_array[MAX_UDP_TX_BURST]; odp_packet_t pkt_array[MAX_UDP_TX_BURST]; - int pkt_array_size; + int pkt_array_size, seq_step; int burst_start, burst_size; setup_pkt_ref_fn_t setup_pkt_ref = NULL; setup_pkt_fn_t setup_pkt = NULL; + counters_t *counters; + uint64_t pkt_count_max = 0; thr = odp_thread_id(); thr_args = arg; pktout = thr_args->tx.pktout; pktout_cfg = thr_args->tx.pktout_cfg; + counters = &thr_args->counters; /* Create reference packets*/ if (args->appl.mode == APPL_MODE_UDP) { - pkt_array_size = args->appl.udp_tx_burst; setup_pkt_ref = setup_udp_pkt_ref; setup_pkt = setup_udp_pkt; + seq_step = args->tx_burst_size * (args->thread_cnt - 1); + if (args->appl.number != -1) + pkt_count_max = args->appl.number / args->thread_cnt + + (args->appl.number % args->thread_cnt ? 1 : 0); } else if (args->appl.mode == APPL_MODE_PING) { - pkt_array_size = 1; setup_pkt_ref = setup_icmp_pkt_ref; setup_pkt = setup_icmp_pkt; + seq_step = 0; + if (args->appl.number != -1) + pkt_count_max = args->appl.number; } else { EXAMPLE_ERR(" [%02i] Error: invalid processing mode %d\n", thr, args->appl.mode); return -1; } + pkt_array_size = args->tx_burst_size; if (setup_pkt_ref_array(thr_args->pool, pktout_cfg, pkt_ref_array, pkt_array_size, @@ -645,13 +669,17 @@ static int gen_send_thread(void *arg) odp_barrier_wait(&barrier); for (;;) { - if (args->appl.number != -1 && - odp_atomic_fetch_add_u64(&counters.cnt, pkt_array_size) >= - (unsigned int)args->appl.number) + if (thr_args->stop) break; + if (pkt_count_max && counters->ctr_pkt_snd > pkt_count_max) { + sleep(1); /* wait for stop command */ + continue; + } + /* Setup TX burst*/ - if (setup_pkt_array(pktout_cfg, pkt_ref_array, pkt_array, + if (setup_pkt_array(pktout_cfg, counters, + pkt_ref_array, pkt_array, pkt_array_size, setup_pkt)) { EXAMPLE_ERR("[%02i] Error: failed to setup packets\n", thr); @@ -663,10 +691,12 @@ static int gen_send_thread(void *arg) ret = odp_pktout_send(pktout, &pkt_array[burst_start], burst_size); if (ret == burst_size) { + burst_size = 0; break; } else if (ret >= 0 && ret < burst_size) { - odp_atomic_add_u64(&counters.tx_drops, - burst_size - ret); + thr_args->counters.ctr_pkt_snd_drop += + burst_size - ret; + burst_start += ret; burst_size -= ret; continue; @@ -677,32 +707,20 @@ static int gen_send_thread(void *arg) break; } + counters->ctr_pkt_snd += pkt_array_size - burst_size; + if (args->appl.interval != 0) { printf(" [%02i] send pkt no:%ju seq %ju\n", thr, - odp_atomic_load_u64(&counters.seq), - odp_atomic_load_u64(&counters.seq)%0xffff); + counters->ctr_seq, + counters->ctr_seq % 0xffff); millisleep(args->appl.interval, thr_args->tp, thr_args->tim, thr_args->tq, thr_args->tmo_ev); } - } - - /* receive number of reply pks until timeout */ - if (args->appl.mode == APPL_MODE_PING && args->appl.number > 0) { - while (args->appl.timeout >= 0) { - if (odp_atomic_load_u64(&counters.icmp) >= - (unsigned int)args->appl.number) - break; - millisleep(DEFAULT_PKT_INTERVAL, - thr_args->tp, - thr_args->tim, - thr_args->tq, - thr_args->tmo_ev); - args->appl.timeout--; - } + counters->ctr_seq += seq_step; } odp_packet_free_multi(pkt_ref_array, pkt_array_size); @@ -717,7 +735,8 @@ static int gen_send_thread(void *arg) * @param msg output buffer */ -static void process_icmp_pkt(odph_icmphdr_t *icmp, char *msg) +static void process_icmp_pkt(thread_args_t *thr_args, + odph_icmphdr_t *icmp, char *msg) { uint64_t trecv; uint64_t tsend; @@ -726,7 +745,7 @@ static void process_icmp_pkt(odph_icmphdr_t *icmp, char *msg) msg[0] = 0; if (icmp->type == ICMP_ECHOREPLY) { - odp_atomic_inc_u64(&counters.icmp); + thr_args->counters.ctr_icmp_reply_rcv++; memcpy(&tsend, (uint8_t *)icmp + ODPH_ICMPHDR_LEN, sizeof(uint64_t)); @@ -751,7 +770,8 @@ static void process_icmp_pkt(odph_icmphdr_t *icmp, char *msg) * @param pkt_tbl packets to be print * @param len packet number */ -static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) +static void print_pkts(int thr, thread_args_t *thr_args, + odp_packet_t pkt_tbl[], unsigned len) { odp_packet_t pkt; char *buf; @@ -768,21 +788,20 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) if (!odp_packet_has_ipv4(pkt)) continue; - odp_atomic_inc_u64(&counters.ip); + thr_args->counters.ctr_pkt_rcv++; buf = odp_packet_data(pkt); ip = (odph_ipv4hdr_t *)(buf + odp_packet_l3_offset(pkt)); offset = odp_packet_l4_offset(pkt); /* udp */ - if (ip->proto == ODPH_IPPROTO_UDP) { - odp_atomic_inc_u64(&counters.udp); - } + if (ip->proto == ODPH_IPPROTO_UDP) + thr_args->counters.ctr_udp_rcv++; /* icmp */ if (ip->proto == ODPH_IPPROTO_ICMPv4) { icmp = (odph_icmphdr_t *)(buf + offset); - process_icmp_pkt(icmp, msg); + process_icmp_pkt(thr_args, icmp, msg); printf(" [%02i] %s\n", thr, msg); } } @@ -810,14 +829,11 @@ static int gen_recv_thread(void *arg) odp_barrier_wait(&barrier); for (;;) { - if (args->appl.number != -1 && - odp_atomic_load_u64(&counters.icmp) >= - (unsigned int)args->appl.number) { + if (thr_args->stop) break; - } /* Use schedule to get buf from any input queue */ - ev_cnt = odp_schedule_multi(NULL, ODP_SCHED_WAIT, + ev_cnt = odp_schedule_multi(NULL, ODP_SCHED_NO_WAIT, events, MAX_RX_BURST); if (ev_cnt == 0) continue; @@ -848,7 +864,7 @@ static int gen_recv_thread(void *arg) } if (pkt_cnt) { - print_pkts(thr, pkts, pkt_cnt); + print_pkts(thr, thr_args, pkts, pkt_cnt); odp_packet_free_multi(pkts, pkt_cnt); } @@ -857,6 +873,35 @@ static int gen_recv_thread(void *arg) return 0; } +#define COUNTER_SUM(_c, _nw) \ +({ \ + int _itr; \ + uint64_t _result = 0; \ + \ + for (_itr = 0; _itr < _nw; _itr++) \ + _result += args->thread[_itr].counters.ctr_ ## _c; \ + \ + _result; \ +}) + +static void garceful_stop_ping(void) +{ + uint64_t snd, rcv; + + if (args->appl.mode != APPL_MODE_PING) + return; + + while (args->appl.timeout >= 0) { + snd = COUNTER_SUM(pkt_snd, 2); + rcv = COUNTER_SUM(icmp_reply_rcv, 2); + if (rcv >= snd) + break; + + sleep(1); + args->appl.timeout--; + } +} + /** * printing verbose statistics * @@ -868,8 +913,8 @@ static void print_global_stats(int num_workers) uint64_t pps_snd = 0, maximum_pps_snd = 0; uint64_t pkts_rcv = 0, pkts_rcv_prev = 0; uint64_t pps_rcv = 0, maximum_pps_rcv = 0; - uint64_t stall; - int verbose_interval = 20; + uint64_t stall, pkts_snd_drop; + int verbose_interval = 20, i; odp_thrmask_t thrd_mask; odp_barrier_wait(&barrier); @@ -878,12 +923,15 @@ static void print_global_stats(int num_workers) next = odp_time_sum(odp_time_local(), wait); while (odp_thrmask_worker(&thrd_mask) == num_workers) { - if (args->appl.number != -1 && - odp_atomic_load_u64(&counters.cnt) >= - (unsigned int)args->appl.number) { - break; - } + if (args->appl.mode != APPL_MODE_RCV && + args->appl.number != -1) { + uint64_t cnt = COUNTER_SUM(pkt_snd, num_workers); + if (cnt >= (unsigned int)args->appl.number) { + garceful_stop_ping(); + break; + } + } cur = odp_time_local(); if (odp_time_cmp(next, cur) > 0) { left = odp_time_diff(next, cur); @@ -894,18 +942,22 @@ static void print_global_stats(int num_workers) usleep(stall / ODP_TIME_USEC_IN_NS); continue; } - next = odp_time_sum(cur, wait); + switch (args->appl.mode) { case APPL_MODE_RCV: - pkts_rcv = odp_atomic_load_u64(&counters.ip); + pkts_rcv = COUNTER_SUM(pkt_rcv, num_workers); + pkts_snd = 0; + pkts_snd_drop = 0; break; case APPL_MODE_PING: - pkts_snd = odp_atomic_load_u64(&counters.seq); - pkts_rcv = odp_atomic_load_u64(&counters.icmp); + pkts_snd = COUNTER_SUM(pkt_snd, num_workers); + pkts_snd_drop = COUNTER_SUM(pkt_snd_drop, num_workers); + pkts_rcv = COUNTER_SUM(icmp_reply_rcv, num_workers); break; case APPL_MODE_UDP: - pkts_snd = odp_atomic_load_u64(&counters.seq); + pkts_snd = COUNTER_SUM(pkt_snd, num_workers); + pkts_snd_drop = COUNTER_SUM(pkt_snd_drop, num_workers); break; default: continue; @@ -927,11 +979,14 @@ static void print_global_stats(int num_workers) "rcv: %" PRIu64 ", " "recv rate: %" PRIu64 " pps, " "max recv rate: %" PRIu64 " pps\n", - pkts_snd, odp_atomic_load_u64(&counters.tx_drops), + pkts_snd, pkts_snd_drop, pps_snd, maximum_pps_snd, pkts_rcv, pps_rcv, maximum_pps_rcv); fflush(NULL); } + + for (i = 0; i < num_workers; i++) + args->thread[i].stop = 1; } /** @@ -968,14 +1023,6 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - /* init counters */ - odp_atomic_init_u64(&counters.seq, 0); - odp_atomic_init_u64(&counters.ip, 0); - odp_atomic_init_u64(&counters.udp, 0); - odp_atomic_init_u64(&counters.icmp, 0); - odp_atomic_init_u64(&counters.cnt, 0); - odp_atomic_init_u64(&counters.tx_drops, 0); - /* Reserve memory for args from shared mem */ shm = odp_shm_reserve("shm_args", sizeof(args_t), ODP_CACHE_LINE_SIZE, 0); @@ -1024,6 +1071,15 @@ int main(int argc, char *argv[]) num_workers = 2; } } + args->thread_cnt = num_workers; + + /* Burst size */ + if (args->appl.mode == APPL_MODE_PING) + args->tx_burst_size = 1; + else if (args->appl.mode == APPL_MODE_UDP) + args->tx_burst_size = args->appl.udp_tx_burst; + else + args->tx_burst_size = 0; /* Create packet pool */ odp_pool_param_init(¶ms); @@ -1104,6 +1160,7 @@ int main(int argc, char *argv[]) if (args->appl.mode == APPL_MODE_PING) { odp_cpumask_t cpu_mask; int cpu_first, cpu_next; + thread_args_t *thr_args; odp_cpumask_zero(&cpu_mask); cpu_first = odp_cpumask_first(&cpumask); @@ -1114,60 +1171,64 @@ int main(int argc, char *argv[]) EXAMPLE_ERR("queue_create failed\n"); abort(); } - args->thread[1].rx.ifs = ifs; - args->thread[1].rx.ifs_count = args->appl.if_count; - args->thread[1].pool = pool; - args->thread[1].tp = tp; - args->thread[1].tq = tq; - args->thread[1].tim = odp_timer_alloc(tp, tq, NULL); - if (args->thread[1].tim == ODP_TIMER_INVALID) { + thr_args = &args->thread[PING_THR_RX]; + thr_args->rx.ifs = ifs; + thr_args->rx.ifs_count = args->appl.if_count; + thr_args->pool = pool; + thr_args->tp = tp; + thr_args->tq = tq; + thr_args->tim = odp_timer_alloc(tp, tq, NULL); + if (thr_args->tim == ODP_TIMER_INVALID) { EXAMPLE_ERR("timer_alloc failed\n"); abort(); } - args->thread[1].tmo_ev = odp_timeout_alloc(tmop); - if (args->thread[1].tmo_ev == ODP_TIMEOUT_INVALID) { + thr_args->tmo_ev = odp_timeout_alloc(tmop); + if (thr_args->tmo_ev == ODP_TIMEOUT_INVALID) { EXAMPLE_ERR("timeout_alloc failed\n"); abort(); } - args->thread[1].mode = args->appl.mode; + thr_args->mode = args->appl.mode; memset(&thr_params, 0, sizeof(thr_params)); thr_params.start = gen_recv_thread; - thr_params.arg = &args->thread[1]; + thr_params.arg = thr_args; thr_params.thr_type = ODP_THREAD_WORKER; thr_params.instance = instance; - odph_odpthreads_create(&thread_tbl[1], &cpu_mask, &thr_params); + odph_odpthreads_create(&thread_tbl[PING_THR_RX], + &cpu_mask, &thr_params); tq = odp_queue_create("", NULL); if (tq == ODP_QUEUE_INVALID) { EXAMPLE_ERR("queue_create failed\n"); abort(); } - args->thread[0].tx.pktout = ifs[0].pktout[0]; - args->thread[0].tx.pktout_cfg = &ifs[0].config.pktout; - args->thread[0].pool = pool; - args->thread[0].tp = tp; - args->thread[0].tq = tq; - args->thread[0].tim = odp_timer_alloc(tp, tq, NULL); - if (args->thread[0].tim == ODP_TIMER_INVALID) { + thr_args = &args->thread[PING_THR_TX]; + thr_args->tx.pktout = ifs[0].pktout[0]; + thr_args->tx.pktout_cfg = &ifs[0].config.pktout; + thr_args->pool = pool; + thr_args->tp = tp; + thr_args->tq = tq; + thr_args->tim = odp_timer_alloc(tp, tq, NULL); + if (thr_args->tim == ODP_TIMER_INVALID) { EXAMPLE_ERR("timer_alloc failed\n"); abort(); } - args->thread[0].tmo_ev = odp_timeout_alloc(tmop); - if (args->thread[0].tmo_ev == ODP_TIMEOUT_INVALID) { + thr_args->tmo_ev = odp_timeout_alloc(tmop); + if (thr_args->tmo_ev == ODP_TIMEOUT_INVALID) { EXAMPLE_ERR("timeout_alloc failed\n"); abort(); } - args->thread[0].mode = args->appl.mode; + thr_args->mode = args->appl.mode; cpu_next = odp_cpumask_next(&cpumask, cpu_first); odp_cpumask_zero(&cpu_mask); odp_cpumask_set(&cpu_mask, cpu_next); thr_params.start = gen_send_thread; - thr_params.arg = &args->thread[0]; + thr_params.arg = thr_args; - odph_odpthreads_create(&thread_tbl[0], &cpu_mask, &thr_params); + odph_odpthreads_create(&thread_tbl[PING_THR_TX], + &cpu_mask, &thr_params); } else { int cpu = odp_cpumask_first(&cpumask); @@ -1176,6 +1237,7 @@ int main(int argc, char *argv[]) odp_cpumask_t thd_mask; int (*thr_run_func)(void *); int if_idx, pktout_idx; + uint64_t start_seq; if (args->appl.mode == APPL_MODE_RCV) { args->thread[i].rx.ifs = ifs; @@ -1185,11 +1247,13 @@ int main(int argc, char *argv[]) if_idx = i % args->appl.if_count; pktout_idx = (i / args->appl.if_count) % ifs[if_idx].pktout_count; + start_seq = i * args->tx_burst_size; args->thread[i].tx.pktout = ifs[if_idx].pktout[pktout_idx]; args->thread[i].tx.pktout_cfg = &ifs[if_idx].config.pktout; + args->thread[i].counters.ctr_seq = start_seq; } tq = odp_queue_create("", NULL); if (tq == ODP_QUEUE_INVALID) { @@ -1531,9 +1595,9 @@ static void usage(char *progname) "OpenDataPlane example application.\n" "\n" " Work mode:\n" - " 1.send udp packets\n" + " 1.send ipv4 udp packets\n" " odp_generator -I eth0 --srcmac fe:0f:97:c9:e0:44 --dstmac 32:cb:9b:27:2f:1a --srcip 192.168.0.1 --dstip 192.168.0.2 -m u\n" - " 2.receive udp packets\n" + " 2.receive ipv4 packets\n" " odp_generator -I eth0 -m r\n" " 3.work likes ping\n" " odp_generator -I eth0 --srcmac fe:0f:97:c9:e0:44 --dstmac 32:cb:9b:27:2f:1a --srcip 192.168.0.1 --dstip 192.168.0.2 --cpumask 0xc -m p\n"