From patchwork Mon Aug 14 11:00:08 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: 109987 Delivered-To: patch@linaro.org Received: by 10.140.95.78 with SMTP id h72csp4181158qge; Mon, 14 Aug 2017 04:05:01 -0700 (PDT) X-Received: by 10.200.53.251 with SMTP id l56mr31293755qtb.82.1502708700776; Mon, 14 Aug 2017 04:05:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1502708700; cv=none; d=google.com; s=arc-20160816; b=SQpnuGYnGRdQWSpXJ4SjxGXFlTLVKuXUB+COo/3ScH3+hxcQZXXJLfnqwboMZooJLO V7BLxfvYFbjKTbE+XoWVF8TLftFVp0bAp4GRV1C8zlfnk2NTPvFbJ7R+dl974a2UV4MO pq9NiFU+tdrPGkCXwHaVhldCceAkLQpc++Dn9RSJW9rp06rynF4+LgiaVMBwu7VyfwKL aP2TTEzxrsWmIftbvF2gSpmqZ61xnurlIJPJ4adBprSdumFEIb5TtOJfFJEim4eJ62X1 UW73MMQQc7xUk/mtifps+4HDl41UnjC3uw6xtv7cttgY8KHYRVfVA4teGVBPjfLIcfta WuSA== 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=qE6MVXaXjTTKPlgxYXlNVOSrR1gE9eFdctfT70A234A=; b=PqpJ2kahWe+5URIZxHfG7WxK+e6cL398tjv8g6fi0qIktbgxYEy8/lWc1tr4HS0k1i 0B8MbxXzhs5t4VLSdwSLsS3meEWIz3SE+rK/C6tp17zYxNyxzesdhm5JXcEWoPRvVOF1 /G9in7hXpxrTMnCnUEywbqdDK3nu7FQ5JWDyJ+WH0tLmu/FOwfy2iuXtiAR3+jH05lqB gNGprxU/Fkw31fStYzSLEmlhONIxSz9R0RZ3p15Tk9Gtgopelatzceo1KKHqAvU/8FJD 39S/JQsydbYGQiJGJxl03klhJ6rgqx87r9vy5QgDj2UszQdOTWVtwT9/zw6HCcYGDXwN i41w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 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 (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id 39si6211748qtz.529.2017.08.14.04.05.00; Mon, 14 Aug 2017 04:05:00 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 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 72DEC65C49; Mon, 14 Aug 2017 11:05: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=-1.9 required=5.0 tests=BAYES_00,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,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 5EB1B607FC; Mon, 14 Aug 2017 11:01:11 +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 EDB49644E9; Mon, 14 Aug 2017 11:01:06 +0000 (UTC) Received: from forward100j.mail.yandex.net (forward100j.mail.yandex.net [5.45.198.240]) by lists.linaro.org (Postfix) with ESMTPS id 0160365C36 for ; Mon, 14 Aug 2017 11:00:30 +0000 (UTC) Received: from mxback1g.mail.yandex.net (mxback1g.mail.yandex.net [IPv6:2a02:6b8:0:1472:2741:0:8b7:162]) by forward100j.mail.yandex.net (Yandex) with ESMTP id 9300F5D815EE for ; Mon, 14 Aug 2017 14:00:29 +0300 (MSK) Received: from smtp4o.mail.yandex.net (smtp4o.mail.yandex.net [2a02:6b8:0:1a2d::28]) by mxback1g.mail.yandex.net (nwsmtp/Yandex) with ESMTP id p70luBsWIJ-0TbikKjA; Mon, 14 Aug 2017 14:00:29 +0300 Received: by smtp4o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id n8iAsiDcdV-0SV86aNY; Mon, 14 Aug 2017 14:00:28 +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, 14 Aug 2017 14:00:08 +0300 Message-Id: <1502708408-10504-7-git-send-email-odpbot@yandex.ru> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1502708408-10504-1-git-send-email-odpbot@yandex.ru> References: <1502708408-10504-1-git-send-email-odpbot@yandex.ru> Github-pr-num: 124 Subject: [lng-odp] [PATCH v1 6/6] examples: generator: update odp_generator to use HW checksum capabilities 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 Signed-off-by: Bogdan Pricope --- /** Email created from pull request 124 (bogdanPricope:dpdk_hw_csum_pr) ** https://github.com/Linaro/odp/pull/124 ** Patch: https://github.com/Linaro/odp/pull/124.patch ** Base sha: 90d4ce1b3b25ca18446131906007571cc0ed0191 ** Merge commit sha: de5ffd818401be95fd7eb3398670d1b92d27d2de **/ example/generator/odp_generator.c | 156 ++++++++++++++++++++++++++++++-------- 1 file changed, 124 insertions(+), 32 deletions(-) diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c index f3ec43be..65471f54 100644 --- a/example/generator/odp_generator.c +++ b/example/generator/odp_generator.c @@ -46,6 +46,7 @@ typedef struct { odp_pktio_t pktio; + odp_pktio_config_t config; odp_pktout_queue_t pktout[MAX_WORKERS]; unsigned pktout_count; } interface_t; @@ -91,7 +92,16 @@ static struct { /** * Thread specific arguments */ typedef struct { - odp_pktout_queue_t pktout; /**< Packet output queue to use*/ + union { + struct { + odp_pktout_queue_t pktout; /**< Packet output queue */ + odp_pktout_config_opt_t *pktout_cfg; /**< Packet output config*/ + } tx; + struct { + interface_t *ifs; /**< Interfaces array */ + int ifs_count; /**< Interfaces array size */ + } rx; + }; odp_pool_t pool; /**< Pool for packet IO */ odp_timer_pool_t tp; /**< Timer pool handle */ odp_queue_t tq; /**< Queue for timeouts */ @@ -116,6 +126,10 @@ static args_t *args; /** Barrier to sync threads execution */ static odp_barrier_t barrier; +/** Packet processing function types */ +typedef odp_packet_t (*setup_pkt_ref_t)(odp_pool_t, odp_pktout_config_opt_t *); +typedef int (*setup_pkt_t)(odp_packet_t, odp_pktout_config_opt_t *); + /* helper funcs */ static void parse_args(int argc, char *argv[], appl_args_t *appl_args); static void print_info(char *progname, appl_args_t *appl_args); @@ -190,20 +204,22 @@ static int scan_ip(char *buf, unsigned int *paddr) * Setup array of reference packets * * @param pool Packet pool + * @param pktout_cfg Interface output configuration * @param pkt_ref_array Packet array * @param pkt_ref_array_size Packet array size * @param setup_ref Packet setup function * @return 0 success, -1 failed */ static int setup_pkt_ref_array(odp_pool_t pool, + odp_pktout_config_opt_t *pktout_cfg, odp_packet_t *pkt_ref_array, int pkt_ref_array_size, - odp_packet_t (*setup_ref)(odp_pool_t)) + setup_pkt_ref_t setup_ref) { int i; for (i = 0; i < pkt_ref_array_size; i++) { - pkt_ref_array[i] = (*setup_ref)(pool); + pkt_ref_array[i] = (*setup_ref)(pool, pktout_cfg); if (pkt_ref_array[i] == ODP_PACKET_INVALID) break; } @@ -218,21 +234,23 @@ static int setup_pkt_ref_array(odp_pool_t pool, /** * Setup array of packets * + * @param pktout_cfg Interface output configuration * @param pkt_ref_array Reference packet array * @param pkt_array Packet array * @param pkt_array_size Packet array size * @param setup_pkt Packet setup function * @return 0 success, -1 failed */ -static int setup_pkt_array(odp_packet_t *pkt_ref_array, +static int setup_pkt_array(odp_pktout_config_opt_t *pktout_cfg, + odp_packet_t *pkt_ref_array, odp_packet_t *pkt_array, int pkt_array_size, - int (*setup_pkt)(odp_packet_t)) + setup_pkt_t setup_pkt) { int i; for (i = 0; i < pkt_array_size; i++) { - if ((*setup_pkt)(pkt_ref_array[i])) + if ((*setup_pkt)(pkt_ref_array[i], pktout_cfg)) break; pkt_array[i] = odp_packet_ref_static(pkt_ref_array[i]); @@ -252,13 +270,15 @@ static int setup_pkt_array(odp_packet_t *pkt_ref_array, * set up an udp packet reference * * @param pool Buffer pool to create packet in + * @param pktout_cfg Interface output configuration * * * @retval Handle of created packet * @retval ODP_PACKET_INVALID Packet could not be created * */ -static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool) +static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool, + odp_pktout_config_opt_t *pktout_cfg) { odp_packet_t pkt; char *buf; @@ -302,8 +322,10 @@ static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool) udp->src_port = odp_cpu_to_be_16(args->appl.srcport); udp->dst_port = odp_cpu_to_be_16(args->appl.dstport); udp->length = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN); - udp->chksum = 0; - udp->chksum = odph_ipv4_udp_chksum(pkt); + if (!pktout_cfg->bit.udp_chksum) { + udp->chksum = 0; + udp->chksum = odph_ipv4_udp_chksum(pkt); + } return pkt; } @@ -312,11 +334,12 @@ static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool) * set up an udp packet * * @param pkt Reference UDP packet + * @param pktout_cfg Interface output configuration * * @return Success/Failed * @retval 0 on success, -1 on fail */ -static int setup_udp_pkt(odp_packet_t pkt) +static int setup_udp_pkt(odp_packet_t pkt, odp_pktout_config_opt_t *pktout_cfg) { char *buf; odph_ipv4hdr_t *ip; @@ -328,9 +351,17 @@ static int setup_udp_pkt(odp_packet_t pkt) ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xFFFF; ip->id = odp_cpu_to_be_16(seq); - ip->chksum = 0; - ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN); + if (!pktout_cfg->bit.ipv4_chksum) { + ip->chksum = 0; + ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN); + } + if (pktout_cfg->bit.ipv4_chksum || pktout_cfg->bit.udp_chksum) { + odp_packet_l2_offset_set(pkt, 0); + odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN); + odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + + ODPH_IPV4HDR_LEN); + } return 0; } @@ -338,11 +369,13 @@ static int setup_udp_pkt(odp_packet_t pkt) * Set up an icmp packet reference * * @param pool Buffer pool to create packet in + * @param pktout_cfg Interface output configuration * * @return Handle of created packet * @retval ODP_PACKET_INVALID Packet could not be created */ -static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool) +static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool, + odp_pktout_config_opt_t *pktout_cfg) { odp_packet_t pkt; char *buf; @@ -350,6 +383,8 @@ static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool) odph_ipv4hdr_t *ip; odph_icmphdr_t *icmp; + (void)pktout_cfg; + args->appl.payload = 56; pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_ICMPHDR_LEN + ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); @@ -393,11 +428,13 @@ static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool) * Set up an icmp packet * * @param pkt Reference ICMP packet + * @param pktout_cfg Interface output configuration * * @return Success/Failed * @retval 0 on success, -1 on fail */ -static int setup_icmp_pkt(odp_packet_t pkt) +static int setup_icmp_pkt(odp_packet_t pkt, + odp_pktout_config_opt_t *pktout_cfg) { char *buf; odph_ipv4hdr_t *ip; @@ -412,8 +449,10 @@ static int setup_icmp_pkt(odp_packet_t pkt) ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xffff; ip->id = odp_cpu_to_be_16(seq); - ip->chksum = 0; - ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN); + if (!pktout_cfg->bit.ipv4_chksum) { + ip->chksum = 0; + ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN); + } /* icmp */ icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN); @@ -427,6 +466,13 @@ static int setup_icmp_pkt(odp_packet_t pkt) icmp->chksum = 0; icmp->chksum = odph_chksum(icmp, args->appl.payload + ODPH_ICMPHDR_LEN); + if (pktout_cfg->bit.ipv4_chksum) { + odp_packet_l2_offset_set(pkt, 0); + odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN); + odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN + + ODPH_IPV4HDR_LEN); + } + return 0; } @@ -467,6 +513,22 @@ static int create_pktio(const char *dev, odp_pool_t pool, dev); return -1; } + odp_pktio_config_init(&itf->config); + itf->config.pktin.bit.ipv4_chksum = capa.config.pktin.bit.ipv4_chksum; + itf->config.pktin.bit.udp_chksum = capa.config.pktin.bit.udp_chksum; + itf->config.pktin.bit.drop_ipv4_err = + capa.config.pktin.bit.drop_ipv4_err; + itf->config.pktin.bit.drop_udp_err = capa.config.pktin.bit.drop_udp_err; + + itf->config.pktout.bit.ipv4_chksum = capa.config.pktout.bit.ipv4_chksum; + itf->config.pktout.bit.udp_chksum = capa.config.pktout.bit.udp_chksum; + + if (odp_pktio_config(itf->pktio, &itf->config)) { + EXAMPLE_ERR("Error: Failed to set interface configuration %s\n", + dev); + return -1; + } + if (num_rx_queues > capa.max_input_queues) num_rx_queues = capa.max_input_queues; @@ -527,17 +589,18 @@ static int gen_send_thread(void *arg) int ret = 0; thread_args_t *thr_args; odp_pktout_queue_t pktout; + 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 burst_start, burst_size; - odp_packet_t (*setup_pkt_ref)(odp_pool_t) = NULL; - int (*setup_pkt)(odp_packet_t) = NULL; + setup_pkt_ref_t setup_pkt_ref = NULL; + setup_pkt_t setup_pkt = NULL; thr = odp_thread_id(); thr_args = arg; - - pktout = thr_args->pktout; + pktout = thr_args->tx.pktout; + pktout_cfg = thr_args->tx.pktout_cfg; /* Create reference packets*/ if (args->appl.mode == APPL_MODE_UDP) { @@ -554,8 +617,9 @@ static int gen_send_thread(void *arg) return -1; } - if (setup_pkt_ref_array(thr_args->pool, pkt_ref_array, - pkt_array_size, setup_pkt_ref)) { + if (setup_pkt_ref_array(thr_args->pool, pktout_cfg, + pkt_ref_array, pkt_array_size, + setup_pkt_ref)) { EXAMPLE_ERR("[%02i] Error: failed to create" " reference packets\n", thr); return -1; @@ -572,7 +636,7 @@ static int gen_send_thread(void *arg) break; /* Setup TX burst*/ - if (setup_pkt_array(pkt_ref_array, pkt_array, + if (setup_pkt_array(pktout_cfg, pkt_ref_array, pkt_array, pkt_array_size, setup_pkt)) { EXAMPLE_ERR("[%02i] Error: failed to setup packets\n", thr); @@ -718,12 +782,15 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) static int gen_recv_thread(void *arg) { int thr; + thread_args_t *thr_args; odp_packet_t pkts[MAX_RX_BURST], pkt; odp_event_t events[MAX_RX_BURST]; int pkt_cnt, ev_cnt, i; + interface_t *itfs, *itf; thr = odp_thread_id(); - (void)arg; + thr_args = (thread_args_t *)arg; + itfs = thr_args->rx.ifs; printf(" [%02i] created mode: RECEIVE\n", thr); odp_barrier_wait(&barrier); @@ -742,6 +809,23 @@ static int gen_recv_thread(void *arg) continue; for (i = 0, pkt_cnt = 0; i < ev_cnt; i++) { pkt = odp_packet_from_event(events[i]); + itf = &itfs[odp_pktio_index(odp_packet_input(pkt))]; + + if (odp_packet_has_ipv4(pkt)) { + if (itf->config.pktin.bit.ipv4_chksum) { + /* HW validation */ + if (odp_packet_has_l3_error(pkt)) + printf("HW detected L3 error\n"); + } /* else SW validation */ + } + + if (odp_packet_has_udp(pkt)) { + if (itf->config.pktin.bit.udp_chksum) { + /* HW validation*/ + if (odp_packet_has_l4_error(pkt)) + printf("HW detected L4 error\n"); + } /* else SW validation */ + } /* Drop packets with errors */ if (odp_unlikely(odp_packet_has_error(pkt))) { @@ -751,9 +835,11 @@ static int gen_recv_thread(void *arg) pkts[pkt_cnt++] = pkt; } - print_pkts(thr, pkts, pkt_cnt); + if (pkt_cnt) { + print_pkts(thr, pkts, pkt_cnt); - odp_packet_free_multi(pkts, pkt_cnt); + odp_packet_free_multi(pkts, pkt_cnt); + } } return 0; @@ -1008,7 +1094,8 @@ int main(int argc, char *argv[]) EXAMPLE_ERR("queue_create failed\n"); abort(); } - (void)args->thread[1].pktout; /* Not used*/ + 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; @@ -1037,7 +1124,8 @@ int main(int argc, char *argv[]) EXAMPLE_ERR("queue_create failed\n"); abort(); } - args->thread[0].pktout = ifs[0].pktout[0]; + 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; @@ -1069,15 +1157,19 @@ int main(int argc, char *argv[]) int (*thr_run_func)(void *); int if_idx, pktout_idx; - if (args->appl.mode == APPL_MODE_RCV) - (void)args->thread[i].pktout; /*not used*/ - else { + if (args->appl.mode == APPL_MODE_RCV) { + args->thread[i].rx.ifs = ifs; + args->thread[i].rx.ifs_count = + args->appl.if_count; + } else { if_idx = i % args->appl.if_count; pktout_idx = (i / args->appl.if_count) % ifs[if_idx].pktout_count; - args->thread[i].pktout = + args->thread[i].tx.pktout = ifs[if_idx].pktout[pktout_idx]; + args->thread[i].tx.pktout_cfg = + &ifs[if_idx].config.pktout; } tq = odp_queue_create("", NULL); if (tq == ODP_QUEUE_INVALID) {