Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 38b2cf29 authored by Alexei Starovoitov's avatar Alexei Starovoitov Committed by David S. Miller
Browse files

net: pktgen: packet bursting via skb->xmit_more



This patch demonstrates the effect of delaying update of HW tailptr.
(based on earlier patch by Jesper)

burst=1 is the default. It sends one packet with xmit_more=false
burst=2 sends one packet with xmit_more=true and
        2nd copy of the same packet with xmit_more=false
burst=3 sends two copies of the same packet with xmit_more=true and
        3rd copy with xmit_more=false

Performance with ixgbe (usec 30):
burst=1  tx:9.2 Mpps
burst=2  tx:13.5 Mpps
burst=3  tx:14.5 Mpps full 10G line rate

Signed-off-by: default avatarAlexei Starovoitov <ast@plumgrid.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarJesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 775dd692
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -99,6 +99,9 @@ Examples:


 pgset "clone_skb 1"     sets the number of copies of the same packet
 pgset "clone_skb 1"     sets the number of copies of the same packet
 pgset "clone_skb 0"     use single SKB for all transmits
 pgset "clone_skb 0"     use single SKB for all transmits
 pgset "burst 8"         uses xmit_more API to queue 8 copies of the same
                         packet and update HW tx queue tail pointer once.
                         "burst 1" is the default
 pgset "pkt_size 9014"   sets packet size to 9014
 pgset "pkt_size 9014"   sets packet size to 9014
 pgset "frags 5"         packet will consist of 5 fragments
 pgset "frags 5"         packet will consist of 5 fragments
 pgset "count 200000"    sets number of packets to send, set to zero
 pgset "count 200000"    sets number of packets to send, set to zero
+24 −2
Original line number Original line Diff line number Diff line
@@ -387,6 +387,7 @@ struct pktgen_dev {
	u16 queue_map_min;
	u16 queue_map_min;
	u16 queue_map_max;
	u16 queue_map_max;
	__u32 skb_priority;	/* skb priority field */
	__u32 skb_priority;	/* skb priority field */
	unsigned int burst;	/* number of duplicated packets to burst */
	int node;               /* Memory node */
	int node;               /* Memory node */


#ifdef CONFIG_XFRM
#ifdef CONFIG_XFRM
@@ -613,6 +614,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
	if (pkt_dev->traffic_class)
	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);

	if (pkt_dev->node >= 0)
	if (pkt_dev->node >= 0)
		seq_printf(seq, "     node: %d\n", pkt_dev->node);
		seq_printf(seq, "     node: %d\n", pkt_dev->node);


@@ -1124,6 +1128,16 @@ static ssize_t pktgen_if_write(struct file *file,
			pkt_dev->dst_mac_count);
			pkt_dev->dst_mac_count);
		return count;
		return count;
	}
	}
	if (!strcmp(name, "burst")) {
		len = num_arg(&user_buffer[i], 10, &value);
		if (len < 0)
			return len;

		i += len;
		pkt_dev->burst = value < 1 ? 1 : value;
		sprintf(pg_result, "OK: burst=%d", pkt_dev->burst);
		return count;
	}
	if (!strcmp(name, "node")) {
	if (!strcmp(name, "node")) {
		len = num_arg(&user_buffer[i], 10, &value);
		len = num_arg(&user_buffer[i], 10, &value);
		if (len < 0)
		if (len < 0)
@@ -3297,6 +3311,7 @@ static void pktgen_wait_for_skb(struct pktgen_dev *pkt_dev)


static void pktgen_xmit(struct pktgen_dev *pkt_dev)
static void pktgen_xmit(struct pktgen_dev *pkt_dev)
{
{
	unsigned int burst = ACCESS_ONCE(pkt_dev->burst);
	struct net_device *odev = pkt_dev->odev;
	struct net_device *odev = pkt_dev->odev;
	struct netdev_queue *txq;
	struct netdev_queue *txq;
	int ret;
	int ret;
@@ -3347,8 +3362,10 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
		pkt_dev->last_ok = 0;
		pkt_dev->last_ok = 0;
		goto unlock;
		goto unlock;
	}
	}
	atomic_inc(&(pkt_dev->skb->users));
	atomic_add(burst, &pkt_dev->skb->users);
	ret = netdev_start_xmit(pkt_dev->skb, odev, txq, false);

xmit_more:
	ret = netdev_start_xmit(pkt_dev->skb, odev, txq, --burst > 0);


	switch (ret) {
	switch (ret) {
	case NETDEV_TX_OK:
	case NETDEV_TX_OK:
@@ -3356,6 +3373,8 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
		pkt_dev->sofar++;
		pkt_dev->sofar++;
		pkt_dev->seq_num++;
		pkt_dev->seq_num++;
		pkt_dev->tx_bytes += pkt_dev->last_pkt_size;
		pkt_dev->tx_bytes += pkt_dev->last_pkt_size;
		if (burst > 0 && !netif_xmit_frozen_or_drv_stopped(txq))
			goto xmit_more;
		break;
		break;
	case NET_XMIT_DROP:
	case NET_XMIT_DROP:
	case NET_XMIT_CN:
	case NET_XMIT_CN:
@@ -3374,6 +3393,8 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
		atomic_dec(&(pkt_dev->skb->users));
		atomic_dec(&(pkt_dev->skb->users));
		pkt_dev->last_ok = 0;
		pkt_dev->last_ok = 0;
	}
	}
	if (unlikely(burst))
		atomic_sub(burst, &pkt_dev->skb->users);
unlock:
unlock:
	HARD_TX_UNLOCK(odev, txq);
	HARD_TX_UNLOCK(odev, txq);


@@ -3572,6 +3593,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
	pkt_dev->svlan_p = 0;
	pkt_dev->svlan_p = 0;
	pkt_dev->svlan_cfi = 0;
	pkt_dev->svlan_cfi = 0;
	pkt_dev->svlan_id = 0xffff;
	pkt_dev->svlan_id = 0xffff;
	pkt_dev->burst = 1;
	pkt_dev->node = -1;
	pkt_dev->node = -1;


	err = pktgen_setup_dev(t->net, pkt_dev, ifname);
	err = pktgen_setup_dev(t->net, pkt_dev, ifname);