Enable BURST_MODE for l2fwd 35/11835/2
authorMesut Ali Ergin <mesut.a.ergin@intel.com>
Fri, 1 Apr 2016 19:05:10 +0000 (12:05 -0700)
committerMesut Ali Ergin <mesut.a.ergin@intel.com>
Wed, 8 Jun 2016 17:07:43 +0000 (17:07 +0000)
JIRA: VSPERF-267

This change adds optional burst mode to l2fwd module that makes use of
skb->xmit_more API available in Linux Kernel > 3.18 in order to batch
transmission of packets out of the NIC, increasing forwarding performance
significantly. By default burst mode is disabled. If a value greater than
1 is provided, burst mode is enabled to send that many packets at once.
Typical values would be burst=8 or burst=16.

Change-Id: I8ef5f86cf73d4cb5a8e4c618a86111ebf411dca8
Signed-off-by: Mesut Ali Ergin <mesut.a.ergin@intel.com>
Signed-off-by: Mallesh Koujalagi <malleshx.koujalagi@intel.com>
src/l2fwd/l2fwd.c

index 338b6f5..3d45680 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/log2.h>
 #include <linux/gfp.h>
 #include <linux/slab.h>
+#include <linux/version.h>
 
 #include <linux/ip.h>
 #include <linux/in.h>
@@ -67,6 +68,14 @@ static bool terminate = false;
 module_param(terminate, bool, 0);
 MODULE_PARM_DESC(terminate, "Free skb instead of forwarding");
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)
+#define BURST_MODE
+static short burst = 1;
+module_param(burst, short, 0);
+MODULE_PARM_DESC(burst, "Send burst-many packets to output device at once (default is 1)");
+
+short burst_count;
+#endif
 static struct net_device *dev1, *dev2;
 int count;
 
@@ -171,7 +180,32 @@ static rx_handler_result_t netdev_frame_hook(struct sk_buff **pskb)
 
             skb->dev = dev;
             skb_push(skb, ETH_HLEN);
+#ifdef BURST_MODE
+            if (burst > 1)
+                {
+                   struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+                   skb_set_queue_mapping(skb, 0);
+
+                   if (!netif_xmit_frozen_or_stopped(txq))
+                       {
+                           const struct net_device_ops *ops = dev->netdev_ops;
+                           int status = NETDEV_TX_OK;
+                           skb->xmit_more = --burst_count > 0 ? 1 : 0;
+                           status = ops->ndo_start_xmit(skb, dev);
+                           if (status == NETDEV_TX_OK)
+                               txq_trans_update(txq);
+                           if (!burst_count)
+                               burst_count = burst;
+                       }
+
+                }
+            else
+                {
+                    dev_queue_xmit(skb);
+                }
+#else
             dev_queue_xmit(skb);
+#endif
         }
 
     return retval;
@@ -187,7 +221,9 @@ static int __init l2fwd_init_module(void)
     char name_fmt_str[IFNAMSIZ+1];
     char t_name[IFNAMSIZ+1];
 
-
+#ifdef BURST_MODE
+    burst_count = burst;
+#endif
 
     sprintf(name_fmt_str,"%%%ds",IFNAMSIZ);
     dnat_fmt = (char *)kmalloc(strlen(name_fmt_str)+strlen(dnat_fmt_suffix)+1,GFP_KERNEL);