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

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
...@@ -99,6 +99,9 @@ Examples: ...@@ -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
......
...@@ -387,6 +387,7 @@ struct pktgen_dev { ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment