netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Björn Töpel" <bjorn.topel@gmail.com>
To: bjorn.topel@gmail.com, magnus.karlsson@intel.com,
	alexander.h.duyck@intel.com, alexander.duyck@gmail.com,
	john.fastabend@gmail.com, ast@fb.com, brouer@redhat.com,
	michael.lundkvist@ericsson.com, ravineet.singh@ericsson.com,
	daniel@iogearbox.net, netdev@vger.kernel.org
Cc: jesse.brandeburg@intel.com, anjali.singhai@intel.com,
	rami.rosen@intel.com, jeffrey.b.shaw@intel.com,
	ferruh.yigit@intel.com, qi.z.zhang@intel.com
Subject: [RFC PATCH 12/14] samples/tpacket4: added veth support
Date: Tue, 31 Oct 2017 13:41:43 +0100	[thread overview]
Message-ID: <20171031124145.9667-13-bjorn.topel@gmail.com> (raw)
In-Reply-To: <20171031124145.9667-1-bjorn.topel@gmail.com>

From: Magnus Karlsson <magnus.karlsson@intel.com>

This commit adds support for running the benchmark using a veth pair.

Signed-off-by: Magnus Karlsson <magnus.karlsson@intel.com>
---
 samples/tpacket4/tpbench.c | 189 ++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 163 insertions(+), 26 deletions(-)

