public inbox for netdev@vger.kernel.org 
 help / color / mirror / Atom feed
From: Jamal Hadi Salim <jhs@mojatatu•com>
To: John Fastabend <john.fastabend@gmail•com>
Cc: netdev@vger•kernel.org, alexei.starovoitov@gmail•com,
	davem@davemloft•net
Subject: Re: [PATCH] net: pktgen: support injecting packets for qdisc testing
Date: Fri, 8 Jan 2016 09:38:48 -0500	[thread overview]
Message-ID: <568FC9F8.8040201@mojatatu.com> (raw)
In-Reply-To: <568F1EE2.7020107@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 389 bytes --]

On 16-01-07 09:28 PM, John Fastabend wrote:
>
> Hi Jamal,
>
> per your comment about using pktgen to test qdiscs here is the
> patch I've been using most the day which has been working well.
> I'm guessing this is more or less what you had in mind.
>

I have attached the one i used over the holidays - see if there are
any differences(sorry dont have much time right now).

cheers,
jamal

[-- Attachment #2: pktgen-patch --]
[-- Type: text/plain, Size: 4394 bytes --]

diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index de8d5cc..30774f1 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -212,7 +212,8 @@
 
 /* Xmit modes */
 #define M_START_XMIT		0	/* Default normal TX */
-#define M_NETIF_RECEIVE 	1	/* Inject packets into stack */
+#define M_NETIF_RECEIVE		1	/* Inject packets into stack */
+#define M_NETIF_QUEUE_XMIT	2	/* Inject packets into qdisc */
 
 /* If lock -- protects updating of if_list */
 #define   if_lock(t)           spin_lock(&(t->if_lock));
@@ -616,7 +617,8 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 		seq_printf(seq, "     tos: 0x%02x\n", pkt_dev->tos);
 
 	if (pkt_dev->traffic_class)
-		seq_printf(seq, "     traffic_class: 0x%02x\n", pkt_dev->traffic_class);
+		seq_printf(seq, "     traffic_class: 0x%02x\n",
+			   pkt_dev->traffic_class);
 
 	if (pkt_dev->burst > 1)
 		seq_printf(seq, "     burst: %d\n", pkt_dev->burst);
@@ -624,8 +626,12 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
 	if (pkt_dev->node >= 0)
 		seq_printf(seq, "     node: %d\n", pkt_dev->node);
 
+	if (pkt_dev->xmit_mode == M_START_XMIT)
+		seq_puts(seq, "     xmit_mode: qdisc_bypass\n");
 	if (pkt_dev->xmit_mode == M_NETIF_RECEIVE)
 		seq_puts(seq, "     xmit_mode: netif_receive\n");
+	if (pkt_dev->xmit_mode == M_NETIF_QUEUE_XMIT)
+		seq_puts(seq, "     xmit_mode: qdisc_xmit\n");
 
 	seq_puts(seq, "     Flags: ");
 
@@ -1198,6 +1204,22 @@ static ssize_t pktgen_if_write(struct file *file,
 			 * at module loading time
 			 */
 			pkt_dev->clone_skb = 0;
+		} else if (strcmp(f, "qdisc_xmit") == 0) {
+			/* clone_skb set earlier, not supported in this mode */
+			if (pkt_dev->clone_skb > 0)
+				return -ENOTSUPP;
+
+			pkt_dev->xmit_mode = M_NETIF_QUEUE_XMIT;
+
+			/* make sure new packet is allocated every time
+			 * pktgen_xmit() is called
+			 */
+			pkt_dev->last_ok = 1;
+
+			/* override clone_skb if user passed default value
+			 * at module loading time
+			 */
+			pkt_dev->clone_skb = 0;
 		} else {
 			sprintf(pg_result,
 				"xmit_mode -:%s:- unknown\nAvailable modes: %s",
@@ -3361,6 +3383,23 @@ static void pktgen_wait_for_skb(struct pktgen_dev *pkt_dev)
 	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_get(), idle_start));
 }
 
