In preparation for batches larger than NETDEV_MAX_BURST,
split big batches into "small" NETDEV_MAX_BURST batches for recirculation,
as some dpif-netdev input operations (flow extraction and dpcls lookups)
are using arrays (on the stack) sized for NETDEV_MAX_BURST burst of
packets.

Add one coverage counter so that next changes can test this code.

Signed-off-by: David Marchand <[email protected]>
---
 lib/dp-packet.h   | 16 ++++++++++++++++
 lib/dpif-netdev.c | 23 +++++++++++++++++++++++
 2 files changed, 39 insertions(+)

diff --git a/lib/dp-packet.h b/lib/dp-packet.h
index d92b9d4730..16b9afbc36 100644
--- a/lib/dp-packet.h
+++ b/lib/dp-packet.h
@@ -890,6 +890,22 @@ dp_packet_batch_add(struct dp_packet_batch *batch, struct 
dp_packet *packet)
     dp_packet_batch_add__(batch, packet, NETDEV_MAX_BURST);
 }
 
+static inline void
+dp_packet_batch_add_array(struct dp_packet_batch *batch,
+                          struct dp_packet *packets[], size_t n)
+{
+    size_t count = MIN(n, NETDEV_MAX_BURST - batch->count);
+
+    if (count) {
+        memcpy(&batch->packets[batch->count], packets,
+               count * sizeof packets[0]);
+        batch->count += count;
+    }
+    for (size_t i = count; i < n; i++) {
+        dp_packet_delete(packets[i]);
+    }
+}
+
 static inline size_t
 dp_packet_batch_size(const struct dp_packet_batch *batch)
 {
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 2dc1dd5d4c..0b8daab052 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -123,6 +123,8 @@ COVERAGE_DEFINE(datapath_drop_rx_invalid_packet);
 COVERAGE_DEFINE(datapath_drop_hw_post_process);
 COVERAGE_DEFINE(datapath_drop_hw_post_process_consumed);
 
+COVERAGE_DEFINE(dpif_netdev_recirc_big_batch);
+
 /* Protects against changes to 'dp_netdevs'. */
 static struct ovs_mutex dp_netdev_mutex = OVS_MUTEX_INITIALIZER;
 
@@ -7686,6 +7688,27 @@ static void
 dp_netdev_recirculate(struct dp_netdev_pmd_thread *pmd,
                       struct dp_packet_batch *packets)
 {
+    if (dp_packet_batch_size(packets) > NETDEV_MAX_BURST) {
+        struct dp_packet_batch smaller_batch;
+        size_t batch_cnt;
+        size_t sent = 0;
+
+        COVERAGE_INC(dpif_netdev_recirc_big_batch);
+        batch_cnt = dp_packet_batch_size(packets);
+        dp_packet_batch_init(&smaller_batch);
+        do {
+            size_t count = MIN(batch_cnt - sent, NETDEV_MAX_BURST);
+
+            smaller_batch.trunc = packets->trunc;
+            smaller_batch.count = 0;
+            dp_packet_batch_add_array(&smaller_batch, &packets->packets[sent],
+                                      count);
+            dp_netdev_input__(pmd, &smaller_batch, true, 0);
+            sent += count;
+        } while (sent < batch_cnt);
+        return;
+    }
+
     dp_netdev_input__(pmd, packets, true, 0);
 }
 
-- 
2.54.0

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

Reply via email to