Prepare for dynamic packet batches by splitting the batch to be sent and
flushing the output queue every time this queue reaches NETDEV_MAX_BURST.
This is a temporary step before introducing dynamic packet batches.

Signed-off-by: David Marchand <[email protected]>
---
 lib/dpif-netdev.c | 36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 0b8daab052..c0ee1c8d88 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -7880,17 +7880,32 @@ dp_execute_userspace_action(struct dp_netdev_pmd_thread 
*pmd,
     }
 }
 
+static size_t
+dp_execute_output_chunk(struct dp_netdev_pmd_thread *pmd, struct tx_port *p,
+                        struct dp_packet **packets, size_t count)
+{
+    count = MIN(count, NETDEV_MAX_BURST - p->output_pkts.count);
+
+    for (unsigned i = 0; i < count; i++) {
+        p->output_pkts_rxqs[p->output_pkts.count + i] = pmd->ctx.last_rxq;
+    }
+    dp_packet_batch_add_array(&p->output_pkts, packets, count);
+
+    return count;
+}
+
 static bool
 dp_execute_output_action(struct dp_netdev_pmd_thread *pmd,
                          struct dp_packet_batch *packets_,
                          bool should_steal, odp_port_t port_no)
 {
     struct tx_port *p = pmd_send_port_cache_lookup(pmd, port_no);
+    size_t batch_cnt = dp_packet_batch_size(packets_);
     struct dp_packet_batch out;
+    size_t sent;
 
     if (!OVS_LIKELY(p)) {
-        COVERAGE_ADD(datapath_drop_invalid_port,
-                     dp_packet_batch_size(packets_));
+        COVERAGE_ADD(datapath_drop_invalid_port, batch_cnt);
         dp_packet_delete_batch(packets_, should_steal);
         return false;
     }
@@ -7900,20 +7915,21 @@ dp_execute_output_action(struct dp_netdev_pmd_thread 
*pmd,
         packets_ = &out;
     }
     dp_packet_batch_apply_cutlen(packets_);
-    if (dp_packet_batch_size(&p->output_pkts)
-        + dp_packet_batch_size(packets_) > NETDEV_MAX_BURST) {
-        /* Flush here to avoid overflow. */
+    if (dp_packet_batch_size(&p->output_pkts) == NETDEV_MAX_BURST) {
         dp_netdev_pmd_flush_output_on_port(pmd, p);
     }
     if (dp_packet_batch_is_empty(&p->output_pkts)) {
         pmd->n_output_batches++;
     }
 
-    struct dp_packet *packet;
-    DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
-        p->output_pkts_rxqs[dp_packet_batch_size(&p->output_pkts)] =
-            pmd->ctx.last_rxq;
-        dp_packet_batch_add(&p->output_pkts, packet);
+    sent = dp_execute_output_chunk(pmd, p, packets_->packets, batch_cnt);
+    if (OVS_UNLIKELY(sent < batch_cnt)) {
+        do {
+            dp_netdev_pmd_flush_output_on_port(pmd, p);
+            pmd->n_output_batches++;
+            sent += dp_execute_output_chunk(pmd, p, &packets_->packets[sent],
+                                            batch_cnt - sent);
+        } while (sent < batch_cnt);
     }
     return true;
 }
-- 
2.54.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to