From patchwork Thu Dec 30 03:54:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ong Boon Leong X-Patchwork-Id: 12701222 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F36F2C433FE for ; Thu, 30 Dec 2021 03:58:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235591AbhL3D62 (ORCPT ); Wed, 29 Dec 2021 22:58:28 -0500 Received: from mga11.intel.com ([192.55.52.93]:3816 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233004AbhL3D62 (ORCPT ); Wed, 29 Dec 2021 22:58:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640836708; x=1672372708; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=XH+OH2B7oAGbJjGlDAbt1/kCzbYLah1qjhrfWjUB6Sg=; b=cZJKbwPsMpNy2Z+K/HuC/599xExi3aeOpw7MY0lHkIFgcgORBiamSsQl L/Jm59Uw8HFYwHTxI7napPcn/LOUf9uEGrLm6rmnXLl2zxnOw7ZRh1Kuw L2gnz5PZ2BkdymawJzBtuL/G8QQAoJh2iIubBtDIBXwGgmJBljD+gHboy krtkYC+UsWWqcEkpO6KOvpFegE7sLw5V7qzE7DFIbXQzFwdZWwdxOeLoW jaGBRrBClTQHdUBJntCkmadbeJKLtq8hJu5ElGm3EYpj0UFuLyex9CTis 3MPoLJzUFnwZhFh/RuLoLuQdUX735lCjn+GxQOjzkYxqrm5gbeaP5dXQa Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10212"; a="239154616" X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="239154616" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Dec 2021 19:58:28 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="609801526" Received: from p12hl98bong5.png.intel.com ([10.158.65.178]) by FMSMGA003.fm.intel.com with ESMTP; 29 Dec 2021 19:58:24 -0800 From: Ong Boon Leong To: bjorn@kernel.org, Magnus Karlsson , Jonathan Lemon , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" , Jakub Kicinski , Jesper Dangaard Brouer , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , KP Singh Cc: bpf@vger.kernel.org, netdev@vger.kernel.org, Ong Boon Leong Subject: [PATCH bpf-next v2 1/7] samples/bpf: xdpsock: add VLAN support for Tx-only operation Date: Thu, 30 Dec 2021 11:54:41 +0800 Message-Id: <20211230035447.523177-2-boon.leong.ong@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211230035447.523177-1-boon.leong.ong@intel.com> References: <20211230035447.523177-1-boon.leong.ong@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net In multi-queue environment testing, the support for VLAN-tag based steering is useful. So, this patch adds the capability to add VLAN tag (VLAN ID and Priority) to the generated Tx frame. To set the VLAN ID=10 and Priority=2 for Tx only through TxQ=3: $ xdpsock -i eth0 -t -N -z -q 3 -V -J 10 -K 2 If VLAN ID (-J) and Priority (-K) is set, it default to VLAN ID = 1 VLAN Priority = 0. For example, VLAN-tagged Tx only, xdp copy mode through TxQ=1: $ xdpsock -i eth0 -t -N -c -q 1 -V Acked-by: Song Liu Signed-off-by: Ong Boon Leong --- samples/bpf/xdpsock_user.c | 90 +++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 15 deletions(-) diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c index 616d663d55a..d5e298ccf49 100644 --- a/samples/bpf/xdpsock_user.c +++ b/samples/bpf/xdpsock_user.c @@ -56,6 +56,12 @@ #define DEBUG_HEXDUMP 0 +#define VLAN_PRIO_MASK 0xe000 /* Priority Code Point */ +#define VLAN_PRIO_SHIFT 13 +#define VLAN_VID_MASK 0x0fff /* VLAN Identifier */ +#define VLAN_VID__DEFAULT 1 +#define VLAN_PRI__DEFAULT 0 + typedef __u64 u64; typedef __u32 u32; typedef __u16 u16; @@ -81,6 +87,9 @@ static u32 opt_batch_size = 64; static int opt_pkt_count; static u16 opt_pkt_size = MIN_PKT_SIZE; static u32 opt_pkt_fill_pattern = 0x12345678; +static bool opt_vlan_tag; +static u16 opt_pkt_vlan_id = VLAN_VID__DEFAULT; +static u16 opt_pkt_vlan_pri = VLAN_PRI__DEFAULT; static bool opt_extra_stats; static bool opt_quiet; static bool opt_app_stats; @@ -101,6 +110,14 @@ static u32 prog_id; static bool opt_busy_poll; static bool opt_reduced_cap; +struct vlan_ethhdr { + unsigned char h_dest[6]; + unsigned char h_source[6]; + __be16 h_vlan_proto; + __be16 h_vlan_TCI; + __be16 h_vlan_encapsulated_proto; +}; + struct xsk_ring_stats { unsigned long rx_npkts; unsigned long tx_npkts; @@ -740,11 +757,13 @@ static inline u16 udp_csum(u32 saddr, u32 daddr, u32 len, #define ETH_FCS_SIZE 4 -#define PKT_HDR_SIZE (sizeof(struct ethhdr) + sizeof(struct iphdr) + \ +#define ETH_HDR_SIZE (opt_vlan_tag ? sizeof(struct vlan_ethhdr) : \ + sizeof(struct ethhdr)) +#define PKT_HDR_SIZE (ETH_HDR_SIZE + sizeof(struct iphdr) + \ sizeof(struct udphdr)) #define PKT_SIZE (opt_pkt_size - ETH_FCS_SIZE) -#define IP_PKT_SIZE (PKT_SIZE - sizeof(struct ethhdr)) +#define IP_PKT_SIZE (PKT_SIZE - ETH_HDR_SIZE) #define UDP_PKT_SIZE (IP_PKT_SIZE - sizeof(struct iphdr)) #define UDP_PKT_DATA_SIZE (UDP_PKT_SIZE - sizeof(struct udphdr)) @@ -752,17 +771,42 @@ static u8 pkt_data[XSK_UMEM__DEFAULT_FRAME_SIZE]; static void gen_eth_hdr_data(void) { - struct udphdr *udp_hdr = (struct udphdr *)(pkt_data + - sizeof(struct ethhdr) + - sizeof(struct iphdr)); - struct iphdr *ip_hdr = (struct iphdr *)(pkt_data + - sizeof(struct ethhdr)); - struct ethhdr *eth_hdr = (struct ethhdr *)pkt_data; - - /* ethernet header */ - memcpy(eth_hdr->h_dest, "\x3c\xfd\xfe\x9e\x7f\x71", ETH_ALEN); - memcpy(eth_hdr->h_source, "\xec\xb1\xd7\x98\x3a\xc0", ETH_ALEN); - eth_hdr->h_proto = htons(ETH_P_IP); + struct udphdr *udp_hdr; + struct iphdr *ip_hdr; + + if (opt_vlan_tag) { + struct vlan_ethhdr *veth_hdr = (struct vlan_ethhdr *)pkt_data; + u16 vlan_tci = 0; + + udp_hdr = (struct udphdr *)(pkt_data + + sizeof(struct vlan_ethhdr) + + sizeof(struct iphdr)); + ip_hdr = (struct iphdr *)(pkt_data + + sizeof(struct vlan_ethhdr)); + + /* ethernet & VLAN header */ + memcpy(veth_hdr->h_dest, "\x3c\xfd\xfe\x9e\x7f\x71", ETH_ALEN); + memcpy(veth_hdr->h_source, "\xec\xb1\xd7\x98\x3a\xc0", ETH_ALEN); + veth_hdr->h_vlan_proto = htons(ETH_P_8021Q); + vlan_tci = opt_pkt_vlan_id & VLAN_VID_MASK; + vlan_tci |= (opt_pkt_vlan_pri << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK; + veth_hdr->h_vlan_TCI = htons(vlan_tci); + veth_hdr->h_vlan_encapsulated_proto = htons(ETH_P_IP); + } else { + struct ethhdr *eth_hdr = (struct ethhdr *)pkt_data; + + udp_hdr = (struct udphdr *)(pkt_data + + sizeof(struct ethhdr) + + sizeof(struct iphdr)); + ip_hdr = (struct iphdr *)(pkt_data + + sizeof(struct ethhdr)); + + /* ethernet header */ + memcpy(eth_hdr->h_dest, "\x3c\xfd\xfe\x9e\x7f\x71", ETH_ALEN); + memcpy(eth_hdr->h_source, "\xec\xb1\xd7\x98\x3a\xc0", ETH_ALEN); + eth_hdr->h_proto = htons(ETH_P_IP); + } + /* IP header */ ip_hdr->version = IPVERSION; @@ -920,6 +964,9 @@ static struct option long_options[] = { {"tx-pkt-count", required_argument, 0, 'C'}, {"tx-pkt-size", required_argument, 0, 's'}, {"tx-pkt-pattern", required_argument, 0, 'P'}, + {"tx-vlan", no_argument, 0, 'V'}, + {"tx-vlan-id", required_argument, 0, 'J'}, + {"tx-vlan-pri", required_argument, 0, 'K'}, {"extra-stats", no_argument, 0, 'x'}, {"quiet", no_argument, 0, 'Q'}, {"app-stats", no_argument, 0, 'a'}, @@ -960,6 +1007,9 @@ static void usage(const char *prog) " (Default: %d bytes)\n" " Min size: %d, Max size %d.\n" " -P, --tx-pkt-pattern=nPacket fill pattern. Default: 0x%x\n" + " -V, --tx-vlan Send VLAN tagged packets (For -t|--txonly)\n" + " -J, --tx-vlan-id=n Tx VLAN ID [1-4095]. Default: %d (For -V|--tx-vlan)\n" + " -K, --tx-vlan-pri=n Tx VLAN Priority [0-7]. Default: %d (For -V|--tx-vlan)\n" " -x, --extra-stats Display extra statistics.\n" " -Q, --quiet Do not display any stats.\n" " -a, --app-stats Display application (syscall) statistics.\n" @@ -969,7 +1019,8 @@ static void usage(const char *prog) "\n"; fprintf(stderr, str, prog, XSK_UMEM__DEFAULT_FRAME_SIZE, opt_batch_size, MIN_PKT_SIZE, MIN_PKT_SIZE, - XSK_UMEM__DEFAULT_FRAME_SIZE, opt_pkt_fill_pattern); + XSK_UMEM__DEFAULT_FRAME_SIZE, opt_pkt_fill_pattern, + VLAN_VID__DEFAULT, VLAN_PRI__DEFAULT); exit(EXIT_FAILURE); } @@ -981,7 +1032,7 @@ static void parse_command_line(int argc, char **argv) opterr = 0; for (;;) { - c = getopt_long(argc, argv, "Frtli:q:pSNn:czf:muMd:b:C:s:P:xQaI:BR", + c = getopt_long(argc, argv, "Frtli:q:pSNn:czf:muMd:b:C:s:P:VJ:K:xQaI:BR", long_options, &option_index); if (c == -1) break; @@ -1062,6 +1113,15 @@ static void parse_command_line(int argc, char **argv) case 'P': opt_pkt_fill_pattern = strtol(optarg, NULL, 16); break; + case 'V': + opt_vlan_tag = true; + break; + case 'J': + opt_pkt_vlan_id = atoi(optarg); + break; + case 'K': + opt_pkt_vlan_pri = atoi(optarg); + break; case 'x': opt_extra_stats = 1; break; From patchwork Thu Dec 30 03:54:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ong Boon Leong X-Patchwork-Id: 12701223 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 45269C433FE for ; Thu, 30 Dec 2021 03:58:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235608AbhL3D6d (ORCPT ); Wed, 29 Dec 2021 22:58:33 -0500 Received: from mga11.intel.com ([192.55.52.93]:3816 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233004AbhL3D6c (ORCPT ); Wed, 29 Dec 2021 22:58:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640836712; x=1672372712; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=n4dCRbk8wrr5bdAIsDms8x7I3EKsrTvye882PklfrUI=; b=VwcSuKvfbDSEvWtyEtXrAteVluLsaWa4HgTVCwcxlnOzdi9o344MkiNH WeHr32c96avdpG1R3Z6gUpsNzWCjDEHm2G0N8LTfYWcwa4GAgrv4DzUCV Tb+pjWpmZ9nLDideeUbuuIZbBtDtL9xx4XI7TlAKCQcuvMZeN94Z7weEE BxqXNJbUDCfF+xAby+CexOJ6xvZUJnulnxXZe/IK2HKbzw8qJdmL48ZHJ lPDgZuUtEB7G4qmyTaycp3WlpDgzeBbynUuDZY76PKj0kbs1HHxpXpwkX E3NrSfAHgq5pEXLXboKnfLqUeFSgs0obv02z8v6qJU+xREpPMoP3LLm45 w==; X-IronPort-AV: E=McAfee;i="6200,9189,10212"; a="239154620" X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="239154620" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Dec 2021 19:58:32 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="609801534" Received: from p12hl98bong5.png.intel.com ([10.158.65.178]) by FMSMGA003.fm.intel.com with ESMTP; 29 Dec 2021 19:58:28 -0800 From: Ong Boon Leong To: bjorn@kernel.org, Magnus Karlsson , Jonathan Lemon , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" , Jakub Kicinski , Jesper Dangaard Brouer , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , KP Singh Cc: bpf@vger.kernel.org, netdev@vger.kernel.org, Ong Boon Leong Subject: [PATCH bpf-next v2 2/7] samples/bpf: xdpsock: add Dest and Src MAC setting for Tx-only operation Date: Thu, 30 Dec 2021 11:54:42 +0800 Message-Id: <20211230035447.523177-3-boon.leong.ong@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211230035447.523177-1-boon.leong.ong@intel.com> References: <20211230035447.523177-1-boon.leong.ong@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net To set Dest MAC address (-G|--tx-dmac) only: $ xdpsock -i eth0 -t -N -z -G aa:bb:cc:dd:ee:ff To set Source MAC address (-H|--tx-smac) only: $ xdpsock -i eth0 -t -N -z -H 11:22:33:44:55:66 To set both Dest and Source MAC address: $ xdpsock -i eth0 -t -N -z -G aa:bb:cc:dd:ee:ff \ -H 11:22:33:44:55:66 The default Dest and Source MAC address remain the same as before. Acked-by: Song Liu Acked-by: Jesper Dangaard Brouer Signed-off-by: Ong Boon Leong --- samples/bpf/xdpsock_user.c | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c index d5e298ccf49..c9a8748a460 100644 --- a/samples/bpf/xdpsock_user.c +++ b/samples/bpf/xdpsock_user.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -90,6 +91,10 @@ static u32 opt_pkt_fill_pattern = 0x12345678; static bool opt_vlan_tag; static u16 opt_pkt_vlan_id = VLAN_VID__DEFAULT; static u16 opt_pkt_vlan_pri = VLAN_PRI__DEFAULT; +static struct ether_addr opt_txdmac = {{ 0x3c, 0xfd, 0xfe, + 0x9e, 0x7f, 0x71 }}; +static struct ether_addr opt_txsmac = {{ 0xec, 0xb1, 0xd7, + 0x98, 0x3a, 0xc0 }}; static bool opt_extra_stats; static bool opt_quiet; static bool opt_app_stats; @@ -785,8 +790,8 @@ static void gen_eth_hdr_data(void) sizeof(struct vlan_ethhdr)); /* ethernet & VLAN header */ - memcpy(veth_hdr->h_dest, "\x3c\xfd\xfe\x9e\x7f\x71", ETH_ALEN); - memcpy(veth_hdr->h_source, "\xec\xb1\xd7\x98\x3a\xc0", ETH_ALEN); + memcpy(veth_hdr->h_dest, &opt_txdmac, ETH_ALEN); + memcpy(veth_hdr->h_source, &opt_txsmac, ETH_ALEN); veth_hdr->h_vlan_proto = htons(ETH_P_8021Q); vlan_tci = opt_pkt_vlan_id & VLAN_VID_MASK; vlan_tci |= (opt_pkt_vlan_pri << VLAN_PRIO_SHIFT) & VLAN_PRIO_MASK; @@ -802,8 +807,8 @@ static void gen_eth_hdr_data(void) sizeof(struct ethhdr)); /* ethernet header */ - memcpy(eth_hdr->h_dest, "\x3c\xfd\xfe\x9e\x7f\x71", ETH_ALEN); - memcpy(eth_hdr->h_source, "\xec\xb1\xd7\x98\x3a\xc0", ETH_ALEN); + memcpy(eth_hdr->h_dest, &opt_txdmac, ETH_ALEN); + memcpy(eth_hdr->h_source, &opt_txsmac, ETH_ALEN); eth_hdr->h_proto = htons(ETH_P_IP); } @@ -967,6 +972,8 @@ static struct option long_options[] = { {"tx-vlan", no_argument, 0, 'V'}, {"tx-vlan-id", required_argument, 0, 'J'}, {"tx-vlan-pri", required_argument, 0, 'K'}, + {"tx-dmac", required_argument, 0, 'G'}, + {"tx-smac", required_argument, 0, 'H'}, {"extra-stats", no_argument, 0, 'x'}, {"quiet", no_argument, 0, 'Q'}, {"app-stats", no_argument, 0, 'a'}, @@ -1010,6 +1017,8 @@ static void usage(const char *prog) " -V, --tx-vlan Send VLAN tagged packets (For -t|--txonly)\n" " -J, --tx-vlan-id=n Tx VLAN ID [1-4095]. Default: %d (For -V|--tx-vlan)\n" " -K, --tx-vlan-pri=n Tx VLAN Priority [0-7]. Default: %d (For -V|--tx-vlan)\n" + " -G, --tx-dmac= Dest MAC addr of TX frame in aa:bb:cc:dd:ee:ff format (For -V|--tx-vlan)\n" + " -H, --tx-smac= Src MAC addr of TX frame in aa:bb:cc:dd:ee:ff format (For -V|--tx-vlan)\n" " -x, --extra-stats Display extra statistics.\n" " -Q, --quiet Do not display any stats.\n" " -a, --app-stats Display application (syscall) statistics.\n" @@ -1032,7 +1041,7 @@ static void parse_command_line(int argc, char **argv) opterr = 0; for (;;) { - c = getopt_long(argc, argv, "Frtli:q:pSNn:czf:muMd:b:C:s:P:VJ:K:xQaI:BR", + c = getopt_long(argc, argv, "Frtli:q:pSNn:czf:muMd:b:C:s:P:VJ:K:G:H:xQaI:BR", long_options, &option_index); if (c == -1) break; @@ -1122,6 +1131,22 @@ static void parse_command_line(int argc, char **argv) case 'K': opt_pkt_vlan_pri = atoi(optarg); break; + case 'G': + if (!ether_aton_r(optarg, + (struct ether_addr *)&opt_txdmac)) { + fprintf(stderr, "Invalid dmac address:%s\n", + optarg); + usage(basename(argv[0])); + } + break; + case 'H': + if (!ether_aton_r(optarg, + (struct ether_addr *)&opt_txsmac)) { + fprintf(stderr, "Invalid smac address:%s\n", + optarg); + usage(basename(argv[0])); + } + break; case 'x': opt_extra_stats = 1; break; From patchwork Thu Dec 30 03:54:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ong Boon Leong X-Patchwork-Id: 12701224 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E27CEC433FE for ; Thu, 30 Dec 2021 03:58:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235619AbhL3D6h (ORCPT ); Wed, 29 Dec 2021 22:58:37 -0500 Received: from mga11.intel.com ([192.55.52.93]:3816 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235614AbhL3D6g (ORCPT ); Wed, 29 Dec 2021 22:58:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640836716; x=1672372716; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=eh+J1EjCWOTZPgw04DeLPj6g1rFzAGHOPJpfkrqdhAQ=; b=DxZ4bXzVz56+ZZnw/eEs0nEB9yslFMA8ery1wn9ujC4A/Q6IySWs9KCD 5ZmKhWTnzEoolY5jk+6Pfas2cQ/AuhnR7BDEdaJdugusDtKmCyGedbJ89 xC7Fn2+DnZ8LPW1DIKU0UWj1ngHBlSSg4CliKUQ7x8B+qXfSI4eATBBIp qmghJSPDG2sNsEcaW+b4Xbd79B/0BlWRjUxZKHsctiqtFT32VYdAyYUd7 H1u40ajr4em3lH7fJ4cvy6+DFzqUPcOeGx+MyRPGUQgjr9RqU7XJDfNLl DEUm3Jb+IVDoWDNL7E66Ga6JF8zAYNxDCcREZcGWPMl0GR5cvA9dFViY1 g==; X-IronPort-AV: E=McAfee;i="6200,9189,10212"; a="239154629" X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="239154629" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Dec 2021 19:58:36 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="609801538" Received: from p12hl98bong5.png.intel.com ([10.158.65.178]) by FMSMGA003.fm.intel.com with ESMTP; 29 Dec 2021 19:58:32 -0800 From: Ong Boon Leong To: bjorn@kernel.org, Magnus Karlsson , Jonathan Lemon , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" , Jakub Kicinski , Jesper Dangaard Brouer , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , KP Singh Cc: bpf@vger.kernel.org, netdev@vger.kernel.org, Ong Boon Leong Subject: [PATCH bpf-next v2 3/7] samples/bpf: xdpsock: add clockid selection support Date: Thu, 30 Dec 2021 11:54:43 +0800 Message-Id: <20211230035447.523177-4-boon.leong.ong@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211230035447.523177-1-boon.leong.ong@intel.com> References: <20211230035447.523177-1-boon.leong.ong@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net User specifies the clock selection by using -w CLOCK or --clock=CLOCK where CLOCK=[REALTIME, TAI, BOOTTIME, MONOTONIC]. The default CLOCK selection is MONOTONIC. The implementation of clock selection parsing is borrowed from iproute2/tc/q_taprio.c Signed-off-by: Ong Boon Leong --- samples/bpf/xdpsock_user.c | 40 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c index c9a8748a460..e6e9a20375c 100644 --- a/samples/bpf/xdpsock_user.c +++ b/samples/bpf/xdpsock_user.c @@ -114,6 +114,7 @@ static u32 opt_num_xsks = 1; static u32 prog_id; static bool opt_busy_poll; static bool opt_reduced_cap; +static clockid_t opt_clock = CLOCK_MONOTONIC; struct vlan_ethhdr { unsigned char h_dest[6]; @@ -178,15 +179,40 @@ struct xsk_socket_info { u32 outstanding_tx; }; +static const struct clockid_map { + const char *name; + clockid_t clockid; +} clockids_map[] = { + { "REALTIME", CLOCK_REALTIME }, + { "TAI", CLOCK_TAI }, + { "BOOTTIME", CLOCK_BOOTTIME }, + { "MONOTONIC", CLOCK_MONOTONIC }, + { NULL } +}; + static int num_socks; struct xsk_socket_info *xsks[MAX_SOCKS]; int sock; +static int get_clockid(clockid_t *id, const char *name) +{ + const struct clockid_map *clk; + + for (clk = clockids_map; clk->name; clk++) { + if (strcasecmp(clk->name, name) == 0) { + *id = clk->clockid; + return 0; + } + } + + return -1; +} + static unsigned long get_nsecs(void) { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); + clock_gettime(opt_clock, &ts); return ts.tv_sec * 1000000000UL + ts.tv_nsec; } @@ -965,6 +991,7 @@ static struct option long_options[] = { {"shared-umem", no_argument, 0, 'M'}, {"force", no_argument, 0, 'F'}, {"duration", required_argument, 0, 'd'}, + {"clock", required_argument, 0, 'w'}, {"batch-size", required_argument, 0, 'b'}, {"tx-pkt-count", required_argument, 0, 'C'}, {"tx-pkt-size", required_argument, 0, 's'}, @@ -1006,6 +1033,7 @@ static void usage(const char *prog) " -F, --force Force loading the XDP prog\n" " -d, --duration=n Duration in secs to run command.\n" " Default: forever.\n" + " -w, --clock=CLOCK Clock NAME (default MONOTONIC).\n" " -b, --batch-size=n Batch size for sending or receiving\n" " packets. Default: %d\n" " -C, --tx-pkt-count=n Number of packets to send.\n" @@ -1041,7 +1069,7 @@ static void parse_command_line(int argc, char **argv) opterr = 0; for (;;) { - c = getopt_long(argc, argv, "Frtli:q:pSNn:czf:muMd:b:C:s:P:VJ:K:G:H:xQaI:BR", + c = getopt_long(argc, argv, "Frtli:q:pSNn:w:czf:muMd:b:C:s:P:VJ:K:G:H:xQaI:BR", long_options, &option_index); if (c == -1) break; @@ -1075,6 +1103,14 @@ static void parse_command_line(int argc, char **argv) case 'n': opt_interval = atoi(optarg); break; + case 'w': + if (get_clockid(&opt_clock, optarg)) { + fprintf(stderr, + "ERROR: Invalid clock %s. Default to CLOCK_MONOTONIC.\n", + optarg); + opt_clock = CLOCK_MONOTONIC; + } + break; case 'z': opt_xdp_bind_flags |= XDP_ZEROCOPY; break; From patchwork Thu Dec 30 03:54:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ong Boon Leong X-Patchwork-Id: 12701225 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 389EAC433F5 for ; Thu, 30 Dec 2021 03:58:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235609AbhL3D6l (ORCPT ); Wed, 29 Dec 2021 22:58:41 -0500 Received: from mga11.intel.com ([192.55.52.93]:3816 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233004AbhL3D6k (ORCPT ); Wed, 29 Dec 2021 22:58:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640836720; x=1672372720; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9aVPYndc9Wg5HQBqqI8m8H5Kq7Ppvb3tsb4FHCaoJ0w=; b=IbQfktWMPBP0u/onJuh6tJ2qolnf6LvJYma3AcmRK9CXHInvGxNjzdE/ VYYYC+La/00jVy79AVXL1Ic1ATfkF+EKMTru4CiwQXpQWrjFI3ScQGk93 u1hsOyk6rGzrhPfsFLR4P8kLT19vJPFArCiu+z6VfFrJ2gIjqTzlX3T4y qy/thuF8T/HCYCMpylOfZd62s1M8z1LGnIRYQ+bVSqM9DdrfFqm4L0tCC Upg8j3nA0qyQdMPiMPRLZlvS3EYMDrVAiTTLBuJOVopq7croRsrjiJLLy 0n4rGuy+4eRSadS/MqirqEz7H1tx6asdzZS1wZ6k2TOmiWArcMVTDaDBT Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10212"; a="239154635" X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="239154635" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Dec 2021 19:58:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="609801543" Received: from p12hl98bong5.png.intel.com ([10.158.65.178]) by FMSMGA003.fm.intel.com with ESMTP; 29 Dec 2021 19:58:36 -0800 From: Ong Boon Leong To: bjorn@kernel.org, Magnus Karlsson , Jonathan Lemon , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" , Jakub Kicinski , Jesper Dangaard Brouer , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , KP Singh Cc: bpf@vger.kernel.org, netdev@vger.kernel.org, Ong Boon Leong Subject: [PATCH bpf-next v2 4/7] samples/bpf: xdpsock: add cyclic TX operation capability Date: Thu, 30 Dec 2021 11:54:44 +0800 Message-Id: <20211230035447.523177-5-boon.leong.ong@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211230035447.523177-1-boon.leong.ong@intel.com> References: <20211230035447.523177-1-boon.leong.ong@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net Tx cycle time is in micro-seconds unit. By combining the batch size (-b M) and Tx cycle time (-T|--tx-cycle N), xdpsock now can transmit batch-size of packets every N-us periodically. Cyclic TX operation is not applicable if --poll mode is used. To transmit 16 packets every 1ms cycle time for total of 100000 packets silently: $ xdpsock -i eth0 -T -N -z -T 1000 -b 16 -C 100000 To print cyclic TX schedule variance stats, use --app-stats|-a: $ xdpsock -i eth0 -T -N -z -T 1000 -b 16 -C 100000 -a sock0@eth0:0 txonly xdp-drv pps pkts 0.00 rx 0 0 tx 0 100000 calls/s count rx empty polls 0 0 fill fail polls 0 0 copy tx sendtos 0 0 tx wakeup sendtos 0 6254 opt polls 0 0 period min ave max cycle Cyclic TX 1000000 53507 75334 712642 6250 Signed-off-by: Ong Boon Leong --- samples/bpf/xdpsock_user.c | 85 +++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c index e6e9a20375c..a2a42ec4b0e 100644 --- a/samples/bpf/xdpsock_user.c +++ b/samples/bpf/xdpsock_user.c @@ -63,12 +63,19 @@ #define VLAN_VID__DEFAULT 1 #define VLAN_PRI__DEFAULT 0 +#define NSEC_PER_SEC 1000000000UL +#define NSEC_PER_USEC 1000 + typedef __u64 u64; typedef __u32 u32; typedef __u16 u16; typedef __u8 u8; static unsigned long prev_time; +static long tx_cycle_diff_min; +static long tx_cycle_diff_max; +static double tx_cycle_diff_ave; +static long tx_cycle_cnt; enum benchmark_type { BENCH_RXDROP = 0, @@ -115,6 +122,7 @@ static u32 prog_id; static bool opt_busy_poll; static bool opt_reduced_cap; static clockid_t opt_clock = CLOCK_MONOTONIC; +static unsigned long opt_tx_cycle_ns; struct vlan_ethhdr { unsigned char h_dest[6]; @@ -305,6 +313,15 @@ static void dump_app_stats(long dt) xsks[i]->app_stats.prev_tx_wakeup_sendtos = xsks[i]->app_stats.tx_wakeup_sendtos; xsks[i]->app_stats.prev_opt_polls = xsks[i]->app_stats.opt_polls; } + + if (opt_tx_cycle_ns) { + printf("\n%-18s %-10s %-10s %-10s %-10s %-10s\n", + "", "period", "min", "ave", "max", "cycle"); + printf("%-18s %-10lu %-10lu %-10lu %-10lu %-10lu\n", + "Cyclic TX", opt_tx_cycle_ns, tx_cycle_diff_min, + (long)(tx_cycle_diff_ave / tx_cycle_cnt), + tx_cycle_diff_max, tx_cycle_cnt); + } } static bool get_interrupt_number(void) @@ -1001,6 +1018,7 @@ static struct option long_options[] = { {"tx-vlan-pri", required_argument, 0, 'K'}, {"tx-dmac", required_argument, 0, 'G'}, {"tx-smac", required_argument, 0, 'H'}, + {"tx-cycle", required_argument, 0, 'T'}, {"extra-stats", no_argument, 0, 'x'}, {"quiet", no_argument, 0, 'Q'}, {"app-stats", no_argument, 0, 'a'}, @@ -1047,6 +1065,7 @@ static void usage(const char *prog) " -K, --tx-vlan-pri=n Tx VLAN Priority [0-7]. Default: %d (For -V|--tx-vlan)\n" " -G, --tx-dmac= Dest MAC addr of TX frame in aa:bb:cc:dd:ee:ff format (For -V|--tx-vlan)\n" " -H, --tx-smac= Src MAC addr of TX frame in aa:bb:cc:dd:ee:ff format (For -V|--tx-vlan)\n" + " -T, --tx-cycle=n Tx cycle time in micro-seconds (For -t|--txonly).\n" " -x, --extra-stats Display extra statistics.\n" " -Q, --quiet Do not display any stats.\n" " -a, --app-stats Display application (syscall) statistics.\n" @@ -1069,7 +1088,7 @@ static void parse_command_line(int argc, char **argv) opterr = 0; for (;;) { - c = getopt_long(argc, argv, "Frtli:q:pSNn:w:czf:muMd:b:C:s:P:VJ:K:G:H:xQaI:BR", + c = getopt_long(argc, argv, "Frtli:q:pSNn:w:czf:muMd:b:C:s:P:VJ:K:G:H:T:xQaI:BR", long_options, &option_index); if (c == -1) break; @@ -1183,6 +1202,10 @@ static void parse_command_line(int argc, char **argv) usage(basename(argv[0])); } break; + case 'T': + opt_tx_cycle_ns = atoi(optarg); + opt_tx_cycle_ns *= NSEC_PER_USEC; + break; case 'x': opt_extra_stats = 1; break; @@ -1388,7 +1411,7 @@ static void rx_drop_all(void) } } -static void tx_only(struct xsk_socket_info *xsk, u32 *frame_nb, int batch_size) +static int tx_only(struct xsk_socket_info *xsk, u32 *frame_nb, int batch_size) { u32 idx; unsigned int i; @@ -1397,7 +1420,7 @@ static void tx_only(struct xsk_socket_info *xsk, u32 *frame_nb, int batch_size) batch_size) { complete_tx_only(xsk, batch_size); if (benchmark_done) - return; + return 0; } for (i = 0; i < batch_size; i++) { @@ -1413,6 +1436,8 @@ static void tx_only(struct xsk_socket_info *xsk, u32 *frame_nb, int batch_size) *frame_nb += batch_size; *frame_nb %= NUM_FRAMES; complete_tx_only(xsk, batch_size); + + return batch_size; } static inline int get_batch_size(int pkt_cnt) @@ -1446,16 +1471,39 @@ static void tx_only_all(void) { struct pollfd fds[MAX_SOCKS] = {}; u32 frame_nb[MAX_SOCKS] = {}; + unsigned long next_tx_ns = 0; int pkt_cnt = 0; int i, ret; + if (opt_poll && opt_tx_cycle_ns) { + fprintf(stderr, + "Error: --poll and --tx-cycles are both set\n"); + return; + } + for (i = 0; i < num_socks; i++) { fds[0].fd = xsk_socket__fd(xsks[i]->xsk); fds[0].events = POLLOUT; } + if (opt_tx_cycle_ns) { + /* Align Tx time to micro-second boundary */ + next_tx_ns = (get_nsecs() / NSEC_PER_USEC + 1) * + NSEC_PER_USEC; + next_tx_ns += opt_tx_cycle_ns; + + /* Initialize periodic Tx scheduling variance */ + tx_cycle_diff_min = 1000000000; + tx_cycle_diff_max = 0; + tx_cycle_diff_ave = 0.0; + } + while ((opt_pkt_count && pkt_cnt < opt_pkt_count) || !opt_pkt_count) { int batch_size = get_batch_size(pkt_cnt); + struct timespec next; + int tx_cnt = 0; + long diff; + int err; if (opt_poll) { for (i = 0; i < num_socks; i++) @@ -1468,13 +1516,40 @@ static void tx_only_all(void) continue; } + if (opt_tx_cycle_ns) { + next.tv_sec = next_tx_ns / NSEC_PER_SEC; + next.tv_nsec = next_tx_ns % NSEC_PER_SEC; + err = clock_nanosleep(opt_clock, TIMER_ABSTIME, &next, NULL); + if (err) { + if (err != EINTR) + fprintf(stderr, + "clock_nanosleep failed. Err:%d errno:%d\n", + err, errno); + break; + } + + /* Measure periodic Tx scheduling variance */ + diff = get_nsecs() - next_tx_ns; + if (diff < tx_cycle_diff_min) + tx_cycle_diff_min = diff; + + if (diff > tx_cycle_diff_max) + tx_cycle_diff_max = diff; + + tx_cycle_diff_ave += (double)diff; + tx_cycle_cnt++; + } + for (i = 0; i < num_socks; i++) - tx_only(xsks[i], &frame_nb[i], batch_size); + tx_cnt += tx_only(xsks[i], &frame_nb[i], batch_size); - pkt_cnt += batch_size; + pkt_cnt += tx_cnt; if (benchmark_done) break; + + if (opt_tx_cycle_ns) + next_tx_ns += opt_tx_cycle_ns; } if (opt_pkt_count) From patchwork Thu Dec 30 03:54:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ong Boon Leong X-Patchwork-Id: 12701226 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 72B64C433FE for ; Thu, 30 Dec 2021 03:58:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235641AbhL3D6p (ORCPT ); Wed, 29 Dec 2021 22:58:45 -0500 Received: from mga11.intel.com ([192.55.52.93]:3816 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233004AbhL3D6o (ORCPT ); Wed, 29 Dec 2021 22:58:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640836724; x=1672372724; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=u1ELHxpyNCf1RCbpTw6DNfBEVTDxwJX+shCST/j92XQ=; b=eefPB+ZKohEVNklsUy69AEGFvoWIMrLMGgbX11SzvCNqX5FLhLylxItX X2TLjSnPxhgZXfiGf5bOL+/vXg0K0lNOtw6cHh1Moln3U0b1g4B7zeD3G wkLIlQnFB4gENAjpb+IkMCKwxvw5stIWrLSLI2IDWYr0nN4pkVEdn8Tik U4gbgYDra1wK4KBYk+i7CvX9P4tDKzeZtsO9VqMMfUJd7OrVFDW1XBnX5 tu6EuRS5rPlrRWW59J/RMwfUrWFA6NvlVZlgMKRXQu9CDfqaNOwIezvj0 1DqxPn6qJHq1z6BHiGTZWZ3pK/QiDf80xYIdQvyog0M8cX51yatolbDeu Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10212"; a="239154640" X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="239154640" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Dec 2021 19:58:44 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="609801547" Received: from p12hl98bong5.png.intel.com ([10.158.65.178]) by FMSMGA003.fm.intel.com with ESMTP; 29 Dec 2021 19:58:40 -0800 From: Ong Boon Leong To: bjorn@kernel.org, Magnus Karlsson , Jonathan Lemon , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" , Jakub Kicinski , Jesper Dangaard Brouer , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , KP Singh Cc: bpf@vger.kernel.org, netdev@vger.kernel.org, Ong Boon Leong Subject: [PATCH bpf-next v2 5/7] samples/bpf: xdpsock: add sched policy and priority support Date: Thu, 30 Dec 2021 11:54:45 +0800 Message-Id: <20211230035447.523177-6-boon.leong.ong@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211230035447.523177-1-boon.leong.ong@intel.com> References: <20211230035447.523177-1-boon.leong.ong@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net By default, TX schedule policy is SCHED_OTHER (round-robin time-sharing). To improve TX cyclic scheduling, we add SCHED_FIFO policy and its priority by using -W FIFO or --policy=FIFO and -U or --schpri=. A) From xdpsock --app-stats, for SCHED_OTHER policy: $ xdpsock -i eth0 -t -N -z -T 1000 -b 16 -C 100000 -a period min ave max cycle Cyclic TX 1000000 53507 75334 712642 6250 B) For SCHED_FIFO policy and schpri=50: $ xdpsock -i eth0 -t -N -z -T 1000 -b 16 -C 100000 -a -W FIFO -U 50 period min ave max cycle Cyclic TX 1000000 3699 24859 54397 6250 Signed-off-by: Ong Boon Leong --- samples/bpf/xdpsock_user.c | 61 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c index a2a42ec4b0e..b7d0f536f97 100644 --- a/samples/bpf/xdpsock_user.c +++ b/samples/bpf/xdpsock_user.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,8 @@ #define NSEC_PER_SEC 1000000000UL #define NSEC_PER_USEC 1000 +#define SCHED_PRI__DEFAULT 0 + typedef __u64 u64; typedef __u32 u32; typedef __u16 u16; @@ -123,6 +126,8 @@ static bool opt_busy_poll; static bool opt_reduced_cap; static clockid_t opt_clock = CLOCK_MONOTONIC; static unsigned long opt_tx_cycle_ns; +static int opt_schpolicy = SCHED_OTHER; +static int opt_schprio = SCHED_PRI__DEFAULT; struct vlan_ethhdr { unsigned char h_dest[6]; @@ -198,6 +203,15 @@ static const struct clockid_map { { NULL } }; +static const struct sched_map { + const char *name; + int policy; +} schmap[] = { + { "OTHER", SCHED_OTHER }, + { "FIFO", SCHED_FIFO }, + { NULL } +}; + static int num_socks; struct xsk_socket_info *xsks[MAX_SOCKS]; int sock; @@ -216,6 +230,20 @@ static int get_clockid(clockid_t *id, const char *name) return -1; } +static int get_schpolicy(int *policy, const char *name) +{ + const struct sched_map *sch; + + for (sch = schmap; sch->name; sch++) { + if (strcasecmp(sch->name, name) == 0) { + *policy = sch->policy; + return 0; + } + } + + return -1; +} + static unsigned long get_nsecs(void) { struct timespec ts; @@ -1019,6 +1047,8 @@ static struct option long_options[] = { {"tx-dmac", required_argument, 0, 'G'}, {"tx-smac", required_argument, 0, 'H'}, {"tx-cycle", required_argument, 0, 'T'}, + {"policy", required_argument, 0, 'W'}, + {"schpri", required_argument, 0, 'U'}, {"extra-stats", no_argument, 0, 'x'}, {"quiet", no_argument, 0, 'Q'}, {"app-stats", no_argument, 0, 'a'}, @@ -1066,6 +1096,8 @@ static void usage(const char *prog) " -G, --tx-dmac= Dest MAC addr of TX frame in aa:bb:cc:dd:ee:ff format (For -V|--tx-vlan)\n" " -H, --tx-smac= Src MAC addr of TX frame in aa:bb:cc:dd:ee:ff format (For -V|--tx-vlan)\n" " -T, --tx-cycle=n Tx cycle time in micro-seconds (For -t|--txonly).\n" + " -W, --policy=POLICY Schedule policy. Default: SCHED_OTHER\n" + " -U, --schpri=n Schedule priority. Default: %d\n" " -x, --extra-stats Display extra statistics.\n" " -Q, --quiet Do not display any stats.\n" " -a, --app-stats Display application (syscall) statistics.\n" @@ -1076,7 +1108,8 @@ static void usage(const char *prog) fprintf(stderr, str, prog, XSK_UMEM__DEFAULT_FRAME_SIZE, opt_batch_size, MIN_PKT_SIZE, MIN_PKT_SIZE, XSK_UMEM__DEFAULT_FRAME_SIZE, opt_pkt_fill_pattern, - VLAN_VID__DEFAULT, VLAN_PRI__DEFAULT); + VLAN_VID__DEFAULT, VLAN_PRI__DEFAULT, + SCHED_PRI__DEFAULT); exit(EXIT_FAILURE); } @@ -1088,7 +1121,8 @@ static void parse_command_line(int argc, char **argv) opterr = 0; for (;;) { - c = getopt_long(argc, argv, "Frtli:q:pSNn:w:czf:muMd:b:C:s:P:VJ:K:G:H:T:xQaI:BR", + c = getopt_long(argc, argv, + "Frtli:q:pSNn:w:czf:muMd:b:C:s:P:VJ:K:G:H:T:W:U:xQaI:BR", long_options, &option_index); if (c == -1) break; @@ -1206,6 +1240,17 @@ static void parse_command_line(int argc, char **argv) opt_tx_cycle_ns = atoi(optarg); opt_tx_cycle_ns *= NSEC_PER_USEC; break; + case 'W': + if (get_schpolicy(&opt_schpolicy, optarg)) { + fprintf(stderr, + "ERROR: Invalid policy %s. Default to SCHED_OTHER.\n", + optarg); + opt_schpolicy = SCHED_OTHER; + } + break; + case 'U': + opt_schprio = atoi(optarg); + break; case 'x': opt_extra_stats = 1; break; @@ -1780,6 +1825,7 @@ int main(int argc, char **argv) struct __user_cap_data_struct data[2] = { { 0 } }; struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY}; bool rx = false, tx = false; + struct sched_param schparam; struct xsk_umem_info *umem; struct bpf_object *obj; int xsks_map_fd = 0; @@ -1881,6 +1927,16 @@ int main(int argc, char **argv) prev_time = get_nsecs(); start_time = prev_time; + /* Configure sched priority for better wake-up accuracy */ + memset(&schparam, 0, sizeof(schparam)); + schparam.sched_priority = opt_schprio; + ret = sched_setscheduler(0, opt_schpolicy, &schparam); + if (ret) { + fprintf(stderr, "Error(%d) in setting priority(%d): %s\n", + errno, opt_schprio, strerror(errno)); + goto out; + } + if (opt_bench == BENCH_RXDROP) rx_drop_all(); else if (opt_bench == BENCH_TXONLY) @@ -1888,6 +1944,7 @@ int main(int argc, char **argv) else l2fwd_all(); +out: benchmark_done = true; if (!opt_quiet) From patchwork Thu Dec 30 03:54:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ong Boon Leong X-Patchwork-Id: 12701227 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 739EBC433EF for ; Thu, 30 Dec 2021 03:58:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235652AbhL3D6t (ORCPT ); Wed, 29 Dec 2021 22:58:49 -0500 Received: from mga11.intel.com ([192.55.52.93]:3816 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235614AbhL3D6t (ORCPT ); Wed, 29 Dec 2021 22:58:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640836728; x=1672372728; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=izOcQEI75S9RXJnvu6Dy9r/kjnTJGhtidSucruZ+rTI=; b=j+NvKCsk0J/R7eZn4BM/HFjwFTg60pi6MWZq+FrLpsu4gSp4nnryixOL 7meg/4SsJJj7tHZdlPxSIqT8Xc+jmpDTzcb+cLeN/fSuxyG8OxeLi7bPl IqOSvIAT+YZ5c9x3R5+Z2LDeXo0hKQbMTv4kekXErRME5r75HrtpJEZZY f6rIOve0lvPA7TY+5je9m12l312wR3pyM+Eu1wuLOe/5Gjrb5tygfoTms Qv8gl4ezmvd8gRdgVNVLkBL0Fa8aiOBRXO1ha6q8Bq2Re63x2euniQYRw kthEv2FDl+0Mr1FCIgMhixwgjJS4HjaNqVAGkVtSI9YTGcDVfb0TgvNL8 A==; X-IronPort-AV: E=McAfee;i="6200,9189,10212"; a="239154646" X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="239154646" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Dec 2021 19:58:48 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="609801553" Received: from p12hl98bong5.png.intel.com ([10.158.65.178]) by FMSMGA003.fm.intel.com with ESMTP; 29 Dec 2021 19:58:44 -0800 From: Ong Boon Leong To: bjorn@kernel.org, Magnus Karlsson , Jonathan Lemon , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" , Jakub Kicinski , Jesper Dangaard Brouer , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , KP Singh Cc: bpf@vger.kernel.org, netdev@vger.kernel.org, Ong Boon Leong Subject: [PATCH bpf-next v2 6/7] samples/bpf: xdpsock: add time-out for cleaning Tx Date: Thu, 30 Dec 2021 11:54:46 +0800 Message-Id: <20211230035447.523177-7-boon.leong.ong@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211230035447.523177-1-boon.leong.ong@intel.com> References: <20211230035447.523177-1-boon.leong.ong@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net When user sets tx-pkt-count and in case where there are invalid Tx frame, the complete_tx_only_all() process polls indefinitely. So, this patch adds a time-out mechanism into the process so that the application can terminate automatically after it retries 3*polling interval duration. v1->v2: Thanks to Jesper's and Song Liu's suggestion. - clean-up git message to remove polling log - make the Tx time-out retries configurable with 1s granularity Signed-off-by: Ong Boon Leong --- samples/bpf/xdpsock_user.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c index b7d0f536f97..319cb3cdb22 100644 --- a/samples/bpf/xdpsock_user.c +++ b/samples/bpf/xdpsock_user.c @@ -113,6 +113,7 @@ static u32 irq_no; static int irqs_at_init = -1; static int opt_poll; static int opt_interval = 1; +static int opt_retries = 3; static u32 opt_xdp_bind_flags = XDP_USE_NEED_WAKEUP; static u32 opt_umem_flags; static int opt_unaligned_chunks; @@ -1028,6 +1029,7 @@ static struct option long_options[] = { {"xdp-skb", no_argument, 0, 'S'}, {"xdp-native", no_argument, 0, 'N'}, {"interval", required_argument, 0, 'n'}, + {"retries", required_argument, 0, 'O'}, {"zero-copy", no_argument, 0, 'z'}, {"copy", no_argument, 0, 'c'}, {"frame-size", required_argument, 0, 'f'}, @@ -1072,6 +1074,7 @@ static void usage(const char *prog) " -S, --xdp-skb=n Use XDP skb-mod\n" " -N, --xdp-native=n Enforce XDP native mode\n" " -n, --interval=n Specify statistics update interval (default 1 sec).\n" + " -O, --retries=n Specify time-out retries (1s interval) attempt (default 3).\n" " -z, --zero-copy Force zero-copy mode.\n" " -c, --copy Force copy mode.\n" " -m, --no-need-wakeup Turn off use of driver need wakeup flag.\n" @@ -1122,7 +1125,7 @@ static void parse_command_line(int argc, char **argv) for (;;) { c = getopt_long(argc, argv, - "Frtli:q:pSNn:w:czf:muMd:b:C:s:P:VJ:K:G:H:T:W:U:xQaI:BR", + "Frtli:q:pSNn:w:O:czf:muMd:b:C:s:P:VJ:K:G:H:T:W:U:xQaI:BR", long_options, &option_index); if (c == -1) break; @@ -1164,6 +1167,9 @@ static void parse_command_line(int argc, char **argv) opt_clock = CLOCK_MONOTONIC; } break; + case 'O': + opt_retries = atoi(optarg); + break; case 'z': opt_xdp_bind_flags |= XDP_ZEROCOPY; break; @@ -1509,7 +1515,8 @@ static void complete_tx_only_all(void) pending = !!xsks[i]->outstanding_tx; } } - } while (pending); + sleep(1); + } while (pending && opt_retries-- > 0); } static void tx_only_all(void) From patchwork Thu Dec 30 03:54:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ong Boon Leong X-Patchwork-Id: 12701228 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F370EC433F5 for ; Thu, 30 Dec 2021 03:58:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235659AbhL3D6y (ORCPT ); Wed, 29 Dec 2021 22:58:54 -0500 Received: from mga11.intel.com ([192.55.52.93]:3816 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235655AbhL3D6x (ORCPT ); Wed, 29 Dec 2021 22:58:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1640836733; x=1672372733; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oRE/Ouq20toHwPXmADMDAGnRpYi0U/CeEOTCL3FwLDk=; b=JSXlXbSptgtuCciMRhiRPx7j29K5XRQIjzoQdJLkOB9Ws7EhRdRsN4tF oGfCrs6GIzlKkYR0SgT4H4dldXT7nA3pg6INEn14kHdqlKYJhwa8vO+pt okL3oDGD3uEMzCyCbGFeNs/d65FWT0akW/b7vfpMTmzc5n/TCRrOJq/ir 8xiDYeuGeDJDsMk0golXOogntWXfNvUsY0pVyzSTzRMaOJyLexdtlNdVk bGuUfp0vRYqiYPnqeGaBvI/dvgcpagTkXtKqHG1XAGX/bHL2VrTuShRoX X9jJTW+ndpqsW3oyWmdp+hX83uby1+cKz6Gr+NmZCujr2C20O3v4A0ArN A==; X-IronPort-AV: E=McAfee;i="6200,9189,10212"; a="239154650" X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="239154650" Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Dec 2021 19:58:53 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,247,1635231600"; d="scan'208";a="609801560" Received: from p12hl98bong5.png.intel.com ([10.158.65.178]) by FMSMGA003.fm.intel.com with ESMTP; 29 Dec 2021 19:58:49 -0800 From: Ong Boon Leong To: bjorn@kernel.org, Magnus Karlsson , Jonathan Lemon , Alexei Starovoitov , Daniel Borkmann , "David S . Miller" , Jakub Kicinski , Jesper Dangaard Brouer , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , KP Singh Cc: bpf@vger.kernel.org, netdev@vger.kernel.org, Ong Boon Leong Subject: [PATCH bpf-next v2 7/7] samples/bpf: xdpsock: add timestamp for Tx-only operation Date: Thu, 30 Dec 2021 11:54:47 +0800 Message-Id: <20211230035447.523177-8-boon.leong.ong@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20211230035447.523177-1-boon.leong.ong@intel.com> References: <20211230035447.523177-1-boon.leong.ong@intel.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net It may be useful to add timestamp for Tx packets for continuous or cyclic transmit operation. The timestamp and sequence ID of a Tx packet are stored according to pktgen header format. To enable per-packet timestamp, use -y|--tstamp option. If timestamp is off, pktgen header is not included in the UDP payload. This means receiving side can use the magic number for pktgen for differentiation. The implementation supports both VLAN tagged and untagged option. By default, the minimum packet size is set at 64B. However, if VLAN tagged is on (-V), the minimum packet size is increased to 66B just so to fit the pktgen_hdr size. Added hex_dump() into the code path just for future cross-checking. As before, simply change to "#define DEBUG_HEXDUMP 1" to inspect the accuracy of TX packet. Signed-off-by: Ong Boon Leong --- samples/bpf/xdpsock_user.c | 77 +++++++++++++++++++++++++++++++++----- 1 file changed, 68 insertions(+), 9 deletions(-) diff --git a/samples/bpf/xdpsock_user.c b/samples/bpf/xdpsock_user.c index 319cb3cdb22..aa50864e441 100644 --- a/samples/bpf/xdpsock_user.c +++ b/samples/bpf/xdpsock_user.c @@ -111,6 +111,7 @@ static bool opt_app_stats; static const char *opt_irq_str = ""; static u32 irq_no; static int irqs_at_init = -1; +static u32 sequence; static int opt_poll; static int opt_interval = 1; static int opt_retries = 3; @@ -129,6 +130,7 @@ static clockid_t opt_clock = CLOCK_MONOTONIC; static unsigned long opt_tx_cycle_ns; static int opt_schpolicy = SCHED_OTHER; static int opt_schprio = SCHED_PRI__DEFAULT; +static bool opt_tstamp; struct vlan_ethhdr { unsigned char h_dest[6]; @@ -138,6 +140,14 @@ struct vlan_ethhdr { __be16 h_vlan_encapsulated_proto; }; +#define PKTGEN_MAGIC 0xbe9be955 +struct pktgen_hdr { + __be32 pgh_magic; + __be32 seq_num; + __be32 tv_sec; + __be32 tv_usec; +}; + struct xsk_ring_stats { unsigned long rx_npkts; unsigned long tx_npkts; @@ -836,18 +846,25 @@ static inline u16 udp_csum(u32 saddr, u32 daddr, u32 len, #define ETH_HDR_SIZE (opt_vlan_tag ? sizeof(struct vlan_ethhdr) : \ sizeof(struct ethhdr)) +#define PKTGEN_HDR_SIZE (opt_tstamp ? sizeof(struct pktgen_hdr) : 0) #define PKT_HDR_SIZE (ETH_HDR_SIZE + sizeof(struct iphdr) + \ - sizeof(struct udphdr)) + sizeof(struct udphdr) + PKTGEN_HDR_SIZE) +#define PKTGEN_HDR_OFFSET (ETH_HDR_SIZE + sizeof(struct iphdr) + \ + sizeof(struct udphdr)) +#define PKTGEN_SIZE_MIN (PKTGEN_HDR_OFFSET + sizeof(struct pktgen_hdr) + \ + ETH_FCS_SIZE) #define PKT_SIZE (opt_pkt_size - ETH_FCS_SIZE) #define IP_PKT_SIZE (PKT_SIZE - ETH_HDR_SIZE) #define UDP_PKT_SIZE (IP_PKT_SIZE - sizeof(struct iphdr)) -#define UDP_PKT_DATA_SIZE (UDP_PKT_SIZE - sizeof(struct udphdr)) +#define UDP_PKT_DATA_SIZE (UDP_PKT_SIZE - \ + (sizeof(struct udphdr) + PKTGEN_HDR_SIZE)) static u8 pkt_data[XSK_UMEM__DEFAULT_FRAME_SIZE]; static void gen_eth_hdr_data(void) { + struct pktgen_hdr *pktgen_hdr; struct udphdr *udp_hdr; struct iphdr *ip_hdr; @@ -860,7 +877,10 @@ static void gen_eth_hdr_data(void) sizeof(struct iphdr)); ip_hdr = (struct iphdr *)(pkt_data + sizeof(struct vlan_ethhdr)); - + pktgen_hdr = (struct pktgen_hdr *)(pkt_data + + sizeof(struct vlan_ethhdr) + + sizeof(struct iphdr) + + sizeof(struct udphdr)); /* ethernet & VLAN header */ memcpy(veth_hdr->h_dest, &opt_txdmac, ETH_ALEN); memcpy(veth_hdr->h_source, &opt_txsmac, ETH_ALEN); @@ -877,7 +897,10 @@ static void gen_eth_hdr_data(void) sizeof(struct iphdr)); ip_hdr = (struct iphdr *)(pkt_data + sizeof(struct ethhdr)); - + pktgen_hdr = (struct pktgen_hdr *)(pkt_data + + sizeof(struct ethhdr) + + sizeof(struct iphdr) + + sizeof(struct udphdr)); /* ethernet header */ memcpy(eth_hdr->h_dest, &opt_txdmac, ETH_ALEN); memcpy(eth_hdr->h_source, &opt_txsmac, ETH_ALEN); @@ -906,6 +929,9 @@ static void gen_eth_hdr_data(void) udp_hdr->dest = htons(0x1000); udp_hdr->len = htons(UDP_PKT_SIZE); + if (opt_tstamp) + pktgen_hdr->pgh_magic = htonl(PKTGEN_MAGIC); + /* UDP data */ memset32_htonl(pkt_data + PKT_HDR_SIZE, opt_pkt_fill_pattern, UDP_PKT_DATA_SIZE); @@ -1049,6 +1075,7 @@ static struct option long_options[] = { {"tx-dmac", required_argument, 0, 'G'}, {"tx-smac", required_argument, 0, 'H'}, {"tx-cycle", required_argument, 0, 'T'}, + {"tstamp", no_argument, 0, 'y'}, {"policy", required_argument, 0, 'W'}, {"schpri", required_argument, 0, 'U'}, {"extra-stats", no_argument, 0, 'x'}, @@ -1099,6 +1126,7 @@ static void usage(const char *prog) " -G, --tx-dmac= Dest MAC addr of TX frame in aa:bb:cc:dd:ee:ff format (For -V|--tx-vlan)\n" " -H, --tx-smac= Src MAC addr of TX frame in aa:bb:cc:dd:ee:ff format (For -V|--tx-vlan)\n" " -T, --tx-cycle=n Tx cycle time in micro-seconds (For -t|--txonly).\n" + " -y, --tstamp Add time-stamp to packet (For -t|--txonly).\n" " -W, --policy=POLICY Schedule policy. Default: SCHED_OTHER\n" " -U, --schpri=n Schedule priority. Default: %d\n" " -x, --extra-stats Display extra statistics.\n" @@ -1125,7 +1153,7 @@ static void parse_command_line(int argc, char **argv) for (;;) { c = getopt_long(argc, argv, - "Frtli:q:pSNn:w:O:czf:muMd:b:C:s:P:VJ:K:G:H:T:W:U:xQaI:BR", + "Frtli:q:pSNn:w:O:czf:muMd:b:C:s:P:VJ:K:G:H:T:yW:U:xQaI:BR", long_options, &option_index); if (c == -1) break; @@ -1246,6 +1274,9 @@ static void parse_command_line(int argc, char **argv) opt_tx_cycle_ns = atoi(optarg); opt_tx_cycle_ns *= NSEC_PER_USEC; break; + case 'y': + opt_tstamp = 1; + break; case 'W': if (get_schpolicy(&opt_schpolicy, optarg)) { fprintf(stderr, @@ -1462,9 +1493,10 @@ static void rx_drop_all(void) } } -static int tx_only(struct xsk_socket_info *xsk, u32 *frame_nb, int batch_size) +static int tx_only(struct xsk_socket_info *xsk, u32 *frame_nb, + int batch_size, unsigned long tx_ns) { - u32 idx; + u32 idx, tv_sec, tv_usec; unsigned int i; while (xsk_ring_prod__reserve(&xsk->tx, batch_size, &idx) < @@ -1474,11 +1506,31 @@ static int tx_only(struct xsk_socket_info *xsk, u32 *frame_nb, int batch_size) return 0; } + if (opt_tstamp) { + tv_sec = (u32)(tx_ns / NSEC_PER_SEC); + tv_usec = (u32)((tx_ns % NSEC_PER_SEC) / 1000); + } + for (i = 0; i < batch_size; i++) { struct xdp_desc *tx_desc = xsk_ring_prod__tx_desc(&xsk->tx, idx + i); tx_desc->addr = (*frame_nb + i) * opt_xsk_frame_size; tx_desc->len = PKT_SIZE; + + if (opt_tstamp) { + struct pktgen_hdr *pktgen_hdr; + u64 addr = tx_desc->addr; + char *pkt; + + pkt = xsk_umem__get_data(xsk->umem->buffer, addr); + pktgen_hdr = (struct pktgen_hdr *)(pkt + PKTGEN_HDR_OFFSET); + + pktgen_hdr->seq_num = htonl(sequence++); + pktgen_hdr->tv_sec = htonl(tv_sec); + pktgen_hdr->tv_usec = htonl(tv_usec); + + hex_dump(pkt, PKT_SIZE, addr); + } } xsk_ring_prod__submit(&xsk->tx, batch_size); @@ -1552,6 +1604,7 @@ static void tx_only_all(void) while ((opt_pkt_count && pkt_cnt < opt_pkt_count) || !opt_pkt_count) { int batch_size = get_batch_size(pkt_cnt); + unsigned long tx_ns = 0; struct timespec next; int tx_cnt = 0; long diff; @@ -1581,7 +1634,8 @@ static void tx_only_all(void) } /* Measure periodic Tx scheduling variance */ - diff = get_nsecs() - next_tx_ns; + tx_ns = get_nsecs(); + diff = tx_ns - next_tx_ns; if (diff < tx_cycle_diff_min) tx_cycle_diff_min = diff; @@ -1590,10 +1644,12 @@ static void tx_only_all(void) tx_cycle_diff_ave += (double)diff; tx_cycle_cnt++; + } else if (opt_tstamp) { + tx_ns = get_nsecs(); } for (i = 0; i < num_socks; i++) - tx_cnt += tx_only(xsks[i], &frame_nb[i], batch_size); + tx_cnt += tx_only(xsks[i], &frame_nb[i], batch_size, tx_ns); pkt_cnt += tx_cnt; @@ -1895,6 +1951,9 @@ int main(int argc, char **argv) apply_setsockopt(xsks[i]); if (opt_bench == BENCH_TXONLY) { + if (opt_tstamp && opt_pkt_size < PKTGEN_SIZE_MIN) + opt_pkt_size = PKTGEN_SIZE_MIN; + gen_eth_hdr_data(); for (i = 0; i < NUM_FRAMES; i++)