diff mbox series

[ovs-dev,v9,15/16] netdev: Optimize netdev_send_prepare_batch

Message ID 20210212171718.2189798-16-harry.van.haaren@intel.com
State New
Headers show
Series DPIF Framework + Optimizations | expand

Commit Message

Harry van Haaren Feb. 12, 2021, 5:17 p.m. UTC
Optimize for the best case here where all packets will be compatible
with 'netdev_flags'.

Signed-off-by: Harry van Haaren <harry.van.haaren@intel.com>
Co-authored-by: Cian Ferriter <cian.ferriter@intel.com>
Signed-off-by: Cian Ferriter <cian.ferriter@intel.com>

---

v9: rebase 2
---
 NEWS         |  2 ++
 lib/netdev.c | 31 ++++++++++++++++++++++---------
 2 files changed, 24 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/NEWS b/NEWS
index 2ffc155f9..cbdcf53a1 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,8 @@  Post-v2.15.0
        CPU supports it. This enhances performance by using the native vpopcount
        instructions, instead of the emulated version of vpopcount.
      * Optimize dp_netdev_output by enhancing compiler optimization potential.
+     * Optimize netdev sending by assuming the happy case, and using fallback
+       for if the netdev doesnt meet the required HWOL needs of a packet.
 
 v2.15.0 - xx xxx xxxx
 ---------------------
diff --git a/lib/netdev.c b/lib/netdev.c
index 91e91955c..29a5f1aa9 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -837,20 +837,33 @@  static void
 netdev_send_prepare_batch(const struct netdev *netdev,
                           struct dp_packet_batch *batch)
 {
-    struct dp_packet *packet;
-    size_t i, size = dp_packet_batch_size(batch);
+    struct dp_packet *p;
+    uint32_t i, size = dp_packet_batch_size(batch);
+    char *err_msg = NULL;
 
-    DP_PACKET_BATCH_REFILL_FOR_EACH (i, size, packet, batch) {
-        char *errormsg = NULL;
+    for (i = 0; i < size; i++) {
+        p = batch->packets[i];
+        int pkt_ok = netdev_send_prepare_packet(netdev->ol_flags, p, &err_msg);
 
-        if (netdev_send_prepare_packet(netdev->ol_flags, packet, &errormsg)) {
-            dp_packet_batch_refill(batch, packet, i);
+        if (OVS_UNLIKELY(!pkt_ok)) {
+            goto refill_loop;
+        }
+    }
+
+    return;
+
+refill_loop:
+    /* Loop through packets from the start of the batch again. This is the
+     * exceptional case where packets aren't compatible with 'netdev_flags'. */
+    DP_PACKET_BATCH_REFILL_FOR_EACH (i, size, p, batch) {
+        if (netdev_send_prepare_packet(netdev->ol_flags, p, &err_msg)) {
+            dp_packet_batch_refill(batch, p, i);
         } else {
-            dp_packet_delete(packet);
+            dp_packet_delete(p);
             COVERAGE_INC(netdev_send_prepare_drops);
             VLOG_WARN_RL(&rl, "%s: Packet dropped: %s",
-                         netdev_get_name(netdev), errormsg);
-            free(errormsg);
+                         netdev_get_name(netdev), err_msg);
+            free(err_msg);
         }
     }
 }