+static inline netdev_tx_t netdevq_start_xmit(struct sk_buff *skb,
+					    struct net_device *dev,
+					    struct netdev_queue *txq, bool more)
+{
+	const struct net_device_ops *ops = dev->netdev_ops;
+	int rc;
+
+	skb->xmit_more = more ? 1 : 0;
+	skb->dev = dev;
+	rc = dev_queue_xmit(skb);
+	if (likely(rc == NET_XMIT_SUCCESS || rc == NET_XMIT_CN)) {
+		txq_trans_update(txq);
+	}
+
+	return rc;
+}
+
 static void pktgen_xmit(struct pktgen_dev *pkt_dev)
 {
 	unsigned int burst = ACCESS_ONCE(pkt_dev->burst);
@@ -3432,8 +3471,54 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
 #endif
 		} while (--burst > 0);
 		goto out; /* Skips xmit_mode M_START_XMIT */
+	} else if (pkt_dev->xmit_mode == M_NETIF_QUEUE_XMIT) {
+
+		txq = skb_get_tx_queue(odev, pkt_dev->skb);
+		local_bh_disable();
+
+		if (unlikely(netif_xmit_frozen_or_drv_stopped(txq))) {
+			ret = NETDEV_TX_BUSY;
+			pkt_dev->last_ok = 0;
+			goto out;
+		}
+		atomic_add(burst, &pkt_dev->skb->users);
+
+qxmit_more:
+		ret = netdevq_start_xmit(pkt_dev->skb, odev, txq, --burst > 0);
+
+		switch (ret) {
+		case NETDEV_TX_OK:
+			pkt_dev->last_ok = 1;
+			pkt_dev->sofar++;
+			pkt_dev->seq_num++;
+			pkt_dev->tx_bytes += pkt_dev->last_pkt_size;
+			if (burst > 0 && !netif_xmit_frozen_or_drv_stopped(txq))
+				goto qxmit_more;
+			break;
+		case NET_XMIT_DROP:
+		case NET_XMIT_CN:
+		case NET_XMIT_POLICED:
+			/* skb has been consumed */
+			pkt_dev->errors++;
+			break;
+		default: /* Drivers are not supposed to return other values! */
+			net_info_ratelimited("%s xmit error: %d\n",
+					     pkt_dev->odevname, ret);
+			pkt_dev->errors++;
+			/* fallthru */
+		case NETDEV_TX_LOCKED:
+		case NETDEV_TX_BUSY:
+			/* Retry it next time */
+			atomic_dec(&(pkt_dev->skb->users));
+			pkt_dev->last_ok = 0;
+		}
+		if (unlikely(burst))
+			atomic_sub(burst, &pkt_dev->skb->users);
+
+		goto out; /* Skips xmit_mode M_START_XMIT */
 	}
 
+	/*M_START_XMIT*/
 	txq = skb_get_tx_queue(odev, pkt_dev->skb);
 
 	local_bh_disable();
@@ -3478,6 +3563,7 @@ xmit_more:
 	}
 	if (unlikely(burst))
 		atomic_sub(burst, &pkt_dev->skb->users);
+
 unlock:
 	HARD_TX_UNLOCK(odev, txq);
 

  reply	other threads:[~2016-01-08 14:38 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-08  2:09 [PATCH] net: pktgen: support injecting packets for qdisc testing John Fastabend
2016-01-08  2:28 ` John Fastabend
2016-01-08 14:38   ` Jamal Hadi Salim [this message]
2016-01-08 15:24     ` John Fastabend
2016-01-09  0:41       ` John Fastabend
2016-01-10 14:09       ` Jamal Hadi Salim
2016-01-11  5:21         ` John Fastabend
2016-01-08 15:28 ` John Fastabend
2016-01-08 15:38   ` John Fastabend
2016-01-08 21:36     ` Eric Dumazet
2016-01-08 21:55       ` John Fastabend

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=568FC9F8.8040201@mojatatu.com \
    --to=jhs@mojatatu$(echo .)com \
    --cc=alexei.starovoitov@gmail$(echo .)com \
    --cc=davem@davemloft$(echo .)net \
    --cc=john.fastabend@gmail$(echo .)com \
    --cc=netdev@vger$(echo .)kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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