diff --git a/samples/tpacket4/tpbench.c b/samples/tpacket4/tpbench.c
index 46fb83009e06..2479f182d1b8 100644
--- a/samples/tpacket4/tpbench.c
+++ b/samples/tpacket4/tpbench.c
@@ -65,8 +65,18 @@ enum benchmark_type {
 static enum tpacket_version opt_tpver = PV4;
 static enum benchmark_type opt_bench = BENCH_RXDROP;
 static const char *opt_if = "";
+static int opt_veth;
 static int opt_zerocopy;
 
+static const char *veth_if1 = "vm1";
+static const char *veth_if2 = "vm2";
+
+/* For process synchronization */
+static int shmid;
+volatile unsigned int *sync_var;
+#define SLEEP_STEP 10
+#define MAX_SLEEP (1000000 / (SLEEP_STEP))
+
 struct tpacket2_queue {
 	void *ring;
 
@@ -296,13 +306,53 @@ static void process_swap_mac(void *queue_pair, unsigned int start,
 	}
 }
 
+static unsigned long get_nsecs(void)
+{
+	struct timespec ts;
+
+	clock_gettime(CLOCK_MONOTONIC, &ts);
+	return ts.tv_sec * 1000000000UL + ts.tv_nsec;
+}
+
 static void run_benchmark(const char *interface_name)
 {
 	unsigned int start, end;
 	struct tp2_queue_pair *qp;
 
+	if (opt_veth) {
+		shmid = shmget(14082017, sizeof(unsigned int),
+			       IPC_CREAT | 666);
+		sync_var = shmat(shmid, 0, 0);
+		if (sync_var == (unsigned int *)-1) {
+			printf("You are probably not running as root\n");
+			exit(EXIT_FAILURE);
+		}
+		*sync_var = 0;
+
+		if (fork() == 0) {
+			opt_if = veth_if2;
+			interface_name = veth_if2;
+		} else {
+			unsigned int i;
+
+			/* Wait for child */
+			for (i = 0; *sync_var == 0 && i < MAX_SLEEP; i++)
+				usleep(SLEEP_STEP);
+			if (i >= MAX_SLEEP) {
+				printf("Wait for vm2 timed out. Exiting.\n");
+				exit(EXIT_FAILURE);
+			}
+		}
+	}
+
 	qp = benchmark.configure(interface_name);
 
+	/* Notify parent that interface configuration completed */
+	if (opt_veth && !strcmp(interface_name, "vm2"))
+		*sync_var = 1;
+
+	start_time = get_nsecs();
+
 	for (;;) {
 		for (;;) {
 			benchmark.rx(qp, &start, &end);
@@ -320,14 +370,6 @@ static void run_benchmark(const char *interface_name)
 	}
 }
 
-static unsigned long get_nsecs(void)
-{
-	struct timespec ts;
-
-	clock_gettime(CLOCK_MONOTONIC, &ts);
-	return ts.tv_sec * 1000000000UL + ts.tv_nsec;
-}
-
 static void *tp2_configure(const char *interface_name)
 {
 	int sfd, noqdisc, ret, ver = TPACKET_V2;
@@ -386,6 +428,36 @@ static void *tp2_configure(const char *interface_name)
 	ret = bind(sfd, (struct sockaddr *)&ll, sizeof(ll));
 	lassert(ret == 0);
 
+	if (opt_veth && !strcmp(interface_name, "vm1"))	{
+		struct tpacket2_queue *txq = &tqp->tx;
+		int i;
+
+		for (i = 0; i < opt_veth; i++) {
+			unsigned int idx = txq->last_used_idx &
+				(txq->ring_size - 1);
+			struct tpacket2_hdr *hdr;
+			unsigned int len;
+
+			hdr = (struct tpacket2_hdr *)(txq->ring +
+					     (idx << txq->frame_size_log2));
+			len = gen_eth_frame((char *)hdr + TPACKET2_HDRLEN -
+					    sizeof(struct sockaddr_ll), i + 1);
+			hdr->tp_snaplen = len;
+			hdr->tp_len = len;
+
+			u_smp_wmb();
+
+			hdr->tp_status = TP_STATUS_SEND_REQUEST;
+			txq->last_used_idx++;
+		}
+
+		ret = sendto(sfd, NULL, 0, MSG_DONTWAIT, NULL, 0);
+		if (!(ret >= 0 || errno == EAGAIN || errno == ENOBUFS))
+			lassert(0);
+
+		tx_npkts += opt_veth;
+	}
+
 	setup_tx_frame();
 
 	return tqp;
@@ -556,6 +628,36 @@ static void *tp3_configure(const char *interface_name)
 	ret = bind(sfd, (struct sockaddr *)&ll, sizeof(ll));
 	lassert(ret == 0);
 
+	if (opt_veth && !strcmp(interface_name, "vm1"))	{
+		struct tpacket2_queue *txq = &tqp->tx;
+		int i;
+
+		for (i = 0; i < opt_veth; i++) {
+			unsigned int idx = txq->last_used_idx &
+				(txq->ring_size - 1);
+			struct tpacket3_hdr *hdr;
+			unsigned int len;
+
+			hdr = (struct tpacket3_hdr *)(txq->ring +
+					     (idx << txq->frame_size_log2));
+			len = gen_eth_frame((char *)hdr + TPACKET3_HDRLEN -
+					    sizeof(struct sockaddr_ll), i + 1);
+			hdr->tp_snaplen = len;
+			hdr->tp_len = len;
+
+			u_smp_wmb();
+
+			hdr->tp_status = TP_STATUS_SEND_REQUEST;
+			txq->last_used_idx++;
+		}
+
+		ret = sendto(sfd, NULL, 0, MSG_DONTWAIT, NULL, 0);
+		if (!(ret >= 0 || errno == EAGAIN || errno == ENOBUFS))
+			lassert(0);
+
+		tx_npkts += opt_veth;
+	}
+
 	setup_tx_frame();
 
 	return tqp;
@@ -783,6 +885,28 @@ static inline int tp4q_enqueue(struct tpacket4_queue *q,
 	return 0;
 }
 
+static inline void *tp4_get_data(void *queue_pair, unsigned int idx,
+				 unsigned int *len)
+{
+	struct tp4_queue_pair *qp = (struct tp4_queue_pair *)queue_pair;
+	struct tp4_umem *umem = qp->umem;
+	struct tpacket4_desc *d;
+
+	d = &qp->rx.ring[idx & qp->rx.ring_mask];
+	*len = d->len;
+
+	return (char *)umem->buffer + (d->idx << umem->frame_size_log2)
+		+ d->offset;
+}
+
+static inline void *tp4_get_buffer(void *queue_pair, unsigned int idx)
+{
+	struct tp4_queue_pair *qp = (struct tp4_queue_pair *)queue_pair;
+	struct tp4_umem *umem = qp->umem;
+
+	return (char *)umem->buffer + (idx << umem->frame_size_log2);
+}
+
 static void *tp4_configure(const char *interface_name)
 {
 	int sfd, noqdisc, ret, ver = TPACKET_V4;
@@ -848,7 +972,27 @@ static void *tp4_configure(const char *interface_name)
 		lassert(ret == 0);
 	}
 
-	for (i = 0; i < (tqp->rx.ring_mask + 1)/4; i++) {
+	if (opt_veth >= (tqp->rx.ring_mask + 1)/4) {
+		printf("Veth batch size too large.\n");
+		exit(EXIT_FAILURE);
+	}
+
+	if (opt_veth && !strcmp(interface_name, "vm1"))	{
+		for (i = 0; i < opt_veth; i++) {
+			struct tpacket4_desc desc = {.idx = i};
+			unsigned int len;
+
+			len = gen_eth_frame(tp4_get_buffer(tqp, i), i + 1);
+
+			desc.len = len;
+			ret = tp4q_enqueue(&tqp->tx, &desc, 1);
+			lassert(ret == 0);
+		}
+		ret = sendto(sfd, NULL, 0, MSG_DONTWAIT, NULL, 0);
+		lassert(ret != -1);
+	}
+
+	for (i = opt_veth; i < (tqp->rx.ring_mask + 1)/4; i++) {
 		struct tpacket4_desc desc = {};
 
 		desc.idx = i;
@@ -902,21 +1046,6 @@ static inline void tp4_rx_release(void *queue_pair, unsigned int start,
 	q->num_free = 0;
 }
 
-static inline void *tp4_get_data(void *queue_pair, unsigned int idx,
-				 unsigned int *len)
-{
-	struct tp4_queue_pair *qp = (struct tp4_queue_pair *)queue_pair;
-	struct tp4_umem *umem = qp->umem;
-	struct tpacket4_desc *d;
-
-	d = &qp->rx.ring[idx & qp->rx.ring_mask];
-	*len = d->len;
-
-	return (char *)umem->buffer + (d->idx << umem->frame_size_log2)
-		+ d->offset;
-}
-
-
 static inline unsigned long tp4_get_data_desc(void *queue_pair,
 					      unsigned int idx,
 					      unsigned int *len,
@@ -1126,6 +1255,7 @@ static struct option long_options[] = {
 	{"l2fwd", no_argument, 0, 'l'},
 	{"zerocopy", required_argument, 0, 'z'},
 	{"interface", required_argument, 0, 'i'},
+	{"veth", required_argument, 0, 'e'},
 	{0, 0, 0, 0}
 };
 
@@ -1152,7 +1282,7 @@ static void parse_command_line(int argc, char **argv)
 	opterr = 0;
 
 	for (;;) {
-		c = getopt_long(argc, argv, "v:rtlz:i:", long_options,
+		c = getopt_long(argc, argv, "v:rtlz:i:e:", long_options,
 				&option_index);
 		if (c == -1)
 			break;
@@ -1182,6 +1312,9 @@ static void parse_command_line(int argc, char **argv)
 		case 'i':
 			opt_if = optarg;
 			break;
+		case 'e':
+			opt_veth = atoi(optarg);
+			break;
 		default:
 			usage();
 		}
@@ -1192,6 +1325,11 @@ static void parse_command_line(int argc, char **argv)
 		usage();
 	}
 
+	if (opt_veth) {
+		opt_bench = BENCH_L2FWD;
+		opt_if = veth_if1;
+	}
+
 	ret = if_nametoindex(opt_if);
 	if (!ret) {
 		fprintf(stderr, "ERROR: interface \"%s\" does not exist\n",
@@ -1246,7 +1384,6 @@ int main(int argc, char **argv)
 	parse_command_line(argc, argv);
 	print_benchmark(true);
 	benchmark = *get_benchmark(opt_tpver, opt_bench);
-	start_time = get_nsecs();
 	run_benchmark(opt_if);
 
 	return 0;
-- 
2.11.0

  parent reply	other threads:[~2017-10-31 12:43 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-31 12:41 [RFC PATCH 00/14] Introducing AF_PACKET V4 support Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 01/14] packet: introduce AF_PACKET V4 userspace API Björn Töpel
2017-11-02  1:45   ` Willem de Bruijn
2017-11-02 10:06     ` Björn Töpel
2017-11-02 16:40       ` Tushar Dave
2017-11-02 16:47         ` Björn Töpel
2017-11-03  2:29       ` Willem de Bruijn
2017-11-03  9:54         ` Björn Töpel
2017-11-15 22:21           ` chet l
2017-11-16 16:53             ` Jesper Dangaard Brouer
2017-11-17  3:32               ` chetan L
2017-11-15 22:34   ` chet l
2017-11-16  1:44     ` David Miller
2017-11-16 19:32       ` chetan L
2017-10-31 12:41 ` [RFC PATCH 02/14] packet: implement PACKET_MEMREG setsockopt Björn Töpel
2017-11-03  3:00   ` Willem de Bruijn
2017-11-03  9:57     ` Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 03/14] packet: enable AF_PACKET V4 rings Björn Töpel
2017-11-03  4:16   ` Willem de Bruijn
2017-11-03 10:02     ` Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 04/14] packet: enable Rx for AF_PACKET V4 Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 05/14] packet: enable Tx support " Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 06/14] netdevice: add AF_PACKET V4 zerocopy ops Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 07/14] packet: wire up zerocopy for AF_PACKET V4 Björn Töpel
2017-11-03  3:17   ` Willem de Bruijn
2017-11-03 10:47     ` Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 08/14] i40e: AF_PACKET V4 ndo_tp4_zerocopy Rx support Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 09/14] i40e: AF_PACKET V4 ndo_tp4_zerocopy Tx support Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 10/14] samples/tpacket4: added tpbench Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 11/14] veth: added support for PACKET_ZEROCOPY Björn Töpel
2017-10-31 12:41 ` Björn Töpel [this message]
2017-10-31 12:41 ` [RFC PATCH 13/14] i40e: added XDP support for TP4 enabled queue pairs Björn Töpel
2017-10-31 12:41 ` [RFC PATCH 14/14] xdp: introducing XDP_PASS_TO_KERNEL for PACKET_ZEROCOPY use Björn Töpel
2017-11-03  4:34 ` [RFC PATCH 00/14] Introducing AF_PACKET V4 support Willem de Bruijn
2017-11-03 10:13   ` Karlsson, Magnus
2017-11-03 13:55     ` Willem de Bruijn
2017-11-13 13:07 ` Björn Töpel
2017-11-13 14:34   ` John Fastabend
2017-11-13 23:50   ` Alexei Starovoitov
2017-11-14  5:33     ` Björn Töpel
2017-11-14  7:02       ` John Fastabend
2017-11-14 12:20         ` Willem de Bruijn
2017-11-16  2:55           ` Alexei Starovoitov
2017-11-16  3:35             ` Willem de Bruijn
2017-11-16  7:09               ` Björn Töpel
2017-11-16  8:26                 ` Jesper Dangaard Brouer
2017-11-14 17:19   ` [RFC PATCH 00/14] Introducing AF_PACKET V4 support (AF_XDP or AF_CHANNEL?) Jesper Dangaard Brouer
2017-11-14 19:01     ` Björn Töpel
2017-11-16  8:00       ` Jesper Dangaard Brouer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171031124145.9667-13-bjorn.topel@gmail.com \
    --to=bjorn.topel@gmail.com \
    --cc=alexander.duyck@gmail.com \
    --cc=alexander.h.duyck@intel.com \
    --cc=anjali.singhai@intel.com \
    --cc=ast@fb.com \
    --cc=brouer@redhat.com \
    --cc=daniel@iogearbox.net \
    --cc=ferruh.yigit@intel.com \
    --cc=jeffrey.b.shaw@intel.com \
    --cc=jesse.brandeburg@intel.com \
    --cc=john.fastabend@gmail.com \
    --cc=magnus.karlsson@intel.com \
    --cc=michael.lundkvist@ericsson.com \
    --cc=netdev@vger.kernel.org \
    --cc=qi.z.zhang@intel.com \
    --cc=rami.rosen@intel.com \
    --cc=ravineet.singh@ericsson.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).